[default -> splittiming] forgot to push my merge. ouch
This commit is contained in:
@@ -9,6 +9,9 @@ change to JSON, but it is unsure if this will be done.
|
||||
Implement .ssc at your own risk.
|
||||
________________________________________________________________________________
|
||||
|
||||
[v0.7] - theDtTvB, Wolfman2000
|
||||
* Split Timing officially implemented.
|
||||
|
||||
[v0.59] - Wolfman2000
|
||||
* Typo fix: #RADARVALUES needed a semicolon at the end, not a colon.
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ function GetTotalItems(radars)
|
||||
return radars:GetValue('RadarCategory_TapsAndHolds')
|
||||
+ radars:GetValue('RadarCategory_Holds')
|
||||
+ radars:GetValue('RadarCategory_Rolls');
|
||||
+ radars:GetValue('RadarCategory_Lifts');
|
||||
end;
|
||||
|
||||
-- Determine whether marvelous timing is to be considered.
|
||||
|
||||
+12
-12
@@ -58,7 +58,7 @@ void AdjustSync::ResetOriginalSyncData()
|
||||
s_pTimingDataOriginal = new TimingData;
|
||||
|
||||
if( GAMESTATE->m_pCurSong )
|
||||
*s_pTimingDataOriginal = GAMESTATE->m_pCurSong->m_Timing;
|
||||
*s_pTimingDataOriginal = GAMESTATE->m_pCurSong->m_SongTiming;
|
||||
else
|
||||
*s_pTimingDataOriginal = TimingData();
|
||||
s_fGlobalOffsetSecondsOriginal = PREFSMAN->m_fGlobalOffsetSeconds;
|
||||
@@ -87,7 +87,7 @@ void AdjustSync::SaveSyncChanges()
|
||||
{
|
||||
if( GAMESTATE->IsCourseMode() )
|
||||
return;
|
||||
if( GAMESTATE->m_pCurSong && *s_pTimingDataOriginal != GAMESTATE->m_pCurSong->m_Timing )
|
||||
if( GAMESTATE->m_pCurSong && *s_pTimingDataOriginal != GAMESTATE->m_pCurSong->m_SongTiming )
|
||||
{
|
||||
if( GAMESTATE->IsEditing() )
|
||||
{
|
||||
@@ -110,7 +110,7 @@ void AdjustSync::RevertSyncChanges()
|
||||
if( GAMESTATE->IsCourseMode() )
|
||||
return;
|
||||
PREFSMAN->m_fGlobalOffsetSeconds.Set( s_fGlobalOffsetSecondsOriginal );
|
||||
GAMESTATE->m_pCurSong->m_Timing = *s_pTimingDataOriginal;
|
||||
GAMESTATE->m_pCurSong->m_SongTiming = *s_pTimingDataOriginal;
|
||||
ResetOriginalSyncData();
|
||||
s_fStandardDeviation = 0.0f;
|
||||
s_fAverageError = 0.0f;
|
||||
@@ -186,7 +186,7 @@ void AdjustSync::AutosyncOffset()
|
||||
switch( GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType )
|
||||
{
|
||||
case SongOptions::AUTOSYNC_SONG:
|
||||
GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += mean;
|
||||
GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += mean;
|
||||
break;
|
||||
case SongOptions::AUTOSYNC_MACHINE:
|
||||
PREFSMAN->m_fGlobalOffsetSeconds.Set( PREFSMAN->m_fGlobalOffsetSeconds + mean );
|
||||
@@ -232,15 +232,15 @@ void AdjustSync::AutosyncTempo()
|
||||
if( !CalcLeastSquares( s_vAutosyncTempoData, fSlope, fIntercept, fFilteredError ) )
|
||||
return;
|
||||
|
||||
GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += fIntercept;
|
||||
GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fIntercept;
|
||||
const float fScaleBPM = 1.0f/(1.0f - fSlope);
|
||||
FOREACH( BPMSegment, GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments, i )
|
||||
FOREACH( BPMSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments, i )
|
||||
i->SetBPM( i->GetBPM() * fScaleBPM );
|
||||
|
||||
// We assume that the stops were measured as a number of beats.
|
||||
// Therefore, if we change the bpms, we need to make a similar
|
||||
// change to the stops.
|
||||
FOREACH( StopSegment, GAMESTATE->m_pCurSong->m_Timing.m_StopSegments, i )
|
||||
FOREACH( StopSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments, i )
|
||||
i->m_fStopSeconds *= 1.0f - fSlope;
|
||||
|
||||
SCREENMAN->SystemMessage( AUTOSYNC_CORRECTION_APPLIED.GetValue() );
|
||||
@@ -296,7 +296,7 @@ void AdjustSync::GetSyncChangeTextSong( vector<RString> &vsAddTo )
|
||||
|
||||
{
|
||||
float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_fBeat0OffsetInSeconds, 0.001f );
|
||||
float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds, 0.001f );
|
||||
float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds, 0.001f );
|
||||
float fDelta = fNew - fOld;
|
||||
|
||||
if( fabsf(fDelta) > 0.0001f )
|
||||
@@ -309,10 +309,10 @@ void AdjustSync::GetSyncChangeTextSong( vector<RString> &vsAddTo )
|
||||
}
|
||||
}
|
||||
|
||||
for( unsigned i=0; i<GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments.size(); i++ )
|
||||
for( unsigned i=0; i<GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments.size(); i++ )
|
||||
{
|
||||
float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_BPMSegments[i].GetBPM(), 0.001f );
|
||||
float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments[i].GetBPM(), 0.001f );
|
||||
float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments[i].GetBPM(), 0.001f );
|
||||
float fDelta = fNew - fOld;
|
||||
|
||||
if( fabsf(fDelta) > 0.0001f )
|
||||
@@ -330,10 +330,10 @@ void AdjustSync::GetSyncChangeTextSong( vector<RString> &vsAddTo )
|
||||
}
|
||||
}
|
||||
|
||||
for( unsigned i=0; i<GAMESTATE->m_pCurSong->m_Timing.m_StopSegments.size(); i++ )
|
||||
for( unsigned i=0; i<GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments.size(); i++ )
|
||||
{
|
||||
float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_StopSegments[i].m_fStopSeconds, 0.001f );
|
||||
float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_StopSegments[i].m_fStopSeconds, 0.001f );
|
||||
float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds, 0.001f );
|
||||
float fDelta = fNew - fOld;
|
||||
|
||||
if( fabsf(fDelta) > 0.0001f )
|
||||
|
||||
+7
-5
@@ -11,9 +11,10 @@ void Attack::GetAttackBeats( const Song *pSong, float &fStartBeat, float &fEndBe
|
||||
{
|
||||
ASSERT( pSong );
|
||||
ASSERT_M( fStartSecond >= 0, ssprintf("StartSecond: %f",fStartSecond) );
|
||||
|
||||
fStartBeat = pSong->GetBeatFromElapsedTime( fStartSecond );
|
||||
fEndBeat = pSong->GetBeatFromElapsedTime( fStartSecond+fSecsRemaining );
|
||||
|
||||
const TimingData &timing = pSong->m_SongTiming;
|
||||
fStartBeat = timing.GetBeatFromElapsedTime( fStartSecond );
|
||||
fEndBeat = timing.GetBeatFromElapsedTime( fStartSecond+fSecsRemaining );
|
||||
}
|
||||
|
||||
/* Get the range for an attack that's being applied in realtime, eg. during battle
|
||||
@@ -34,9 +35,10 @@ void Attack::GetRealtimeAttackBeats( const Song *pSong, const PlayerState* pPlay
|
||||
fStartBeat = min( GAMESTATE->m_fSongBeat+8, pPlayerState->m_fLastDrawnBeat );
|
||||
fStartBeat = truncf(fStartBeat)+1;
|
||||
|
||||
const float lStartSecond = pSong->GetElapsedTimeFromBeat( fStartBeat );
|
||||
const TimingData &timing = pSong->m_SongTiming;
|
||||
const float lStartSecond = timing.GetElapsedTimeFromBeat( fStartBeat );
|
||||
const float fEndSecond = lStartSecond + fSecsRemaining;
|
||||
fEndBeat = pSong->GetBeatFromElapsedTime( fEndSecond );
|
||||
fEndBeat = timing.GetBeatFromElapsedTime( fEndSecond );
|
||||
fEndBeat = truncf(fEndBeat)+1;
|
||||
|
||||
// loading the course should have caught this.
|
||||
|
||||
@@ -99,7 +99,7 @@ void AutoKeysounds::LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain )
|
||||
if( tn[pn].iKeysoundIndex >= 0 )
|
||||
{
|
||||
RString sKeysoundFilePath = sSongDir + pSong->m_vsKeysoundFile[tn[pn].iKeysoundIndex];
|
||||
float fSeconds = pSong->m_Timing.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency();
|
||||
float fSeconds = pSong->m_SongTiming.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency();
|
||||
|
||||
float fPan = 0;
|
||||
if( !bSoundIsGlobal )
|
||||
|
||||
+3
-3
@@ -419,7 +419,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac
|
||||
int iStartRow = BeatToNoteRow(fFirstBeat);
|
||||
int iEndRow = BeatToNoteRow(fEndBeat);
|
||||
|
||||
const TimingData &timing = m_pSong->m_Timing;
|
||||
const TimingData &timing = m_pSong->m_SongTiming;
|
||||
|
||||
// change BG every time signature change or 4 measures
|
||||
FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter )
|
||||
@@ -697,7 +697,7 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus
|
||||
float fBeat, fBPS, fThrowAway;
|
||||
bool bFreeze;
|
||||
int iThrowAway;
|
||||
pSong->m_Timing.GetBeatAndBPSFromElapsedTime( fCurrentTime, fBeat, fBPS, bFreeze, bFreeze, iThrowAway, fThrowAway );
|
||||
pSong->m_SongTiming.GetBeatAndBPSFromElapsedTime( fCurrentTime, fBeat, fBPS, bFreeze, bFreeze, iThrowAway, fThrowAway );
|
||||
|
||||
// Calls to Update() should *not* be scaled by music rate; fCurrentTime is. Undo it.
|
||||
const float fRate = GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;
|
||||
@@ -762,7 +762,7 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus
|
||||
m_pCurrentBGA->PlayCommand( "GainFocus" );
|
||||
|
||||
/* How much time of this BGA have we skipped? (This happens with SetSeconds.) */
|
||||
const float fStartSecond = pSong->m_Timing.GetElapsedTimeFromBeat( change.m_fStartBeat );
|
||||
const float fStartSecond = pSong->m_SongTiming.GetElapsedTimeFromBeat( change.m_fStartBeat );
|
||||
|
||||
/* This is affected by the music rate. */
|
||||
fDeltaTime = fCurrentTime - fStartSecond;
|
||||
|
||||
+3
-3
@@ -41,9 +41,9 @@ void Foreground::LoadFromSong( const Song *pSong )
|
||||
bga.m_fStartBeat = change.m_fStartBeat;
|
||||
bga.m_bFinished = false;
|
||||
|
||||
const float fStartSecond = pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat );
|
||||
const float fStartSecond = pSong->m_SongTiming.GetElapsedTimeFromBeat( bga.m_fStartBeat );
|
||||
const float fStopSecond = fStartSecond + bga.m_bga->GetTweenTimeLeft();
|
||||
bga.m_fStopBeat = pSong->m_Timing.GetBeatFromElapsedTime( fStopSecond );
|
||||
bga.m_fStopBeat = pSong->m_SongTiming.GetBeatFromElapsedTime( fStopSecond );
|
||||
|
||||
bga.m_bga->SetVisible( false );
|
||||
|
||||
@@ -82,7 +82,7 @@ void Foreground::Update( float fDeltaTime )
|
||||
bga.m_bga->SetVisible( true );
|
||||
bga.m_bga->PlayCommand( "On" );
|
||||
|
||||
const float fStartSecond = m_pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat );
|
||||
const float fStartSecond = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( bga.m_fStartBeat );
|
||||
lDeltaTime = GAMESTATE->m_fMusicSeconds - fStartSecond;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -146,7 +146,7 @@ static void StartMusic( MusicToPlay &ToPlay )
|
||||
SSCLoader::LoadFromSSCFile(ToPlay.m_sTimingFile, song) )
|
||||
{
|
||||
ToPlay.HasTiming = true;
|
||||
ToPlay.m_TimingData = song.m_Timing;
|
||||
ToPlay.m_TimingData = song.m_SongTiming;
|
||||
// get cabinet lights if any
|
||||
Steps *pStepsCabinetLights = SongUtil::GetOneSteps( &song, StepsType_lights_cabinet );
|
||||
if( pStepsCabinetLights )
|
||||
@@ -156,7 +156,7 @@ static void StartMusic( MusicToPlay &ToPlay )
|
||||
SMLoader::LoadFromSMFile(ToPlay.m_sTimingFile, song) )
|
||||
{
|
||||
ToPlay.HasTiming = true;
|
||||
ToPlay.m_TimingData = song.m_Timing;
|
||||
ToPlay.m_TimingData = song.m_SongTiming;
|
||||
// get cabinet lights if any
|
||||
Steps *pStepsCabinetLights = SongUtil::GetOneSteps( &song, StepsType_lights_cabinet );
|
||||
if( pStepsCabinetLights )
|
||||
|
||||
@@ -27,7 +27,7 @@ void GameplayAssist::PlayTicks( const NoteData &nd )
|
||||
* come out on time; the actual precise timing is handled by SetStartTime. */
|
||||
float fPositionSeconds = GAMESTATE->m_fMusicSeconds;
|
||||
fPositionSeconds += SOUNDMAN->GetPlayLatency() + (float)CommonMetrics::TICK_EARLY_SECONDS + 0.250f;
|
||||
const TimingData &timing = GAMESTATE->m_pCurSong->m_Timing;
|
||||
const TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming;
|
||||
const float fSongBeat = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds );
|
||||
|
||||
const int iSongRow = max( 0, BeatToNoteRowNotRounded( fSongBeat ) );
|
||||
|
||||
@@ -59,7 +59,7 @@ void LyricDisplay::Update( float fDeltaTime )
|
||||
if( m_iCurLyricNumber+1 < GAMESTATE->m_pCurSong->m_LyricSegments.size() )
|
||||
fEndTime = pSong->m_LyricSegments[m_iCurLyricNumber+1].m_fStartTime;
|
||||
else
|
||||
fEndTime = pSong->GetElapsedTimeFromBeat( pSong->m_fLastBeat );
|
||||
fEndTime = pSong->m_SongTiming.GetElapsedTimeFromBeat( pSong->m_fLastBeat );
|
||||
|
||||
const float fDistance = fEndTime - pSong->m_LyricSegments[m_iCurLyricNumber].m_fStartTime;
|
||||
const float fTweenBufferTime = IN_LENGTH.GetValue() + OUT_LENGTH.GetValue();
|
||||
|
||||
@@ -73,8 +73,8 @@ void SongMeterDisplay::Update( float fDeltaTime )
|
||||
{
|
||||
if( GAMESTATE->m_pCurSong )
|
||||
{
|
||||
float fSongStartSeconds = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fFirstBeat );
|
||||
float fSongEndSeconds = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat );
|
||||
float fSongStartSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fFirstBeat );
|
||||
float fSongEndSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat );
|
||||
float fPercentPositionSong = SCALE( GAMESTATE->m_fMusicSeconds, fSongStartSeconds, fSongEndSeconds, 0.0f, 1.0f );
|
||||
CLAMP( fPercentPositionSong, 0, 1 );
|
||||
|
||||
|
||||
+2
-1
@@ -466,7 +466,8 @@ int NoteData::GetNumTapNotes( int iStartIndex, int iEndIndex ) const
|
||||
FOREACH_NONEMPTY_ROW_IN_TRACK_RANGE( *this, t, r, iStartIndex, iEndIndex )
|
||||
{
|
||||
const TapNote &tn = GetTapNote(t, r);
|
||||
if( tn.type != TapNote::empty && tn.type != TapNote::mine && tn.type != TapNote::fake )
|
||||
if( tn.type != TapNote::empty && tn.type != TapNote::mine
|
||||
&& tn.type != TapNote::lift && tn.type != TapNote::fake )
|
||||
iNumNotes++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2215,7 +2215,7 @@ void NoteDataUtil::AddTapAttacks( NoteData &nd, Song* pSong )
|
||||
|
||||
for( float sec=15; sec<pSong->m_fMusicLengthSeconds; sec+=30 )
|
||||
{
|
||||
float fBeat = pSong->GetBeatFromElapsedTime( sec );
|
||||
float fBeat = pSong->m_SongTiming.GetBeatFromElapsedTime( sec );
|
||||
int iBeat = (int)fBeat;
|
||||
int iTrack = iBeat % nd.GetNumTracks(); // deterministically calculates track
|
||||
TapNote tn(
|
||||
@@ -2448,7 +2448,7 @@ void NoteDataUtil::SetHopoPossibleFlags( const Song *pSong, NoteData& ndInOut )
|
||||
FOREACH_NONEMPTY_ROW_ALL_TRACKS( ndInOut, r )
|
||||
{
|
||||
float fBeat = NoteRowToBeat( r );
|
||||
float fSeconds = pSong->GetElapsedTimeFromBeat( fBeat );
|
||||
float fSeconds = pSong->m_SongTiming.GetElapsedTimeFromBeat( fBeat );
|
||||
|
||||
int iLastTapTrack = ndInOut.GetLastTrackWithTapOrHoldHead( r );
|
||||
if( iLastTapTrack != -1 && fSeconds <= fLastRowMusicSeconds + g_fTimingWindowHopo )
|
||||
|
||||
+11
-9
@@ -742,7 +742,7 @@ void NoteField::DrawPrimitives()
|
||||
// Draw beat bars
|
||||
if( GAMESTATE->IsEditing() || SHOW_BEAT_BARS )
|
||||
{
|
||||
const vector<TimeSignatureSegment> &vTimeSignatureSegments = GAMESTATE->m_pCurSong->m_Timing.m_vTimeSignatureSegments;
|
||||
const vector<TimeSignatureSegment> &vTimeSignatureSegments = GAMESTATE->m_pCurSong->m_SongTiming.m_vTimeSignatureSegments;
|
||||
int iMeasureIndex = 0;
|
||||
FOREACH_CONST( TimeSignatureSegment, vTimeSignatureSegments, iter )
|
||||
{
|
||||
@@ -785,8 +785,10 @@ void NoteField::DrawPrimitives()
|
||||
{
|
||||
ASSERT(GAMESTATE->m_pCurSong);
|
||||
|
||||
const TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming;
|
||||
|
||||
// BPM text
|
||||
FOREACH_CONST( BPMSegment, GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments, seg )
|
||||
FOREACH_CONST( BPMSegment, timing.m_BPMSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
@@ -797,7 +799,7 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Freeze text
|
||||
FOREACH_CONST( StopSegment, GAMESTATE->m_pCurSong->m_Timing.m_StopSegments, seg )
|
||||
FOREACH_CONST( StopSegment, timing.m_StopSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
@@ -808,7 +810,7 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Warp text
|
||||
FOREACH_CONST( WarpSegment, GAMESTATE->m_pCurSong->m_Timing.m_WarpSegments, seg )
|
||||
FOREACH_CONST( WarpSegment, timing.m_WarpSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
@@ -819,7 +821,7 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Time Signature text
|
||||
FOREACH_CONST( TimeSignatureSegment, GAMESTATE->m_pCurSong->m_Timing.m_vTimeSignatureSegments, seg )
|
||||
FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
@@ -830,7 +832,7 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Tickcount text
|
||||
FOREACH_CONST( TickcountSegment, GAMESTATE->m_pCurSong->m_Timing.m_TickcountSegments, seg )
|
||||
FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
@@ -841,7 +843,7 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Combo text
|
||||
FOREACH_CONST( ComboSegment, GAMESTATE->m_pCurSong->m_Timing.m_ComboSegments, seg )
|
||||
FOREACH_CONST( ComboSegment, timing.m_ComboSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
@@ -852,7 +854,7 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Label text
|
||||
FOREACH_CONST( LabelSegment, GAMESTATE->m_pCurSong->m_Timing.m_LabelSegments, seg )
|
||||
FOREACH_CONST( LabelSegment, timing.m_LabelSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
@@ -872,7 +874,7 @@ void NoteField::DrawPrimitives()
|
||||
FOREACH_CONST( Attack, ce.attacks, a )
|
||||
{
|
||||
float fSecond = a->fStartSecond;
|
||||
float fBeat = GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTime( fSecond );
|
||||
float fBeat = timing.GetBeatFromElapsedTime( fSecond );
|
||||
|
||||
if( BeatToNoteRow(fBeat) >= iFirstRowToDraw &&
|
||||
BeatToNoteRow(fBeat) <= iLastRowToDraw)
|
||||
|
||||
@@ -799,7 +799,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
if( PREFSMAN->m_bQuirksMode )
|
||||
{
|
||||
BPMSegment newSeg( 0, fBPM );
|
||||
out.AddBPMSegment( newSeg );
|
||||
out.m_SongTiming.AddBPMSegment( newSeg );
|
||||
if( fBPM > 0.0f )
|
||||
LOG->Trace( "Inserting new positive BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM );
|
||||
else
|
||||
@@ -810,7 +810,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
if( fBPM > 0.0f )
|
||||
{
|
||||
BPMSegment newSeg( 0, fBPM );
|
||||
out.AddBPMSegment( newSeg );
|
||||
out.m_SongTiming.AddBPMSegment( newSeg );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM );
|
||||
}
|
||||
else
|
||||
@@ -901,7 +901,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
case BMS_TRACK_BPM:
|
||||
if( iVal > 0 )
|
||||
{
|
||||
out.SetBPMAtBeat( fBeat, (float) iVal );
|
||||
out.m_SongTiming.SetBPMAtBeat( fBeat, (float) iVal );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %i", fBeat, iVal );
|
||||
}
|
||||
else
|
||||
@@ -918,7 +918,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBPM ) )
|
||||
{
|
||||
float fBPM = StringToFloat( sBPM );
|
||||
out.SetBPMAtBeat( fBeat, fBPM );
|
||||
out.m_SongTiming.SetBPMAtBeat( fBeat, fBPM );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -937,12 +937,12 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBeats ) )
|
||||
{
|
||||
// find the BPM at the time of this freeze
|
||||
float fBPS = out.m_Timing.GetBPMAtBeat(fBeat) / 60.0f;
|
||||
float fBPS = out.m_SongTiming.GetBPMAtBeat(fBeat) / 60.0f;
|
||||
float fBeats = StringToFloat( sBeats ) / 48.0f;
|
||||
float fFreezeSecs = fBeats / fBPS;
|
||||
|
||||
StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs );
|
||||
out.AddStopSegment( newSeg );
|
||||
out.m_SongTiming.AddStopSegment( newSeg );
|
||||
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.m_fStopSeconds );
|
||||
}
|
||||
else
|
||||
|
||||
+12
-12
@@ -358,7 +358,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
else if( sValueName=="BPM" )
|
||||
{
|
||||
BPM1 = StringToFloat(sParams[1]);
|
||||
out.AddBPMSegment( BPMSegment(0, BPM1) );
|
||||
out.m_SongTiming.AddBPMSegment( BPMSegment(0, BPM1) );
|
||||
}
|
||||
else if( sValueName=="BPM2" )
|
||||
{
|
||||
@@ -383,7 +383,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
else if( sValueName=="STARTTIME" )
|
||||
{
|
||||
SMGap1 = -StringToFloat( sParams[1] )/100;
|
||||
out.m_Timing.m_fBeat0OffsetInSeconds = SMGap1;
|
||||
out.m_SongTiming.m_fBeat0OffsetInSeconds = SMGap1;
|
||||
}
|
||||
// This is currently required for more accurate KIU BPM changes.
|
||||
else if( sValueName=="STARTTIME2" )
|
||||
@@ -409,7 +409,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
TickcountSegment tcs;
|
||||
tcs.m_iStartRow = BeatToNoteRow(0.0f);
|
||||
tcs.m_iTicks = iTickCount > ROWS_PER_BEAT ? ROWS_PER_BEAT : iTickCount;
|
||||
out.m_Timing.AddTickcountSegment( tcs );
|
||||
out.m_SongTiming.AddTickcountSegment( tcs );
|
||||
}
|
||||
else if ( sValueName=="STEP" )
|
||||
{
|
||||
@@ -469,7 +469,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
const float beat = (BPMPos2 + SMGap1) * BeatsPerSecond;
|
||||
LOG->Trace( "BPM %f, BPS %f, BPMPos2 %f, beat %f",
|
||||
BPM1, BeatsPerSecond, BPMPos2, beat );
|
||||
out.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM2) );
|
||||
out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM2) );
|
||||
}
|
||||
|
||||
if( BPM3 > 0 && BPMPos3 > 0 )
|
||||
@@ -479,7 +479,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
const float beat = (BPMPos3 + SMGap2) * BeatsPerSecond;
|
||||
LOG->Trace( "BPM %f, BPS %f, BPMPos3 %f, beat %f",
|
||||
BPM2, BeatsPerSecond, BPMPos3, beat );
|
||||
out.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM3) );
|
||||
out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM3) );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -515,7 +515,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
TickcountSegment tcs;
|
||||
tcs.m_iStartRow = BeatToNoteRow(fCurBeat);
|
||||
tcs.m_iTicks = iTickCount > ROWS_PER_BEAT ? ROWS_PER_BEAT : iTickCount;
|
||||
out.m_Timing.AddTickcountSegment( tcs );
|
||||
out.m_SongTiming.AddTickcountSegment( tcs );
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -523,22 +523,22 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
{
|
||||
float fCurBpm = (float)numTemp;
|
||||
//out.m_Timing.AddBPMSegment( BPMSegment( BeatToNoteRow(fCurBeat), (float)numTemp ) );
|
||||
out.m_Timing.SetBPMAtBeat( fCurBeat, fCurBpm );
|
||||
out.m_SongTiming.SetBPMAtBeat( fCurBeat, fCurBpm );
|
||||
continue;
|
||||
}
|
||||
else if (BeginsWith(NoteRowString, "|E"))
|
||||
{
|
||||
// Finally! the |E| tag is working as it should. I can die happy now -DaisuMaster
|
||||
float fCurDelay = 60 / out.m_Timing.GetBPMAtBeat(fCurBeat) * (float)numTemp / iTickCount;
|
||||
fCurDelay += out.m_Timing.GetStopAtRow(BeatToNoteRow(fCurBeat) );
|
||||
out.m_Timing.SetStopAtBeat( fCurBeat, fCurDelay, true );
|
||||
float fCurDelay = 60 / out.m_SongTiming.GetBPMAtBeat(fCurBeat) * (float)numTemp / iTickCount;
|
||||
fCurDelay += out.m_SongTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) );
|
||||
out.m_SongTiming.SetStopAtBeat( fCurBeat, fCurDelay, true );
|
||||
continue;
|
||||
}
|
||||
else if (BeginsWith(NoteRowString, "|D"))
|
||||
{
|
||||
float fCurDelay = out.m_Timing.GetStopAtRow(BeatToNoteRow(fCurBeat) );
|
||||
float fCurDelay = out.m_SongTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) );
|
||||
fCurDelay += (float)numTemp / 1000;
|
||||
out.m_Timing.SetStopAtBeat( fCurBeat, fCurDelay, true );
|
||||
out.m_SongTiming.SetStopAtBeat( fCurBeat, fCurDelay, true );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,7 +682,7 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut )
|
||||
double fSecondsPerBeat = (iter->tickSeconds * GUITAR_MIDI_COUNTS_PER_BEAT);
|
||||
bpmSeg.m_fBPS = float( 1. / fSecondsPerBeat );
|
||||
|
||||
songOut.m_Timing.AddBPMSegment( bpmSeg );
|
||||
songOut.m_SongTiming.AddBPMSegment( bpmSeg );
|
||||
}
|
||||
|
||||
FOREACH_CONST( MidiFileIn::TimeSignatureChange, midi.timeSignatureEvents_, iter )
|
||||
@@ -692,7 +692,7 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut )
|
||||
seg.m_iNumerator = iter->numerator;
|
||||
seg.m_iDenominator = iter->denominator;
|
||||
|
||||
songOut.m_Timing.AddTimeSignatureSegment( seg );
|
||||
songOut.m_SongTiming.AddTimeSignatureSegment( seg );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -591,7 +591,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
if( fBPM > 0.0f )
|
||||
{
|
||||
BPMSegment newSeg( 0, fBPM );
|
||||
out.AddBPMSegment( newSeg );
|
||||
out.m_SongTiming.AddBPMSegment( newSeg );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM );
|
||||
}
|
||||
else
|
||||
@@ -673,7 +673,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
case PMS_TRACK_BPM:
|
||||
if( iVal > 0 )
|
||||
{
|
||||
out.SetBPMAtBeat( fBeat, (float) iVal );
|
||||
out.m_SongTiming.SetBPMAtBeat( fBeat, (float) iVal );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %i", fBeat, iVal );
|
||||
}
|
||||
else
|
||||
@@ -694,7 +694,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
if( fBPM > 0.0f )
|
||||
{
|
||||
BPMSegment newSeg( BeatToNoteRow(fBeat), fBPM );
|
||||
out.AddBPMSegment( newSeg );
|
||||
out.m_SongTiming.AddBPMSegment( newSeg );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", fBeat, newSeg.GetBPM() );
|
||||
}
|
||||
else
|
||||
@@ -716,12 +716,12 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBeats ) )
|
||||
{
|
||||
// find the BPM at the time of this freeze
|
||||
float fBPS = out.m_Timing.GetBPMAtBeat(fBeat) / 60.0f;
|
||||
float fBPS = out.m_SongTiming.GetBPMAtBeat(fBeat) / 60.0f;
|
||||
float fBeats = StringToFloat( sBeats ) / 48.0f;
|
||||
float fFreezeSecs = fBeats / fBPS;
|
||||
|
||||
StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs );
|
||||
out.AddStopSegment( newSeg );
|
||||
out.m_SongTiming.AddStopSegment( newSeg );
|
||||
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.m_fStopSeconds );
|
||||
}
|
||||
else
|
||||
@@ -750,7 +750,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
||||
if( fBPM > 0.0f )
|
||||
{
|
||||
BPMSegment newSeg( iStepIndex, fBPM );
|
||||
out.AddBPMSegment( newSeg );
|
||||
out.m_SongTiming.AddBPMSegment( newSeg );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(newSeg.m_iStartRow), newSeg.GetBPM() );
|
||||
|
||||
}
|
||||
|
||||
+243
-233
@@ -103,6 +103,244 @@ bool SMLoader::LoadTimingFromFile( const RString &fn, TimingData &out )
|
||||
return true;
|
||||
}
|
||||
|
||||
void SMLoader::ProcessBPMs( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> arrayBPMChangeExpressions;
|
||||
split( sParam, ",", arrayBPMChangeExpressions );
|
||||
|
||||
// prepare storage variables for negative BPMs -> Warps.
|
||||
float negBeat = -1;
|
||||
float negBPM = 1;
|
||||
float highspeedBeat = -1;
|
||||
|
||||
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayBPMChangeValues;
|
||||
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayBPMChangeValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #BPMs value \"%s\" (must have exactly one '='), ignored.",
|
||||
arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayBPMChangeValues[0] );
|
||||
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||
|
||||
if( fNewBPM < 0.0f )
|
||||
{
|
||||
out.m_bHasNegativeBpms = true;
|
||||
negBeat = fBeat;
|
||||
negBPM = fNewBPM;
|
||||
}
|
||||
else if( fNewBPM > 0.0f )
|
||||
{
|
||||
// add in a warp.
|
||||
if( negBPM < 0 )
|
||||
{
|
||||
float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat);
|
||||
WarpSegment new_seg(negBeat, endBeat);
|
||||
out.AddWarpSegment( new_seg );
|
||||
|
||||
negBeat = -1;
|
||||
negBPM = 1;
|
||||
}
|
||||
// too fast. make it a warp.
|
||||
if( fNewBPM > FAST_BPM_WARP )
|
||||
{
|
||||
highspeedBeat = fBeat;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add in a warp.
|
||||
if( highspeedBeat > 0 )
|
||||
{
|
||||
WarpSegment new_seg(highspeedBeat, fBeat);
|
||||
out.AddWarpSegment( new_seg );
|
||||
highspeedBeat = -1;
|
||||
}
|
||||
{
|
||||
BPMSegment new_seg;
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fBeat);
|
||||
new_seg.SetBPM( fNewBPM );
|
||||
out.AddBPMSegment( new_seg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SMLoader::ProcessStops( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> arrayFreezeExpressions;
|
||||
split( sParam, ",", arrayFreezeExpressions );
|
||||
|
||||
// Prepare variables for negative stop conversion.
|
||||
float negBeat = -1;
|
||||
float negPause = 0;
|
||||
|
||||
for( unsigned f=0; f<arrayFreezeExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayFreezeValues;
|
||||
split( arrayFreezeExpressions[f], "=", arrayFreezeValues );
|
||||
if( arrayFreezeValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #STOPS value \"%s\" (must have exactly one '='), ignored.",
|
||||
arrayFreezeExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] );
|
||||
const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] );
|
||||
|
||||
// Process the prior stop.
|
||||
if( negPause > 0 )
|
||||
{
|
||||
BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
|
||||
float fSecondsPerBeat = 60 / oldBPM.GetBPM();
|
||||
float fSkipBeats = negPause / fSecondsPerBeat;
|
||||
|
||||
if( negBeat + fSkipBeats > fFreezeBeat )
|
||||
fSkipBeats = fFreezeBeat - negBeat;
|
||||
|
||||
WarpSegment ws( negBeat, negBeat + fSkipBeats);
|
||||
out.AddWarpSegment( ws );
|
||||
|
||||
negBeat = -1;
|
||||
negPause = 0;
|
||||
}
|
||||
|
||||
if( fFreezeSeconds < 0.0f )
|
||||
{
|
||||
negBeat = fFreezeBeat;
|
||||
negPause = -fFreezeSeconds;
|
||||
}
|
||||
else if( fFreezeSeconds > 0.0f )
|
||||
{
|
||||
StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds );
|
||||
out.AddStopSegment( ss );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Process the prior stop if there was one.
|
||||
if( negPause > 0 )
|
||||
{
|
||||
BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
|
||||
float fSecondsPerBeat = 60 / oldBPM.GetBPM();
|
||||
float fSkipBeats = negPause / fSecondsPerBeat;
|
||||
|
||||
WarpSegment ws( negBeat, negBeat + fSkipBeats);
|
||||
out.AddWarpSegment( ws );
|
||||
}
|
||||
}
|
||||
|
||||
void SMLoader::ProcessDelays( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> arrayDelayExpressions;
|
||||
split( sParam, ",", arrayDelayExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayDelayExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayDelayValues;
|
||||
split( arrayDelayExpressions[f], "=", arrayDelayValues );
|
||||
if( arrayDelayValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #DELAYS value \"%s\" (must have exactly one '='), ignored.",
|
||||
arrayDelayExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fFreezeBeat = StringToFloat( arrayDelayValues[0] );
|
||||
const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] );
|
||||
|
||||
StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true );
|
||||
// XXX: Remove Negatives Bug?
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat);
|
||||
new_seg.m_fStopSeconds = fFreezeSeconds;
|
||||
|
||||
// LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
|
||||
if(fFreezeSeconds > 0.0f)
|
||||
out.AddStopSegment( new_seg );
|
||||
else
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds );
|
||||
}
|
||||
}
|
||||
|
||||
void SMLoader::ProcessTimeSignatures( 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() < 3 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( vs2[0] );
|
||||
|
||||
TimeSignatureSegment seg;
|
||||
seg.m_iStartRow = BeatToNoteRow(fBeat);
|
||||
seg.m_iNumerator = atoi( vs2[1] );
|
||||
seg.m_iDenominator = atoi( vs2[2] );
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg.m_iNumerator < 1 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg.m_iDenominator < 1 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.AddTimeSignatureSegment( seg );
|
||||
}
|
||||
}
|
||||
|
||||
void SMLoader::ProcessTickcounts( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> arrayTickcountExpressions;
|
||||
split( sParam, ",", arrayTickcountExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayTickcountExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayTickcountValues;
|
||||
split( arrayTickcountExpressions[f], "=", arrayTickcountValues );
|
||||
if( arrayTickcountValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #TICKCOUNTS value \"%s\" (must have exactly one '='), ignored.",
|
||||
arrayTickcountExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] );
|
||||
int iTicks = clamp(atoi( arrayTickcountValues[1] ), 0, ROWS_PER_BEAT);
|
||||
|
||||
TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks );
|
||||
out.AddTickcountSegment( new_seg );
|
||||
}
|
||||
}
|
||||
|
||||
void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
{
|
||||
out.m_fBeat0OffsetInSeconds = 0;
|
||||
@@ -123,255 +361,27 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
}
|
||||
else if( sValueName=="BPMS" )
|
||||
{
|
||||
vector<RString> arrayBPMChangeExpressions;
|
||||
split( sParams[1], ",", arrayBPMChangeExpressions );
|
||||
|
||||
// prepare storage variables for negative BPMs -> Warps.
|
||||
float negBeat = -1;
|
||||
float negBPM = 1;
|
||||
float highspeedBeat = -1;
|
||||
|
||||
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayBPMChangeValues;
|
||||
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayBPMChangeValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayBPMChangeValues[0] );
|
||||
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||
|
||||
if( fNewBPM < 0.0f )
|
||||
{
|
||||
out.m_bHasNegativeBpms = true;
|
||||
negBeat = fBeat;
|
||||
negBPM = fNewBPM;
|
||||
}
|
||||
else if( fNewBPM > 0.0f )
|
||||
{
|
||||
// add in a warp.
|
||||
if( negBPM < 0 )
|
||||
{
|
||||
float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat);
|
||||
WarpSegment new_seg(negBeat, endBeat);
|
||||
out.AddWarpSegment( new_seg );
|
||||
|
||||
negBeat = -1;
|
||||
negBPM = 1;
|
||||
}
|
||||
// too fast. make it a warp.
|
||||
if( fNewBPM > FAST_BPM_WARP )
|
||||
{
|
||||
highspeedBeat = fBeat;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add in a warp.
|
||||
if( highspeedBeat > 0 )
|
||||
{
|
||||
WarpSegment new_seg(highspeedBeat, fBeat);
|
||||
out.AddWarpSegment( new_seg );
|
||||
highspeedBeat = -1;
|
||||
}
|
||||
{
|
||||
BPMSegment new_seg;
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fBeat);
|
||||
new_seg.SetBPM( fNewBPM );
|
||||
out.AddBPMSegment( new_seg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ProcessBPMs(out, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="STOPS" || sValueName=="FREEZES" )
|
||||
{
|
||||
vector<RString> arrayFreezeExpressions;
|
||||
split( sParams[1], ",", arrayFreezeExpressions );
|
||||
|
||||
// Prepare variables for negative stop conversion.
|
||||
float negBeat = -1;
|
||||
float negPause = 0;
|
||||
|
||||
for( unsigned f=0; f<arrayFreezeExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayFreezeValues;
|
||||
split( arrayFreezeExpressions[f], "=", arrayFreezeValues );
|
||||
if( arrayFreezeValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayFreezeExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] );
|
||||
const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] );
|
||||
|
||||
// Process the prior stop.
|
||||
if( negPause > 0 )
|
||||
{
|
||||
BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
|
||||
float fSecondsPerBeat = 60 / oldBPM.GetBPM();
|
||||
float fSkipBeats = negPause / fSecondsPerBeat;
|
||||
|
||||
if( negBeat + fSkipBeats > fFreezeBeat )
|
||||
fSkipBeats = fFreezeBeat - negBeat;
|
||||
|
||||
WarpSegment ws( negBeat, negBeat + fSkipBeats);
|
||||
out.AddWarpSegment( ws );
|
||||
|
||||
negBeat = -1;
|
||||
negPause = 0;
|
||||
}
|
||||
|
||||
if( fFreezeSeconds < 0.0f )
|
||||
{
|
||||
negBeat = fFreezeBeat;
|
||||
negPause = -fFreezeSeconds;
|
||||
}
|
||||
else if( fFreezeSeconds > 0.0f )
|
||||
{
|
||||
StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds );
|
||||
out.AddStopSegment( ss );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Process the prior stop if there was one.
|
||||
if( negPause > 0 )
|
||||
{
|
||||
BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
|
||||
float fSecondsPerBeat = 60 / oldBPM.GetBPM();
|
||||
float fSkipBeats = negPause / fSecondsPerBeat;
|
||||
|
||||
WarpSegment ws( negBeat, negBeat + fSkipBeats);
|
||||
out.AddWarpSegment( ws );
|
||||
}
|
||||
ProcessStops(out, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="DELAYS" )
|
||||
{
|
||||
vector<RString> arrayDelayExpressions;
|
||||
split( sParams[1], ",", arrayDelayExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayDelayExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayDelayValues;
|
||||
split( arrayDelayExpressions[f], "=", arrayDelayValues );
|
||||
if( arrayDelayValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayDelayExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fFreezeBeat = StringToFloat( arrayDelayValues[0] );
|
||||
const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] );
|
||||
|
||||
StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true );
|
||||
// XXX: Remove Negatives Bug?
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat);
|
||||
new_seg.m_fStopSeconds = fFreezeSeconds;
|
||||
|
||||
// LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
|
||||
if(fFreezeSeconds > 0.0f)
|
||||
out.AddStopSegment( new_seg );
|
||||
else
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds );
|
||||
}
|
||||
ProcessDelays(out, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="TIMESIGNATURES" )
|
||||
{
|
||||
vector<RString> vs1;
|
||||
split( sParams[1], ",", vs1 );
|
||||
|
||||
FOREACH_CONST( RString, vs1, s1 )
|
||||
{
|
||||
vector<RString> vs2;
|
||||
split( *s1, "=", vs2 );
|
||||
|
||||
if( vs2.size() < 3 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( vs2[0] );
|
||||
|
||||
TimeSignatureSegment seg;
|
||||
seg.m_iStartRow = BeatToNoteRow(fBeat);
|
||||
seg.m_iNumerator = atoi( vs2[1] );
|
||||
seg.m_iDenominator = atoi( vs2[2] );
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg.m_iNumerator < 1 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg.m_iDenominator < 1 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.AddTimeSignatureSegment( seg );
|
||||
}
|
||||
ProcessTimeSignatures(out, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="TICKCOUNTS" )
|
||||
{
|
||||
vector<RString> arrayTickcountExpressions;
|
||||
split( sParams[1], ",", arrayTickcountExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayTickcountExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayTickcountValues;
|
||||
split( arrayTickcountExpressions[f], "=", arrayTickcountValues );
|
||||
if( arrayTickcountValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayTickcountExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] );
|
||||
int iTicks = atoi( arrayTickcountValues[1] );
|
||||
// you're lazy, let SM do the work for you... -DaisuMaster
|
||||
if( iTicks < 1) iTicks = 1;
|
||||
if( iTicks > ROWS_PER_BEAT ) iTicks = ROWS_PER_BEAT;
|
||||
|
||||
TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks );
|
||||
out.AddTickcountSegment( new_seg );
|
||||
|
||||
if(iTicks >= 1 && iTicks <= ROWS_PER_BEAT ) // Constants
|
||||
{
|
||||
// LOG->Trace( "Adding a tickcount segment: beat: %f, ticks = %d", fTickcountBeat, iTicks );
|
||||
//out.AddTickcountSegment( new_seg );
|
||||
}
|
||||
else
|
||||
{
|
||||
//LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid tickcount at beat %f, ticks %d.", fTickcountBeat, iTicks );
|
||||
//LOG->UserLog( "Song file", "(UNKNOWN)", "Clamping tickcount value to %d at beat %f.", iTicks, fTickcountBeat);
|
||||
//etc
|
||||
}
|
||||
}
|
||||
ProcessTickcounts(out, sParams[1]);
|
||||
}
|
||||
// Ensure all of the warps are handled right.
|
||||
sort(out.m_WarpSegments.begin(), out.m_WarpSegments.end());
|
||||
|
||||
@@ -25,6 +25,13 @@ namespace SMLoader
|
||||
bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot );
|
||||
bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||
bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression );
|
||||
|
||||
|
||||
void ProcessBPMs( TimingData &, const RString );
|
||||
void ProcessStops( TimingData &, const RString );
|
||||
void ProcessDelays( TimingData &, const RString );
|
||||
void ProcessTimeSignatures( TimingData &, const RString );
|
||||
void ProcessTickcounts( TimingData &, const RString );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -113,8 +113,8 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out )
|
||||
return false;
|
||||
}
|
||||
|
||||
out.m_Timing.m_sFile = sPath;
|
||||
LoadTimingFromSMAFile( msd, out.m_Timing );
|
||||
out.m_SongTiming.m_sFile = sPath;
|
||||
LoadTimingFromSMAFile( msd, out.m_SongTiming );
|
||||
|
||||
for( unsigned i=0; i<msd.GetNumValues(); i++ )
|
||||
{
|
||||
|
||||
+111
-393
@@ -4,7 +4,7 @@
|
||||
#include "GameManager.h"
|
||||
#include "MsdFile.h" // No JSON here.
|
||||
#include "NoteTypes.h"
|
||||
#include "NotesLoaderSM.h" // For loading SM style edits.
|
||||
#include "NotesLoaderSM.h" // For programming shortcuts.
|
||||
#include "RageFileManager.h"
|
||||
#include "RageLog.h"
|
||||
#include "RageUtil.h"
|
||||
@@ -21,79 +21,13 @@ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60 KB
|
||||
|
||||
/**
|
||||
* @brief Attempt to load any background changes in use by this song.
|
||||
*
|
||||
* This code is right now copied from NotesLoaderSM. There may be a time
|
||||
* when we add to this code, or perhaps just refactor it properly.
|
||||
* @param change a reference to the background change.
|
||||
* @param sBGChangeExpression a reference to the list of changes to be made.
|
||||
* @return its success or failure.
|
||||
*/
|
||||
bool LoadFromBGSSCChangesString( BackgroundChange &change, const RString &sBGChangeExpression )
|
||||
{
|
||||
vector<RString> aBGChangeValues;
|
||||
split( sBGChangeExpression, "=", aBGChangeValues, false );
|
||||
|
||||
aBGChangeValues.resize( min((int)aBGChangeValues.size(),11) );
|
||||
|
||||
switch( aBGChangeValues.size() )
|
||||
{
|
||||
case 11:
|
||||
change.m_def.m_sColor2 = aBGChangeValues[10];
|
||||
change.m_def.m_sColor2.Replace( '^', ',' );
|
||||
change.m_def.m_sColor2 = RageColor::NormalizeColorString( change.m_def.m_sColor2 );
|
||||
// fall through
|
||||
case 10:
|
||||
change.m_def.m_sColor1 = aBGChangeValues[9];
|
||||
change.m_def.m_sColor1.Replace( '^', ',' );
|
||||
change.m_def.m_sColor1 = RageColor::NormalizeColorString( change.m_def.m_sColor1 );
|
||||
// fall through
|
||||
case 9:
|
||||
change.m_sTransition = aBGChangeValues[8];
|
||||
// fall through
|
||||
case 8:
|
||||
change.m_def.m_sFile2 = aBGChangeValues[7];
|
||||
// fall through
|
||||
case 7:
|
||||
change.m_def.m_sEffect = aBGChangeValues[6];
|
||||
// fall through
|
||||
case 6:
|
||||
// param 7 overrides this.
|
||||
// Backward compatibility:
|
||||
if( change.m_def.m_sEffect.empty() )
|
||||
{
|
||||
bool bLoop = atoi( aBGChangeValues[5] ) != 0;
|
||||
if( !bLoop )
|
||||
change.m_def.m_sEffect = SBE_StretchNoLoop;
|
||||
}
|
||||
// fall through
|
||||
case 5:
|
||||
// param 7 overrides this.
|
||||
// Backward compatibility:
|
||||
if( change.m_def.m_sEffect.empty() )
|
||||
{
|
||||
bool bRewindMovie = atoi( aBGChangeValues[4] ) != 0;
|
||||
if( bRewindMovie )
|
||||
change.m_def.m_sEffect = SBE_StretchRewind;
|
||||
}
|
||||
// fall through
|
||||
case 4:
|
||||
// param 9 overrides this.
|
||||
// Backward compatibility:
|
||||
if( change.m_sTransition.empty() )
|
||||
change.m_sTransition = (atoi( aBGChangeValues[3] ) != 0) ? "CrossFade" : "";
|
||||
// fall through
|
||||
case 3:
|
||||
change.m_fRate = StringToFloat( aBGChangeValues[2] );
|
||||
// fall through
|
||||
case 2:
|
||||
change.m_def.m_sFile1 = aBGChangeValues[1];
|
||||
// fall through
|
||||
case 1:
|
||||
change.m_fStartBeat = StringToFloat( aBGChangeValues[0] );
|
||||
// fall through
|
||||
}
|
||||
|
||||
return aBGChangeValues.size() >= 2;
|
||||
return SMLoader::LoadFromBGChangesString( change, sBGChangeExpression );
|
||||
}
|
||||
|
||||
bool SSCLoader::LoadFromDir( const RString &sPath, Song &out )
|
||||
@@ -112,6 +46,86 @@ bool SSCLoader::LoadFromDir( const RString &sPath, Song &out )
|
||||
return LoadFromSSCFile( sPath + aFileNames[0], out );
|
||||
}
|
||||
|
||||
void SSCLoader::ProcessWarps( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> arrayWarpExpressions;
|
||||
split( sParam, ",", arrayWarpExpressions );
|
||||
|
||||
for( unsigned b=0; b<arrayWarpExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayWarpValues;
|
||||
split( arrayWarpExpressions[b], "=", arrayWarpValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayWarpValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #WARPS value \"%s\" (must have exactly one '='), ignored.",
|
||||
arrayWarpExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayWarpValues[0] );
|
||||
const float fNewBeat = StringToFloat( arrayWarpValues[1] );
|
||||
|
||||
if(fNewBeat > fBeat)
|
||||
out.AddWarpSegment( WarpSegment(fBeat, fNewBeat) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Warp at beat %f, BPM %f.", fBeat, fNewBeat );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SSCLoader::ProcessLabels( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> arrayLabelExpressions;
|
||||
split( sParam, ",", arrayLabelExpressions );
|
||||
|
||||
for( unsigned b=0; b<arrayLabelExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayLabelValues;
|
||||
split( arrayLabelExpressions[b], "=", arrayLabelValues );
|
||||
if( arrayLabelValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #LABELS value \"%s\" (must have exactly one '='), ignored.",
|
||||
arrayLabelExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayLabelValues[0] );
|
||||
RString sLabel = arrayLabelValues[1];
|
||||
TrimRight(sLabel);
|
||||
if( fBeat >= 0.0f )
|
||||
out.AddLabelSegment( LabelSegment(fBeat, sLabel) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Label at beat %f called %s.", fBeat, sLabel.c_str() );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SSCLoader::ProcessCombos( TimingData &out, const RString sParam )
|
||||
{
|
||||
vector<RString> arrayComboExpressions;
|
||||
split( sParam, ",", arrayComboExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayComboExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayComboValues;
|
||||
split( arrayComboExpressions[f], "=", arrayComboValues );
|
||||
if( arrayComboValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #COMBOS value \"%s\" (must have exactly one '='), ignored.",
|
||||
arrayComboExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
const float fComboBeat = StringToFloat( arrayComboValues[0] );
|
||||
const int iCombos = atoi( arrayComboValues[1] );
|
||||
ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos );
|
||||
out.AddComboSegment( new_seg );
|
||||
}
|
||||
}
|
||||
|
||||
bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCache )
|
||||
{
|
||||
LOG->Trace( "Song::LoadFromSSCFile(%s)", sPath.c_str() );
|
||||
@@ -123,7 +137,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
return false;
|
||||
}
|
||||
|
||||
out.m_Timing.m_sFile = sPath; // songs still have their fallback timing.
|
||||
out.m_SongTiming.m_sFile = sPath; // songs still have their fallback timing.
|
||||
|
||||
int state = GETTING_SONG_INFO;
|
||||
const unsigned values = msd.GetNumValues();
|
||||
@@ -384,270 +398,47 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
|
||||
else if( sValueName=="OFFSET" )
|
||||
{
|
||||
out.m_Timing.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] );
|
||||
out.m_SongTiming.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] );
|
||||
}
|
||||
/* Below are the song based timings that should only be used
|
||||
* if the steps do not have their own timing. */
|
||||
else if( sValueName=="STOPS" )
|
||||
{
|
||||
vector<RString> arrayFreezeExpressions;
|
||||
split( sParams[1], ",", arrayFreezeExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayFreezeExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayFreezeValues;
|
||||
split( arrayFreezeExpressions[f], "=", arrayFreezeValues );
|
||||
if( arrayFreezeValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayFreezeExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] );
|
||||
const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] );
|
||||
StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds );
|
||||
|
||||
if(fFreezeSeconds > 0.0f)
|
||||
{
|
||||
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
out.m_Timing.AddStopSegment( new_seg );
|
||||
}
|
||||
else
|
||||
{
|
||||
// negative stops (hi JS!) -aj
|
||||
if( PREFSMAN->m_bQuirksMode )
|
||||
{
|
||||
// LOG->Trace( "Adding a negative freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
out.m_Timing.AddStopSegment( new_seg );
|
||||
}
|
||||
else
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid stop at beat %f, length %f.", fFreezeBeat, fFreezeSeconds );
|
||||
}
|
||||
}
|
||||
SMLoader::ProcessStops(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
else if( sValueName=="DELAYS" )
|
||||
{
|
||||
vector<RString> arrayDelayExpressions;
|
||||
split( sParams[1], ",", arrayDelayExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayDelayExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayDelayValues;
|
||||
split( arrayDelayExpressions[f], "=", arrayDelayValues );
|
||||
if( arrayDelayValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayDelayExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fFreezeBeat = StringToFloat( arrayDelayValues[0] );
|
||||
const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] );
|
||||
|
||||
StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true );
|
||||
|
||||
// LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
|
||||
if(fFreezeSeconds > 0.0f)
|
||||
out.m_Timing.AddStopSegment( new_seg );
|
||||
else
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds );
|
||||
}
|
||||
SMLoader::ProcessDelays(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="BPMS" )
|
||||
{
|
||||
vector<RString> arrayBPMChangeExpressions;
|
||||
split( sParams[1], ",", arrayBPMChangeExpressions );
|
||||
|
||||
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayBPMChangeValues;
|
||||
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayBPMChangeValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayBPMChangeValues[0] );
|
||||
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||
|
||||
if(fNewBPM > 0.0f)
|
||||
out.m_Timing.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) );
|
||||
else
|
||||
{
|
||||
out.m_Timing.m_bHasNegativeBpms = true;
|
||||
// only add Negative BPMs in quirks mode -aj
|
||||
if( PREFSMAN->m_bQuirksMode )
|
||||
out.m_Timing.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) );
|
||||
else
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM );
|
||||
}
|
||||
}
|
||||
SMLoader::ProcessBPMs(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="WARPS" )
|
||||
{
|
||||
vector<RString> arrayWarpExpressions;
|
||||
split( sParams[1], ",", arrayWarpExpressions );
|
||||
|
||||
for( unsigned b=0; b<arrayWarpExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayWarpValues;
|
||||
split( arrayWarpExpressions[b], "=", arrayWarpValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayWarpValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayWarpExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayWarpValues[0] );
|
||||
const float fNewBeat = StringToFloat( arrayWarpValues[1] );
|
||||
|
||||
if(fNewBeat > fBeat)
|
||||
out.m_Timing.AddWarpSegment( WarpSegment(fBeat, fNewBeat) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Warp at beat %f, BPM %f.", fBeat, fNewBeat );
|
||||
}
|
||||
}
|
||||
ProcessWarps( out.m_SongTiming, sParams[1] );
|
||||
}
|
||||
|
||||
else if( sValueName=="LABELS" )
|
||||
{
|
||||
vector<RString> arrayLabelExpressions;
|
||||
split( sParams[1], ",", arrayLabelExpressions );
|
||||
|
||||
for( unsigned b=0; b<arrayLabelExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayLabelValues;
|
||||
split( arrayLabelExpressions[b], "=", arrayLabelValues );
|
||||
if( arrayLabelValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayLabelExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayLabelValues[0] );
|
||||
RString sLabel = arrayLabelValues[1];
|
||||
TrimRight(sLabel);
|
||||
if( fBeat >= 0.0f )
|
||||
out.m_Timing.AddLabelSegment( LabelSegment(fBeat, sLabel) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Label at beat %f called %s.", fBeat, sLabel.c_str() );
|
||||
}
|
||||
|
||||
}
|
||||
ProcessLabels( out.m_SongTiming, sParams[1] );
|
||||
}
|
||||
|
||||
else if( sValueName=="TIMESIGNATURES" )
|
||||
{
|
||||
vector<RString> vs1;
|
||||
split( sParams[1], ",", vs1 );
|
||||
|
||||
FOREACH_CONST( RString, vs1, s1 )
|
||||
{
|
||||
vector<RString> vs2;
|
||||
split( *s1, "=", vs2 );
|
||||
|
||||
if( vs2.size() < 3 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( vs2[0] );
|
||||
|
||||
TimeSignatureSegment seg;
|
||||
seg.m_iStartRow = BeatToNoteRow(fBeat);
|
||||
seg.m_iNumerator = atoi( vs2[1] );
|
||||
seg.m_iDenominator = atoi( vs2[2] );
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg.m_iNumerator < 1 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg.m_iDenominator < 1 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.m_Timing.AddTimeSignatureSegment( seg );
|
||||
}
|
||||
SMLoader::ProcessTimeSignatures(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="TICKCOUNTS" )
|
||||
{
|
||||
vector<RString> arrayTickcountExpressions;
|
||||
split( sParams[1], ",", arrayTickcountExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayTickcountExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayTickcountValues;
|
||||
split( arrayTickcountExpressions[f], "=", arrayTickcountValues );
|
||||
if( arrayTickcountValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayTickcountExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] );
|
||||
const int iTicks = atoi( arrayTickcountValues[1] );
|
||||
TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks );
|
||||
|
||||
if(iTicks >= 1 && iTicks <= ROWS_PER_BEAT ) // Constants
|
||||
{
|
||||
// LOG->Trace( "Adding a tickcount segment: beat: %f, ticks = %d", fTickcountBeat, iTicks );
|
||||
out.m_Timing.AddTickcountSegment( new_seg );
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid tickcount at beat %f, ticks %d.", fTickcountBeat, iTicks );
|
||||
}
|
||||
}
|
||||
SMLoader::ProcessTickcounts(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="COMBOS" )
|
||||
{
|
||||
vector<RString> arrayComboExpressions;
|
||||
split( sParams[1], ",", arrayComboExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayComboExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayComboValues;
|
||||
split( arrayComboExpressions[f], "=", arrayComboValues );
|
||||
if( arrayComboValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayComboExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
const float fComboBeat = StringToFloat( arrayComboValues[0] );
|
||||
const int iCombos = atoi( arrayComboValues[1] );
|
||||
ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos );
|
||||
out.m_Timing.AddComboSegment( new_seg );
|
||||
}
|
||||
ProcessCombos( out.m_SongTiming, sParams[1] );
|
||||
}
|
||||
|
||||
/* The following are cache tags. Never fill their values
|
||||
@@ -756,41 +547,14 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
out.AddSteps( pNewNotes );
|
||||
}
|
||||
|
||||
else if( sValueName=="BPMS" )
|
||||
else if( sValueName=="BPMS" ) // This must ALWAYS be here in Split Timing.
|
||||
{
|
||||
/*
|
||||
state = GETTING_STEP_TIMING_INFO;
|
||||
vector<RString> arrayBPMChangeExpressions;
|
||||
split( sParams[1], ",", arrayBPMChangeExpressions );
|
||||
|
||||
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayBPMChangeValues;
|
||||
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayBPMChangeValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayBPMChangeValues[0] );
|
||||
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||
|
||||
if(fNewBPM > 0.0f)
|
||||
pNewNotes->m_Timing.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) );
|
||||
else
|
||||
{
|
||||
pNewNotes->m_Timing.m_bHasNegativeBpms = true;
|
||||
// only add Negative BPMs in quirks mode -aj
|
||||
if( PREFSMAN->m_bQuirksMode )
|
||||
pNewNotes->m_Timing.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) );
|
||||
else
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM );
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
pNewNotes->m_Timing = TimingData(out.m_SongTiming.m_fBeat0OffsetInSeconds);
|
||||
SMLoader::ProcessBPMs(pNewNotes->m_Timing, sParams[1]);
|
||||
*/
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -798,28 +562,31 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
{
|
||||
if( sValueName=="STOPS" )
|
||||
{
|
||||
// copy from above when it's time.
|
||||
// SMLoader::ProcessStops(pNewNotes->m_Timing, sParams[1]);
|
||||
}
|
||||
else if( sValueName=="DELAYS" )
|
||||
{
|
||||
// copy from above when it's time.
|
||||
// SMLoader::ProcessDelays(pNewNotes->m_Timing, sParams[1]);
|
||||
}
|
||||
else if( sValueName=="TIMESIGNATURES" )
|
||||
{
|
||||
// copy from above when it's time.
|
||||
// SMLoader::ProcessTimeSignatures(pNewNotes->m_Timing, sParams[1]);
|
||||
}
|
||||
|
||||
else if( sValueName=="TICKCOUNTS" )
|
||||
{
|
||||
// copy from above when it's time.
|
||||
// SMLoader::ProcessTickcounts(pNewNotes->m_Timing, sParams[1]);
|
||||
}
|
||||
else if( sValueName=="COMBOS" )
|
||||
{
|
||||
// copy from above when it's time.
|
||||
// ProcessCombos(pNewNotes->m_Timing, sParams[1]);
|
||||
}
|
||||
else if( sValueName=="WARPS" || sValueName=="LABELS" )
|
||||
else if( sValueName=="WARPS" )
|
||||
{
|
||||
// copy from above when it's time.
|
||||
// ProcessWarps(pNewNotes->m_Timing, sParams[1]);
|
||||
}
|
||||
else if( sValueName=="LABELS" )
|
||||
{
|
||||
// ProcessLabels(pNewNotes->m_Timing, sParams[1]);
|
||||
}
|
||||
else if( sValueName=="ATTACKS" )
|
||||
{
|
||||
@@ -874,10 +641,9 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
*/
|
||||
}
|
||||
|
||||
else if( sValueName=="NOTES" )
|
||||
else if( sValueName=="NOTES" || sValueName=="NOTES2" )
|
||||
{
|
||||
state = GETTING_SONG_INFO;
|
||||
// pNewNotes->m_Timing.m_fBeat0OffsetInSeconds = out.m_Timing.m_fBeat0OffsetInSeconds;
|
||||
pNewNotes->SetSMNoteData( sParams[1] );
|
||||
pNewNotes->TidyUpData();
|
||||
out.AddSteps( pNewNotes );
|
||||
@@ -1095,55 +861,7 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat
|
||||
|
||||
void SSCLoader::TidyUpData( Song &song, bool bFromCache )
|
||||
{
|
||||
/*
|
||||
* Hack: if the song has any changes at all (so it won't use a random BGA)
|
||||
* and doesn't end with "-nosongbg-", add a song background BGC. Remove
|
||||
* "-nosongbg-" if it exists.
|
||||
*
|
||||
* This way, songs that were created earlier, when we added the song BG
|
||||
* at the end by default, will still behave as expected; all new songs will
|
||||
* have to add an explicit song BG tag if they want it. This is really a
|
||||
* formatting hack only; nothing outside of SMLoader ever sees "-nosongbg-".
|
||||
*/
|
||||
vector<BackgroundChange> &bg = song.GetBackgroundChanges(BACKGROUND_LAYER_1);
|
||||
if( !bg.empty() )
|
||||
{
|
||||
/* BGChanges have been sorted. On the odd chance that a BGChange exists
|
||||
* with a very high beat, search the whole list. */
|
||||
bool bHasNoSongBgTag = false;
|
||||
|
||||
for( unsigned i = 0; !bHasNoSongBgTag && i < bg.size(); ++i )
|
||||
{
|
||||
if( !bg[i].m_def.m_sFile1.CompareNoCase(NO_SONG_BG_FILE) )
|
||||
{
|
||||
bg.erase( bg.begin()+i );
|
||||
bHasNoSongBgTag = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If there's no -nosongbg- tag, add the song BG.
|
||||
if( !bHasNoSongBgTag ) do
|
||||
{
|
||||
/* If we're loading cache, -nosongbg- should always be in there. We
|
||||
* must not call IsAFile(song.GetBackgroundPath()) when loading cache. */
|
||||
if( bFromCache )
|
||||
break;
|
||||
|
||||
/* If BGChanges already exist after the last beat, don't add the
|
||||
* background in the middle. */
|
||||
if( !bg.empty() && bg.back().m_fStartBeat-0.0001f >= song.m_fLastBeat )
|
||||
break;
|
||||
|
||||
// If the last BGA is already the song BGA, don't add a duplicate.
|
||||
if( !bg.empty() && !bg.back().m_def.m_sFile1.CompareNoCase(song.m_sBackgroundFile) )
|
||||
break;
|
||||
|
||||
if( !IsAFile( song.GetBackgroundPath() ) )
|
||||
break;
|
||||
|
||||
bg.push_back( BackgroundChange(song.m_fLastBeat,song.m_sBackgroundFile) );
|
||||
} while(0);
|
||||
}
|
||||
SMLoader::TidyUpData(song, bFromCache);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -25,6 +25,8 @@ enum SSCLoadingStates
|
||||
const float VERSION_RADAR_FAKE = 0.53f;
|
||||
/** @brief The version where WarpSegments started to be utilized. */
|
||||
const float VERSION_WARP_SEGMENT = 0.56f;
|
||||
/** @brief The version that formally introduced Split Timing. */
|
||||
const float VERSION_SPLIT_TIMING = 0.7f;
|
||||
|
||||
/**
|
||||
* @brief The SSCLoader handles all of the parsing needed for .ssc files.
|
||||
@@ -75,6 +77,11 @@ namespace SSCLoader
|
||||
* @param bFromCache a flag to determine if this song is loaded from a cache file.
|
||||
*/
|
||||
void TidyUpData( Song &song, bool bFromCache );
|
||||
|
||||
|
||||
void ProcessWarps( TimingData &, const RString );
|
||||
void ProcessLabels( TimingData &, const RString );
|
||||
void ProcessCombos( TimingData &, const RString );
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
|
||||
+27
-27
@@ -74,7 +74,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
f.PutLine( "#INSTRUMENTTRACK:" + s + ";\n" );
|
||||
}
|
||||
}
|
||||
f.PutLine( ssprintf( "#OFFSET:%.6f;", out.m_Timing.m_fBeat0OffsetInSeconds ) );
|
||||
f.PutLine( ssprintf( "#OFFSET:%.6f;", out.m_SongTiming.m_fBeat0OffsetInSeconds ) );
|
||||
f.PutLine( ssprintf( "#SAMPLESTART:%.6f;", out.m_fMusicSampleStartSeconds ) );
|
||||
f.PutLine( ssprintf( "#SAMPLELENGTH:%.6f;", out.m_fMusicSampleLengthSeconds ) );
|
||||
if( out.m_fSpecifiedLastBeat > 0 )
|
||||
@@ -107,39 +107,39 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
}
|
||||
|
||||
f.Write( "#BPMS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_BPMSegments.size(); i++ )
|
||||
for( unsigned i=0; i<out.m_SongTiming.m_BPMSegments.size(); i++ )
|
||||
{
|
||||
const BPMSegment &bs = out.m_Timing.m_BPMSegments[i];
|
||||
const BPMSegment &bs = out.m_SongTiming.m_BPMSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(bs.m_iStartRow), bs.GetBPM() ) );
|
||||
if( i != out.m_Timing.m_BPMSegments.size()-1 )
|
||||
if( i != out.m_SongTiming.m_BPMSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
f.Write( "#STOPS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_StopSegments.size(); i++ )
|
||||
for( unsigned i=0; i<out.m_SongTiming.m_StopSegments.size(); i++ )
|
||||
{
|
||||
const StopSegment &fs = out.m_Timing.m_StopSegments[i];
|
||||
const StopSegment &fs = out.m_SongTiming.m_StopSegments[i];
|
||||
|
||||
if(!fs.m_bDelay)
|
||||
{
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(fs.m_iStartRow), fs.m_fStopSeconds ) );
|
||||
if( i != out.m_Timing.m_StopSegments.size()-1 )
|
||||
if( i != out.m_SongTiming.m_StopSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
f.Write( "#DELAYS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_StopSegments.size(); i++ )
|
||||
for( unsigned i=0; i<out.m_SongTiming.m_StopSegments.size(); i++ )
|
||||
{
|
||||
const StopSegment &fs = out.m_Timing.m_StopSegments[i];
|
||||
const StopSegment &fs = out.m_SongTiming.m_StopSegments[i];
|
||||
|
||||
if( fs.m_bDelay )
|
||||
{
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(fs.m_iStartRow), fs.m_fStopSeconds ) );
|
||||
if( i != out.m_Timing.m_StopSegments.size()-1 )
|
||||
if( i != out.m_SongTiming.m_StopSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
}
|
||||
@@ -147,61 +147,61 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
|
||||
|
||||
f.Write( "#WARPS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_WarpSegments.size(); i++ )
|
||||
for( unsigned i=0; i<out.m_SongTiming.m_WarpSegments.size(); i++ )
|
||||
{
|
||||
const WarpSegment &ws = out.m_Timing.m_WarpSegments[i];
|
||||
const WarpSegment &ws = out.m_SongTiming.m_WarpSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(ws.m_iStartRow), ws.m_fEndBeat ) );
|
||||
if( i != out.m_Timing.m_WarpSegments.size()-1 )
|
||||
if( i != out.m_SongTiming.m_WarpSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
|
||||
ASSERT( !out.m_Timing.m_vTimeSignatureSegments.empty() );
|
||||
ASSERT( !out.m_SongTiming.m_vTimeSignatureSegments.empty() );
|
||||
f.Write( "#TIMESIGNATURES:" );
|
||||
FOREACH_CONST( TimeSignatureSegment, out.m_Timing.m_vTimeSignatureSegments, iter )
|
||||
FOREACH_CONST( TimeSignatureSegment, out.m_SongTiming.m_vTimeSignatureSegments, iter )
|
||||
{
|
||||
f.PutLine( ssprintf( "%.6f=%d=%d", NoteRowToBeat(iter->m_iStartRow), iter->m_iNumerator, iter->m_iDenominator ) );
|
||||
vector<TimeSignatureSegment>::const_iterator iter2 = iter;
|
||||
iter2++;
|
||||
if( iter2 != out.m_Timing.m_vTimeSignatureSegments.end() )
|
||||
if( iter2 != out.m_SongTiming.m_vTimeSignatureSegments.end() )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
ASSERT( !out.m_Timing.m_TickcountSegments.empty() );
|
||||
ASSERT( !out.m_SongTiming.m_TickcountSegments.empty() );
|
||||
f.Write( "#TICKCOUNTS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_TickcountSegments.size(); i++ )
|
||||
for( unsigned i=0; i<out.m_SongTiming.m_TickcountSegments.size(); i++ )
|
||||
{
|
||||
const TickcountSegment &ts = out.m_Timing.m_TickcountSegments[i];
|
||||
const TickcountSegment &ts = out.m_SongTiming.m_TickcountSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%d", NoteRowToBeat(ts.m_iStartRow), ts.m_iTicks ) );
|
||||
if( i != out.m_Timing.m_TickcountSegments.size()-1 )
|
||||
if( i != out.m_SongTiming.m_TickcountSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
|
||||
ASSERT( !out.m_Timing.m_ComboSegments.empty() );
|
||||
ASSERT( !out.m_SongTiming.m_ComboSegments.empty() );
|
||||
f.Write( "#COMBOS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_ComboSegments.size(); i++ )
|
||||
for( unsigned i=0; i<out.m_SongTiming.m_ComboSegments.size(); i++ )
|
||||
{
|
||||
const ComboSegment &cs = out.m_Timing.m_ComboSegments[i];
|
||||
const ComboSegment &cs = out.m_SongTiming.m_ComboSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%d", NoteRowToBeat(cs.m_iStartRow), cs.m_iCombo ) );
|
||||
if( i != out.m_Timing.m_ComboSegments.size()-1 )
|
||||
if( i != out.m_SongTiming.m_ComboSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
f.Write( "#LABELS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_LabelSegments.size(); i++ )
|
||||
for( unsigned i=0; i<out.m_SongTiming.m_LabelSegments.size(); i++ )
|
||||
{
|
||||
const LabelSegment &ls = out.m_Timing.m_LabelSegments[i];
|
||||
const LabelSegment &ls = out.m_SongTiming.m_LabelSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%s", NoteRowToBeat(ls.m_iStartRow), ls.m_sLabel.c_str() ) );
|
||||
if( i != out.m_Timing.m_LabelSegments.size()-1 )
|
||||
if( i != out.m_SongTiming.m_LabelSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
+14
-14
@@ -1528,7 +1528,7 @@ int Player::GetClosestNoteDirectional( int col, int iStartRow, int iEndRow, bool
|
||||
// Is this the row we want?
|
||||
do {
|
||||
const TapNote &tn = begin->second;
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( begin->first ) )
|
||||
if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( begin->first ) )
|
||||
break;
|
||||
if( tn.type == TapNote::empty )
|
||||
break;
|
||||
@@ -1579,7 +1579,7 @@ int Player::GetClosestNonEmptyRowDirectional( int iStartRow, int iEndRow, bool b
|
||||
++iter;
|
||||
continue;
|
||||
}
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iter.Row() ) )
|
||||
if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iter.Row() ) )
|
||||
{
|
||||
++iter;
|
||||
continue;
|
||||
@@ -1873,7 +1873,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b
|
||||
break;
|
||||
}
|
||||
|
||||
const float fSongBeat = GAMESTATE->m_pCurSong ? GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds ) : GAMESTATE->m_fSongBeat;
|
||||
const float fSongBeat = GAMESTATE->m_pCurSong ? GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds ) : GAMESTATE->m_fSongBeat;
|
||||
const int iSongRow = row == -1 ? BeatToNoteRow( fSongBeat ) : row;
|
||||
|
||||
if( col != -1 && !bRelease )
|
||||
@@ -2011,8 +2011,8 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b
|
||||
* "jack hammers." Hmm.
|
||||
*/
|
||||
const int iStepSearchRows = max(
|
||||
BeatToNoteRow( GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds + StepSearchDistance ) ) - iSongRow,
|
||||
iSongRow - BeatToNoteRow( GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds - StepSearchDistance ) )
|
||||
BeatToNoteRow( GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds + StepSearchDistance ) ) - iSongRow,
|
||||
iSongRow - BeatToNoteRow( GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds - StepSearchDistance ) )
|
||||
) + ROWS_PER_BEAT;
|
||||
int iRowOfOverlappingNoteOrRow = row;
|
||||
if( row == -1 )
|
||||
@@ -2039,7 +2039,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b
|
||||
float fNoteOffset = 0.0f;
|
||||
// we need this later if we are autosyncing
|
||||
const float fStepBeat = NoteRowToBeat( iRowOfOverlappingNoteOrRow );
|
||||
const float fStepSeconds = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat(fStepBeat);
|
||||
const float fStepSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat(fStepBeat);
|
||||
|
||||
if( row == -1 )
|
||||
{
|
||||
@@ -2089,7 +2089,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b
|
||||
// Stepped too close to mine?
|
||||
if( !bRelease && ( REQUIRE_STEP_ON_MINES == !bHeld ) &&
|
||||
fSecondsFromExact <= GetWindowSeconds(TW_Mine) &&
|
||||
!GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow(iSongRow) )
|
||||
!GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow(iSongRow) )
|
||||
score = TNS_HitMine;
|
||||
break;
|
||||
|
||||
@@ -2564,7 +2564,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
|
||||
float fThrowAway;
|
||||
int iWarpBeginRow;
|
||||
float fWarpLength;
|
||||
GAMESTATE->m_pCurSong->m_Timing.GetBeatAndBPSFromElapsedTime( fEarliestTime, fMissIfOlderThanThisBeat, fThrowAway, bFreeze, bDelay, iWarpBeginRow, fWarpLength );
|
||||
GAMESTATE->m_pCurSong->m_SongTiming.GetBeatAndBPSFromElapsedTime( fEarliestTime, fMissIfOlderThanThisBeat, fThrowAway, bFreeze, bDelay, iWarpBeginRow, fWarpLength );
|
||||
|
||||
iMissIfOlderThanThisRow = BeatToNoteRow( fMissIfOlderThanThisBeat );
|
||||
if( bFreeze || bDelay )
|
||||
@@ -2587,7 +2587,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
|
||||
continue;
|
||||
|
||||
// Ignore all notes that are skipped via WARPS.
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iter.Row() ) )
|
||||
if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iter.Row() ) )
|
||||
continue;
|
||||
|
||||
if( tn.type == TapNote::mine )
|
||||
@@ -2622,7 +2622,7 @@ void Player::UpdateJudgedRows()
|
||||
int iRow = iter.Row();
|
||||
|
||||
// If row is within a warp section, ignore it. -aj
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow(iRow) )
|
||||
if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow(iRow) )
|
||||
continue;
|
||||
|
||||
if( iLastSeenRow != iRow )
|
||||
@@ -2843,13 +2843,13 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
|
||||
int iCheckpointFrequencyRows = ROWS_PER_BEAT/2;
|
||||
if( CHECKPOINTS_USE_TICKCOUNTS )
|
||||
{
|
||||
int tickCurrent = GAMESTATE->m_pCurSong->m_Timing.GetTickcountAtRow( iLastRowCrossed );
|
||||
int tickCurrent = GAMESTATE->m_pCurSong->m_SongTiming.GetTickcountAtRow( iLastRowCrossed );
|
||||
// There are some charts that don't want tickcounts involved at all.
|
||||
iCheckpointFrequencyRows = (tickCurrent > 0 ? ROWS_PER_BEAT / tickCurrent : 0);
|
||||
}
|
||||
else if( CHECKPOINTS_USE_TIME_SIGNATURES )
|
||||
{
|
||||
TimeSignatureSegment tSignature = GAMESTATE->m_pCurSong->m_Timing.GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) );
|
||||
TimeSignatureSegment tSignature = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) );
|
||||
|
||||
// Most songs are in 4/4 time. The frequency for checking tick counts should reflect that.
|
||||
iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.m_iDenominator / (tSignature.m_iNumerator * 4);
|
||||
@@ -2957,7 +2957,7 @@ void Player::HandleTapRowScore( unsigned row )
|
||||
#endif
|
||||
|
||||
// Warp hackery. -aj
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( row ) )
|
||||
if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( row ) )
|
||||
return;
|
||||
|
||||
if( GAMESTATE->m_bDemonstrationOrJukebox )
|
||||
@@ -3061,7 +3061,7 @@ void Player::HandleHoldCheckpoint( int iRow, int iNumHoldsHeldThisRow, int iNumH
|
||||
#endif
|
||||
|
||||
// More warp hackery. -aj
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iRow ) )
|
||||
if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iRow ) )
|
||||
return;
|
||||
|
||||
// don't accumulate combo if AutoPlay is on.
|
||||
|
||||
@@ -443,7 +443,7 @@ void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumH
|
||||
|
||||
if( iNumBreakCombo == 0 )
|
||||
{
|
||||
TimingData td = GAMESTATE->m_pCurSong->m_Timing;
|
||||
TimingData td = GAMESTATE->m_pCurSong->m_SongTiming;
|
||||
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo );
|
||||
m_pPlayerStageStats->m_iCurCombo += iNumHitContinueCombo * multiplier;
|
||||
}
|
||||
@@ -463,7 +463,7 @@ void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsIn
|
||||
if ( tns >= m_MinScoreToContinueCombo )
|
||||
{
|
||||
m_pPlayerStageStats->m_iCurMissCombo = 0;
|
||||
TimingData td = GAMESTATE->m_pCurSong->m_Timing;
|
||||
TimingData td = GAMESTATE->m_pCurSong->m_SongTiming;
|
||||
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo );
|
||||
m_pPlayerStageStats->m_iCurCombo += iNumTapsInRow * multiplier;
|
||||
}
|
||||
|
||||
+76
-76
@@ -913,7 +913,7 @@ void ScreenEdit::Update( float fDeltaTime )
|
||||
{
|
||||
RageTimer tm;
|
||||
const float fSeconds = m_pSoundMusic->GetPositionSeconds( NULL, &tm );
|
||||
GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_Timing, tm );
|
||||
GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_SongTiming, tm );
|
||||
}
|
||||
|
||||
if( m_EditState == STATE_RECORDING )
|
||||
@@ -931,7 +931,7 @@ void ScreenEdit::Update( float fDeltaTime )
|
||||
continue;
|
||||
|
||||
float fStartedHoldingSeconds = m_pSoundMusic->GetPositionSeconds() - fSecsHeld;
|
||||
float fStartBeat = max( fStartPlayingAtBeat, m_pSong->GetBeatFromElapsedTime(fStartedHoldingSeconds) );
|
||||
float fStartBeat = max( fStartPlayingAtBeat, m_pSong->m_SongTiming.GetBeatFromElapsedTime(fStartedHoldingSeconds) );
|
||||
float fEndBeat = max( fStartBeat, GAMESTATE->m_fSongBeat );
|
||||
fEndBeat = min( fEndBeat, NoteRowToBeat(m_iStopPlayingAt) );
|
||||
|
||||
@@ -976,11 +976,11 @@ void ScreenEdit::Update( float fDeltaTime )
|
||||
float fLastBeat = NoteRowToBeat(m_iStopPlayingAt);
|
||||
if( bButtonIsBeingPressed && m_EditState == STATE_RECORDING )
|
||||
{
|
||||
float fSeconds = m_pSong->m_Timing.GetElapsedTimeFromBeat( fLastBeat );
|
||||
fLastBeat = m_pSong->m_Timing.GetBeatFromElapsedTime( fSeconds + 0.5f );
|
||||
float fSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( fLastBeat );
|
||||
fLastBeat = m_pSong->m_SongTiming.GetBeatFromElapsedTime( fSeconds + 0.5f );
|
||||
}
|
||||
|
||||
float fStopAtSeconds = m_pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStopPlayingAt) ) + 1;
|
||||
float fStopAtSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStopPlayingAt) ) + 1;
|
||||
if( GAMESTATE->m_fMusicSeconds > fStopAtSeconds )
|
||||
{
|
||||
// loop
|
||||
@@ -1071,7 +1071,7 @@ void ScreenEdit::UpdateTextInfo()
|
||||
|
||||
RString sText;
|
||||
sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GAMESTATE->m_fSongBeat );
|
||||
sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSong->GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat) );
|
||||
sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSong->m_SongTiming.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat) );
|
||||
switch( EDIT_MODE.GetValue() )
|
||||
{
|
||||
DEFAULT_FAIL( EDIT_MODE.GetValue() );
|
||||
@@ -1129,7 +1129,7 @@ void ScreenEdit::UpdateTextInfo()
|
||||
case EditMode_Home:
|
||||
break;
|
||||
case EditMode_Full:
|
||||
sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), m_pSong->m_Timing.m_fBeat0OffsetInSeconds );
|
||||
sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds );
|
||||
sText += ssprintf( PREVIEW_START_FORMAT.GetValue(), PREVIEW_START.GetValue().c_str(), m_pSong->m_fMusicSampleStartSeconds );
|
||||
sText += ssprintf( PREVIEW_LENGTH_FORMAT.GetValue(), PREVIEW_LENGTH.GetValue().c_str(), m_pSong->m_fMusicSampleLengthSeconds );
|
||||
break;
|
||||
@@ -1243,7 +1243,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
m_iShiftAnchor = -1;
|
||||
return;
|
||||
}
|
||||
int beatsPerMeasure = GAMESTATE->m_pCurSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator;
|
||||
int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator;
|
||||
|
||||
switch( EditB )
|
||||
{
|
||||
@@ -1443,13 +1443,13 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
break;
|
||||
case EDIT_BUTTON_LABEL_NEXT:
|
||||
{
|
||||
ScrollTo( GAMESTATE->m_pCurSong->m_Timing.
|
||||
ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming.
|
||||
GetNextLabelSegmentBeatAtBeat( GAMESTATE->m_fSongBeat ) );
|
||||
}
|
||||
break;
|
||||
case EDIT_BUTTON_LABEL_PREV:
|
||||
{
|
||||
ScrollTo( GAMESTATE->m_pCurSong->m_Timing.
|
||||
ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming.
|
||||
GetPreviousLabelSegmentBeatAtBeat( GAMESTATE->m_fSongBeat ) );
|
||||
}
|
||||
break;
|
||||
@@ -1579,7 +1579,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
case EDIT_BUTTON_BPM_UP:
|
||||
case EDIT_BUTTON_BPM_DOWN:
|
||||
{
|
||||
float fBPM = m_pSong->GetBPMAtBeat( GAMESTATE->m_fSongBeat );
|
||||
float fBPM = m_pSong->m_SongTiming.GetBPMAtBeat( GAMESTATE->m_fSongBeat );
|
||||
float fDelta;
|
||||
switch( EditB )
|
||||
{
|
||||
@@ -1600,7 +1600,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
}
|
||||
|
||||
float fNewBPM = fBPM + fDelta;
|
||||
m_pSong->SetBPMAtBeat( GAMESTATE->m_fSongBeat, fNewBPM );
|
||||
m_pSong->m_SongTiming.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fNewBPM );
|
||||
(fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play();
|
||||
SetDirty( true );
|
||||
}
|
||||
@@ -1627,24 +1627,24 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
fDelta *= 40;
|
||||
}
|
||||
unsigned i;
|
||||
for( i=0; i<m_pSong->m_Timing.m_StopSegments.size(); i++ )
|
||||
for( i=0; i<m_pSong->m_SongTiming.m_StopSegments.size(); i++ )
|
||||
{
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) )
|
||||
if( m_pSong->m_SongTiming.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) )
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == m_pSong->m_Timing.m_StopSegments.size() ) // there is no StopSegment at the current beat
|
||||
if( i == m_pSong->m_SongTiming.m_StopSegments.size() ) // there is no StopSegment at the current beat
|
||||
{
|
||||
// create a new StopSegment
|
||||
if( fDelta > 0 )
|
||||
m_pSong->AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta) );
|
||||
m_pSong->m_SongTiming.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta) );
|
||||
}
|
||||
else // StopSegment being modified is m_Timing.m_StopSegments[i]
|
||||
else // StopSegment being modified is m_SongTiming.m_StopSegments[i]
|
||||
{
|
||||
m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds += fDelta;
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 )
|
||||
m_pSong->m_Timing.m_StopSegments.erase( m_pSong->m_Timing.m_StopSegments.begin()+i,
|
||||
m_pSong->m_Timing.m_StopSegments.begin()+i+1);
|
||||
m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds += fDelta;
|
||||
if( m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds <= 0 )
|
||||
m_pSong->m_SongTiming.m_StopSegments.erase( m_pSong->m_SongTiming.m_StopSegments.begin()+i,
|
||||
m_pSong->m_SongTiming.m_StopSegments.begin()+i+1);
|
||||
}
|
||||
(fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play();
|
||||
SetDirty( true );
|
||||
@@ -1673,24 +1673,24 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
fDelta *= 40;
|
||||
}
|
||||
unsigned i;
|
||||
for( i=0; i<m_pSong->m_Timing.m_StopSegments.size(); i++ )
|
||||
for( i=0; i<m_pSong->m_SongTiming.m_StopSegments.size(); i++ )
|
||||
{
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) )
|
||||
if( m_pSong->m_SongTiming.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) )
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == m_pSong->m_Timing.m_StopSegments.size() ) // there is no delay segment at the current beat
|
||||
if( i == m_pSong->m_SongTiming.m_StopSegments.size() ) // there is no delay segment at the current beat
|
||||
{
|
||||
// create a new delay segment
|
||||
if( fDelta > 0 )
|
||||
m_pSong->AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta, true) );
|
||||
}
|
||||
else // delay segment being modified is m_Timing.m_StopSegments[i]
|
||||
else // delay segment being modified is m_SongTiming.m_StopSegments[i]
|
||||
{
|
||||
m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds += fDelta;
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 )
|
||||
m_pSong->m_Timing.m_StopSegments.erase( m_pSong->m_Timing.m_StopSegments.begin()+i,
|
||||
m_pSong->m_Timing.m_StopSegments.begin()+i+1);
|
||||
m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds += fDelta;
|
||||
if( m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds <= 0 )
|
||||
m_pSong->m_SongTiming.m_StopSegments.erase( m_pSong->m_SongTiming.m_StopSegments.begin()+i,
|
||||
m_pSong->m_SongTiming.m_StopSegments.begin()+i+1);
|
||||
}
|
||||
(fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play();
|
||||
SetDirty( true );
|
||||
@@ -1718,7 +1718,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
else
|
||||
fDelta *= 40;
|
||||
}
|
||||
m_pSong->m_Timing.m_fBeat0OffsetInSeconds += fDelta;
|
||||
m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds += fDelta;
|
||||
(fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play();
|
||||
SetDirty( true );
|
||||
}
|
||||
@@ -1900,7 +1900,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
if( pCourse == NULL )
|
||||
break;
|
||||
CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex];
|
||||
float fStartTime = m_pSong->GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat );
|
||||
float fStartTime = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat );
|
||||
int iAttack = FindAttackAtTime( ce.attacks, fStartTime );
|
||||
|
||||
if( iAttack >= 0 )
|
||||
@@ -1941,7 +1941,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
}
|
||||
else
|
||||
{
|
||||
fStart = m_pSong->GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) );
|
||||
fStart = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) );
|
||||
int iAttack = FindAttackAtTime( ce.attacks, fStart );
|
||||
|
||||
if( iAttack >= 0 )
|
||||
@@ -1950,7 +1950,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
if( m_NoteFieldEdit.m_iEndMarker == -1 )
|
||||
fEnd = m_pSong->m_fMusicLengthSeconds;
|
||||
else
|
||||
fEnd = m_pSong->GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) );
|
||||
fEnd = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) );
|
||||
}
|
||||
g_fLastInsertAttackPositionSeconds = fStart;
|
||||
g_fLastInsertAttackDurationSeconds = fEnd - fStart;
|
||||
@@ -2265,7 +2265,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB )
|
||||
fOffsetDelta *= 40;
|
||||
}
|
||||
|
||||
m_pSong->m_Timing.m_fBeat0OffsetInSeconds += fOffsetDelta;
|
||||
m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds += fOffsetDelta;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2381,8 +2381,8 @@ void ScreenEdit::TransitionEditState( EditState em )
|
||||
AdjustSync::ResetOriginalSyncData();
|
||||
|
||||
/* Give a 1 second lead-in. If we're loading Player, this must be done first. */
|
||||
float fSeconds = m_pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1;
|
||||
GAMESTATE->UpdateSongPosition( fSeconds, m_pSong->m_Timing );
|
||||
float fSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1;
|
||||
GAMESTATE->UpdateSongPosition( fSeconds, m_pSong->m_SongTiming );
|
||||
|
||||
GAMESTATE->m_bGameplayLeadIn.Set( false );
|
||||
|
||||
@@ -2463,7 +2463,7 @@ void ScreenEdit::TransitionEditState( EditState em )
|
||||
{
|
||||
case STATE_PLAYING:
|
||||
case STATE_RECORDING:
|
||||
const float fStartSeconds = m_pSong->GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat);
|
||||
const float fStartSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat);
|
||||
LOG->Trace( "Starting playback at %f", fStartSeconds );
|
||||
|
||||
RageSoundParams p;
|
||||
@@ -2627,21 +2627,21 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
float fBPM = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
if( fBPM > 0 )
|
||||
m_pSong->SetBPMAtBeat( GAMESTATE->m_fSongBeat, fBPM );
|
||||
m_pSong->m_SongTiming.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fBPM );
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromStopChange )
|
||||
{
|
||||
float fStop = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
if( fStop >= 0 )
|
||||
m_pSong->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, fStop );
|
||||
m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, fStop );
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromDelayChange )
|
||||
{
|
||||
float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
if( fDelay >= 0 )
|
||||
m_pSong->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, fDelay, true );
|
||||
m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, fDelay, true );
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromTimeSignatureNumeratorChange )
|
||||
@@ -2649,7 +2649,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
int iNum = atoi( ScreenTextEntry::s_sLastAnswer );
|
||||
if( iNum > 0 )
|
||||
{
|
||||
m_pSong->m_Timing.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_fSongBeat, iNum );
|
||||
m_pSong->m_SongTiming.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_fSongBeat, iNum );
|
||||
}
|
||||
SetDirty( true );
|
||||
}
|
||||
@@ -2658,7 +2658,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
int iDen = atoi( ScreenTextEntry::s_sLastAnswer );
|
||||
if( iDen > 0)
|
||||
{
|
||||
m_pSong->m_Timing.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_fSongBeat, iDen );
|
||||
m_pSong->m_SongTiming.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_fSongBeat, iDen );
|
||||
}
|
||||
SetDirty( true );
|
||||
}
|
||||
@@ -2667,7 +2667,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
int iTick = atoi( ScreenTextEntry::s_sLastAnswer );
|
||||
if ( iTick >= 0 && iTick <= ROWS_PER_BEAT )
|
||||
{
|
||||
m_pSong->m_Timing.SetTickcountAtBeat( GAMESTATE->m_fSongBeat, iTick );
|
||||
m_pSong->m_SongTiming.SetTickcountAtBeat( GAMESTATE->m_fSongBeat, iTick );
|
||||
}
|
||||
SetDirty( true );
|
||||
}
|
||||
@@ -2676,25 +2676,25 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
int iCombo = atoi( ScreenTextEntry::s_sLastAnswer );
|
||||
if ( iCombo >= 0 )
|
||||
{
|
||||
m_pSong->m_Timing.SetComboAtBeat( GAMESTATE->m_fSongBeat, iCombo );
|
||||
m_pSong->m_SongTiming.SetComboAtBeat( GAMESTATE->m_fSongBeat, iCombo );
|
||||
}
|
||||
SetDirty( true );
|
||||
}
|
||||
else if ( SM == SM_BackFromLabelChange )
|
||||
{
|
||||
RString sLabel = ScreenTextEntry::s_sLastAnswer;
|
||||
if ( !m_pSong->m_Timing.DoesLabelExist(sLabel) )
|
||||
if ( !m_pSong->m_SongTiming.DoesLabelExist(sLabel) )
|
||||
{
|
||||
sLabel.Replace("=", "_");
|
||||
sLabel.Replace(",", "_");
|
||||
m_pSong->m_Timing.SetLabelAtBeat( GAMESTATE->m_fSongBeat, sLabel );
|
||||
m_pSong->m_SongTiming.SetLabelAtBeat( GAMESTATE->m_fSongBeat, sLabel );
|
||||
SetDirty( true );
|
||||
}
|
||||
}
|
||||
else if ( SM == SM_BackFromWarpChange )
|
||||
{
|
||||
float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
m_pSong->m_Timing.SetWarpAtBeat( GAMESTATE->m_fSongBeat, fWarp );
|
||||
m_pSong->m_SongTiming.SetWarpAtBeat( GAMESTATE->m_fSongBeat, fWarp );
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromBGChange )
|
||||
@@ -2767,7 +2767,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex];
|
||||
int iAttack;
|
||||
|
||||
g_fLastInsertAttackPositionSeconds = m_pSong->GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat );
|
||||
g_fLastInsertAttackPositionSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat );
|
||||
g_fLastInsertAttackDurationSeconds = StringToFloat( g_InsertCourseAttack.rows[0].choices[iDurationChoice] );
|
||||
iAttack = FindAttackAtTime( ce.attacks, g_fLastInsertAttackPositionSeconds );
|
||||
|
||||
@@ -3024,7 +3024,7 @@ static void ChangeArtistTranslit( const RString &sNew )
|
||||
|
||||
static void ChangeBeat0Offset( const RString &sNew )
|
||||
{
|
||||
GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew );
|
||||
GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds = StringToFloat( sNew );
|
||||
}
|
||||
|
||||
static void ChangeLastBeatHint( const RString &sNew )
|
||||
@@ -3135,7 +3135,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector<int> &iAns
|
||||
}
|
||||
g_StepsInformation.rows[difficulty].iDefaultChoice = pSteps->GetDifficulty();
|
||||
g_StepsInformation.rows[difficulty].bEnabled = (EDIT_MODE.GetValue() >= EditMode_Full);
|
||||
g_StepsInformation.rows[meter].SetOneUnthemedChoice( ssprintf("%d", pSteps->GetMeter()-1) );
|
||||
g_StepsInformation.rows[meter].SetOneUnthemedChoice( ssprintf("%d", pSteps->GetMeter()) );
|
||||
g_StepsInformation.rows[meter].bEnabled = (EDIT_MODE.GetValue() >= EditMode_Home);
|
||||
g_StepsInformation.rows[predict_meter].SetOneUnthemedChoice( ssprintf("%.2f",pSteps->PredictMeter()) );
|
||||
g_StepsInformation.rows[description].bEnabled = (EDIT_MODE.GetValue() >= EditMode_Full);
|
||||
@@ -3242,7 +3242,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector<int> &iAns
|
||||
g_SongInformation.rows[main_title_transliteration].SetOneUnthemedChoice( pSong->m_sMainTitleTranslit );
|
||||
g_SongInformation.rows[sub_title_transliteration].SetOneUnthemedChoice( pSong->m_sSubTitleTranslit );
|
||||
g_SongInformation.rows[artist_transliteration].SetOneUnthemedChoice( pSong->m_sArtistTranslit );
|
||||
g_SongInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_Timing.m_fBeat0OffsetInSeconds) );
|
||||
g_SongInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_SongTiming.m_fBeat0OffsetInSeconds) );
|
||||
g_SongInformation.rows[last_beat_hint].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fSpecifiedLastBeat) );
|
||||
g_SongInformation.rows[preview_start].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fMusicSampleStartSeconds) );
|
||||
g_SongInformation.rows[preview_length].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fMusicSampleLengthSeconds) );
|
||||
@@ -3256,9 +3256,9 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector<int> &iAns
|
||||
case edit_timing_data:
|
||||
{
|
||||
const Song* pSong = GAMESTATE->m_pCurSong;
|
||||
TimingData pTime = pSong->m_Timing;
|
||||
TimingData pTime = pSong->m_SongTiming;
|
||||
const float fBeat = GAMESTATE->m_fSongBeat;
|
||||
g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pSong->GetBPMAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ;
|
||||
g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[time_signature_numerator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ) ) );
|
||||
@@ -3501,7 +3501,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex );
|
||||
|
||||
// scale timing data
|
||||
m_pSong->m_Timing.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true );
|
||||
m_pSong->m_SongTiming.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true );
|
||||
|
||||
// scale all other steps.
|
||||
const vector<Steps*> sIter = m_pSong->GetAllSteps();
|
||||
@@ -3546,16 +3546,16 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) );
|
||||
break;
|
||||
case shift_pauses_forward:
|
||||
m_pSong->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) );
|
||||
m_pSong->m_SongTiming.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) );
|
||||
break;
|
||||
case shift_pauses_backward:
|
||||
m_pSong->m_Timing.DeleteRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) );
|
||||
m_pSong->m_SongTiming.DeleteRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) );
|
||||
break;
|
||||
case convert_to_pause:
|
||||
{
|
||||
ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 );
|
||||
float fMarkerStart = m_pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) );
|
||||
float fMarkerEnd = m_pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) );
|
||||
float fMarkerStart = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) );
|
||||
float fMarkerEnd = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) );
|
||||
|
||||
// The length of the stop segment we're going to create. This includes time spent in any
|
||||
// stops in the selection, which will be deleted and subsumed into the new stop.
|
||||
@@ -3567,9 +3567,9 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
m_NoteFieldEdit.m_iBeginMarker + 1,
|
||||
m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker
|
||||
);
|
||||
m_pSong->m_Timing.DeleteRows( m_NoteFieldEdit.m_iBeginMarker,
|
||||
m_pSong->m_SongTiming.DeleteRows( m_NoteFieldEdit.m_iBeginMarker,
|
||||
m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker );
|
||||
m_pSong->m_Timing.SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength );
|
||||
m_pSong->m_SongTiming.SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength );
|
||||
m_NoteFieldEdit.m_iBeginMarker = -1;
|
||||
m_NoteFieldEdit.m_iEndMarker = -1;
|
||||
break;
|
||||
@@ -3577,14 +3577,14 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
case convert_pause_to_beat:
|
||||
{
|
||||
// TODO: Convert both Delays and Stops at once.
|
||||
float fStopSeconds = m_pSong->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) );
|
||||
m_pSong->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, 0 );
|
||||
float fStopSeconds = m_pSong->m_SongTiming.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) );
|
||||
m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, 0 );
|
||||
|
||||
float fStopBeats = fStopSeconds * m_pSong->GetBPMAtBeat(GAMESTATE->m_fSongBeat) / 60;
|
||||
float fStopBeats = fStopSeconds * m_pSong->m_SongTiming.GetBPMAtBeat(GAMESTATE->m_fSongBeat) / 60;
|
||||
|
||||
// don't move the step from where it is, just move everything later
|
||||
NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) );
|
||||
m_pSong->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) );
|
||||
m_pSong->m_SongTiming.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) );
|
||||
}
|
||||
break;
|
||||
case undo:
|
||||
@@ -3701,7 +3701,7 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec
|
||||
break;
|
||||
case beat_0_offset:
|
||||
ScreenTextEntry::TextEntry( SM_None, ENTER_BEAT_0_OFFSET,
|
||||
ssprintf("%.5f", pSong->m_Timing.m_fBeat0OffsetInSeconds), 20,
|
||||
ssprintf("%.5f", pSong->m_SongTiming.m_fBeat0OffsetInSeconds), 20,
|
||||
ScreenTextEntry::FloatValidate, ChangeBeat0Offset, NULL );
|
||||
break;
|
||||
case last_beat_hint:
|
||||
@@ -3750,7 +3750,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromBPMChange,
|
||||
ENTER_BPM_VALUE,
|
||||
ssprintf( "%.4f", m_pSong->GetBPMAtBeat(GAMESTATE->m_fSongBeat) ),
|
||||
ssprintf( "%.4f", m_pSong->m_SongTiming.GetBPMAtBeat(GAMESTATE->m_fSongBeat) ),
|
||||
10
|
||||
);
|
||||
break;
|
||||
@@ -3758,7 +3758,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromStopChange,
|
||||
ENTER_STOP_VALUE,
|
||||
ssprintf( "%.4f", m_pSong->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ),
|
||||
ssprintf( "%.4f", m_pSong->m_SongTiming.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ),
|
||||
10
|
||||
);
|
||||
break;
|
||||
@@ -3766,7 +3766,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromDelayChange,
|
||||
ENTER_DELAY_VALUE,
|
||||
ssprintf( "%.4f", m_pSong->m_Timing.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ),
|
||||
ssprintf( "%.4f", m_pSong->m_SongTiming.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ),
|
||||
10
|
||||
);
|
||||
break;
|
||||
@@ -3774,7 +3774,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromTimeSignatureNumeratorChange,
|
||||
ENTER_TIME_SIGNATURE_NUMERATOR_VALUE,
|
||||
ssprintf( "%d", m_pSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator ),
|
||||
ssprintf( "%d", m_pSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator ),
|
||||
3
|
||||
);
|
||||
break;
|
||||
@@ -3782,7 +3782,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromTimeSignatureDenominatorChange,
|
||||
ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE,
|
||||
ssprintf( "%d", m_pSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iDenominator ),
|
||||
ssprintf( "%d", m_pSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iDenominator ),
|
||||
3
|
||||
);
|
||||
break;
|
||||
@@ -3790,7 +3790,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromTickcountChange,
|
||||
ENTER_TICKCOUNT_VALUE,
|
||||
ssprintf( "%d", m_pSong->m_Timing.GetTickcountAtBeat( GAMESTATE->m_fSongBeat ) ),
|
||||
ssprintf( "%d", m_pSong->m_SongTiming.GetTickcountAtBeat( GAMESTATE->m_fSongBeat ) ),
|
||||
2
|
||||
);
|
||||
break;
|
||||
@@ -3798,7 +3798,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromComboChange,
|
||||
ENTER_COMBO_VALUE,
|
||||
ssprintf( "%d", m_pSong->m_Timing.GetComboAtBeat( GAMESTATE->m_fSongBeat ) ),
|
||||
ssprintf( "%d", m_pSong->m_SongTiming.GetComboAtBeat( GAMESTATE->m_fSongBeat ) ),
|
||||
4
|
||||
);
|
||||
break;
|
||||
@@ -3806,7 +3806,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromLabelChange,
|
||||
ENTER_LABEL_VALUE,
|
||||
ssprintf( "%s", m_pSong->m_Timing.GetLabelAtBeat( GAMESTATE->m_fSongBeat ).c_str() ),
|
||||
ssprintf( "%s", m_pSong->m_SongTiming.GetLabelAtBeat( GAMESTATE->m_fSongBeat ).c_str() ),
|
||||
64
|
||||
);
|
||||
break;
|
||||
@@ -3814,7 +3814,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromWarpChange,
|
||||
ENTER_WARP_VALUE,
|
||||
ssprintf( "%.4f", m_pSong->m_Timing.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ),
|
||||
ssprintf( "%.4f", m_pSong->m_SongTiming.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ),
|
||||
10
|
||||
);
|
||||
break;
|
||||
@@ -4021,7 +4021,7 @@ void ScreenEdit::CheckNumberOfNotesAndUndo()
|
||||
if( EDIT_MODE.GetValue() != EditMode_Home )
|
||||
return;
|
||||
|
||||
TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat );
|
||||
TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat );
|
||||
int rowsPerMeasure = curTime.m_iDenominator * curTime.m_iNumerator;
|
||||
|
||||
for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure )
|
||||
@@ -4073,7 +4073,7 @@ float ScreenEdit::GetMaximumBeatForNewNote() const
|
||||
/* Round up to the next measure end. Some songs end on weird beats
|
||||
* mid-measure, and it's odd to have movement capped to these weird
|
||||
* beats. */
|
||||
int beatsPerMeasure = GAMESTATE->m_pCurSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator;
|
||||
int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator;
|
||||
fEndBeat += beatsPerMeasure;
|
||||
fEndBeat = ftruncf( fEndBeat, (float)beatsPerMeasure );
|
||||
|
||||
|
||||
+31
-22
@@ -128,8 +128,7 @@ enum EditButton
|
||||
EDIT_BUTTON_SAMPLE_LENGTH_UP,
|
||||
EDIT_BUTTON_SAMPLE_LENGTH_DOWN,
|
||||
|
||||
// This modifies offset, BPM, and stop segment changes.
|
||||
EDIT_BUTTON_ADJUST_FINE,
|
||||
EDIT_BUTTON_ADJUST_FINE, /**< This button modifies offset, BPM, and stop segment changes. */
|
||||
|
||||
EDIT_BUTTON_SAVE, /**< Save the present changes into the chart. */
|
||||
|
||||
@@ -166,7 +165,9 @@ struct MapEditToDI
|
||||
}
|
||||
};
|
||||
|
||||
// Like MapEditToDI, but maps GameButton instead of DeviceInput.
|
||||
/**
|
||||
* @brief This is similar to MapEditToDI,
|
||||
* but maps GameButton instead of DeviceInput. */
|
||||
struct MapEditButtonToMenuButton
|
||||
{
|
||||
GameButton button[NUM_EditButton][NUM_EDIT_TO_MENU_SLOTS];
|
||||
@@ -214,11 +215,14 @@ protected:
|
||||
|
||||
// Call this before modifying m_NoteDataEdit.
|
||||
void SaveUndo();
|
||||
// Revert m_NoteDataEdit using m_Undo.
|
||||
/** @brief Revert the last change made to m_NoteDataEdit. */
|
||||
void Undo();
|
||||
/** @brief Remove the previously stored NoteData to prevent undoing. */
|
||||
void ClearUndo();
|
||||
// Call this after modifying m_NoteDataEdit. It will Undo() if
|
||||
// MAX_NOTES_PER_MEASURE was exceeded.
|
||||
/**
|
||||
* @brief This is to be called after modifying m_NoteDataEdit.
|
||||
*
|
||||
* It will Undo itself if MAX_NOTES_PER_MEASURE was exceeded. */
|
||||
void CheckNumberOfNotesAndUndo();
|
||||
|
||||
void OnSnapModeChange();
|
||||
@@ -252,7 +256,10 @@ protected:
|
||||
|
||||
// keep track of where we are and what we're doing
|
||||
float m_fTrailingBeat; // this approaches GAMESTATE->m_fSongBeat, which is the actual beat
|
||||
// The location we were at when shift was pressed, or -1 when shift isn't pressed:
|
||||
/**
|
||||
* @brief The location we were at when shift was pressed.
|
||||
*
|
||||
* If shift wasn't pressed, this will be -1. */
|
||||
int m_iShiftAnchor;
|
||||
|
||||
/** @brief The NoteData that has been cut or copied. */
|
||||
@@ -311,22 +318,23 @@ protected:
|
||||
ThemeMetric<EditMode> EDIT_MODE;
|
||||
|
||||
public:
|
||||
/** @brief What are the choices that one can make on the main menu? */
|
||||
enum MainMenuChoice
|
||||
{
|
||||
play_selection,
|
||||
set_selection_start,
|
||||
set_selection_end,
|
||||
edit_steps_information,
|
||||
play_whole_song,
|
||||
play_whole_song, /**< Play the entire chart from the beginning. */
|
||||
play_selection_start_to_end,
|
||||
play_current_beat_to_end,
|
||||
save,
|
||||
save, /**< Save the current chart to disk. */
|
||||
revert_to_last_save,
|
||||
revert_from_disk,
|
||||
options,
|
||||
edit_song_info,
|
||||
edit_timing_data,
|
||||
play_preview_music,
|
||||
options, /**< Modify the PlayerOptions and SongOptions. */
|
||||
edit_song_info, /**< Edit some general information about the song. */
|
||||
edit_timing_data, /**< Edit the chart's timing data. */
|
||||
play_preview_music, /**< Play the song's preview music. */
|
||||
exit,
|
||||
save_on_exit,
|
||||
NUM_MAIN_MENU_CHOICES,
|
||||
@@ -361,13 +369,14 @@ public:
|
||||
};
|
||||
void HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAnswers, bool bAllowUndo = true );
|
||||
void HandleAreaMenuChoice( AreaMenuChoice c, bool bAllowUndo = true ) { const vector<int> v; HandleAreaMenuChoice( c, v, bAllowUndo ); }
|
||||
/** @brief How should the selected notes be transformed? */
|
||||
enum TurnType
|
||||
{
|
||||
left,
|
||||
right,
|
||||
mirror,
|
||||
shuffle,
|
||||
super_shuffle,
|
||||
left, /**< Turn the notes as if you were facing to the left. */
|
||||
right, /**< Turn the notes as if you were facing to the right. */
|
||||
mirror, /**< Turn the notes as if you were facing away from the machine. */
|
||||
shuffle, /**< Replace one column with another column. */
|
||||
super_shuffle, /**< Replace each note individually. */
|
||||
NUM_TURN_TYPES
|
||||
};
|
||||
enum TransformType
|
||||
@@ -421,10 +430,10 @@ public:
|
||||
{
|
||||
difficulty,
|
||||
meter,
|
||||
description,
|
||||
chartstyle,
|
||||
step_credit,
|
||||
predict_meter,
|
||||
description, /**< What is the description of this chart? */
|
||||
chartstyle, /**< How is this chart meant to be played? */
|
||||
step_credit, /**< Who wrote this individual chart? */
|
||||
predict_meter, /**< What does the game think this chart's rating should be? */
|
||||
tap_notes,
|
||||
jumps,
|
||||
hands,
|
||||
|
||||
@@ -1423,7 +1423,7 @@ void ScreenGameplay::UpdateSongPosition( float fDeltaTime )
|
||||
RageTimer tm;
|
||||
const float fSeconds = m_pSoundMusic->GetPositionSeconds( NULL, &tm );
|
||||
const float fAdjust = SOUND->GetFrameTimingAdjustment( fDeltaTime );
|
||||
GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, GAMESTATE->m_pCurSong->m_Timing, tm+fAdjust );
|
||||
GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, GAMESTATE->m_pCurSong->m_SongTiming, tm+fAdjust );
|
||||
}
|
||||
|
||||
void ScreenGameplay::BeginScreen()
|
||||
@@ -1480,7 +1480,7 @@ bool ScreenGameplay::AllAreFailing()
|
||||
|
||||
void ScreenGameplay::GetMusicEndTiming( float &fSecondsToStartFadingOutMusic, float &fSecondsToStartTransitioningOut )
|
||||
{
|
||||
float fLastStepSeconds = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat );
|
||||
float fLastStepSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat );
|
||||
fLastStepSeconds += Player::GetMaxStepDistanceSeconds();
|
||||
|
||||
float fTransitionLength;
|
||||
@@ -1995,7 +1995,7 @@ void ScreenGameplay::SendCrossedMessages()
|
||||
static int iRowLastCrossed = 0;
|
||||
|
||||
float fPositionSeconds = GAMESTATE->m_fMusicSeconds;
|
||||
float fSongBeat = GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds );
|
||||
float fSongBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds );
|
||||
|
||||
int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
|
||||
iRowNow = max( 0, iRowNow );
|
||||
@@ -2033,7 +2033,7 @@ void ScreenGameplay::SendCrossedMessages()
|
||||
float fNoteWillCrossInSeconds = MESSAGE_SPACING_SECONDS * i;
|
||||
|
||||
float fPositionSeconds = GAMESTATE->m_fMusicSeconds + fNoteWillCrossInSeconds;
|
||||
float fSongBeat = GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds );
|
||||
float fSongBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds );
|
||||
|
||||
int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
|
||||
iRowNow = max( 0, iRowNow );
|
||||
|
||||
@@ -244,7 +244,7 @@ void ScreenHowToPlay::Update( float fDelta )
|
||||
{
|
||||
if( GAMESTATE->m_pCurSong != NULL )
|
||||
{
|
||||
GAMESTATE->UpdateSongPosition( m_fFakeSecondsIntoSong, GAMESTATE->m_pCurSong->m_Timing );
|
||||
GAMESTATE->UpdateSongPosition( m_fFakeSecondsIntoSong, GAMESTATE->m_pCurSong->m_SongTiming );
|
||||
m_fFakeSecondsIntoSong += fDelta;
|
||||
|
||||
static int iLastNoteRowCounted = 0;
|
||||
|
||||
@@ -1763,7 +1763,7 @@ void ScreenSelectMusic::AfterMusicChange()
|
||||
case SampleMusicPreviewMode_LastSong: // fall through
|
||||
// play the sample music
|
||||
m_sSampleMusicToPlay = pSong->GetMusicPath();
|
||||
m_pSampleMusicTimingData = &pSong->m_Timing;
|
||||
m_pSampleMusicTimingData = &pSong->m_SongTiming;
|
||||
m_fSampleStartSeconds = pSong->m_fMusicSampleStartSeconds;
|
||||
m_fSampleLengthSeconds = pSong->m_fMusicSampleLengthSeconds;
|
||||
break;
|
||||
|
||||
@@ -221,7 +221,7 @@ bool ScreenSyncOverlay::OverlayInput( const InputEventPlus &input )
|
||||
}
|
||||
if( GAMESTATE->m_pCurSong != NULL )
|
||||
{
|
||||
BPMSegment& seg = GAMESTATE->m_pCurSong->GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat );
|
||||
BPMSegment& seg = GAMESTATE->m_pCurSong->m_SongTiming.GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat );
|
||||
seg.m_fBPS += fDelta;
|
||||
}
|
||||
}
|
||||
@@ -253,7 +253,7 @@ bool ScreenSyncOverlay::OverlayInput( const InputEventPlus &input )
|
||||
|
||||
case ChangeSongOffset:
|
||||
if( GAMESTATE->m_pCurSong != NULL )
|
||||
GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += fDelta;
|
||||
GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fDelta;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+21
-19
@@ -167,7 +167,7 @@ void Song::GetDisplayBpms( DisplayBpms &AddTo ) const
|
||||
else
|
||||
{
|
||||
float fMinBPM, fMaxBPM;
|
||||
m_Timing.GetActualBPM( fMinBPM, fMaxBPM );
|
||||
m_SongTiming.GetActualBPM( fMinBPM, fMaxBPM );
|
||||
AddTo.Add( fMinBPM );
|
||||
AddTo.Add( fMaxBPM );
|
||||
}
|
||||
@@ -488,29 +488,30 @@ void Song::TidyUpData()
|
||||
m_sArtist = "Unknown artist";
|
||||
TranslateTitles();
|
||||
|
||||
if( m_Timing.m_BPMSegments.empty() )
|
||||
if( m_SongTiming.m_BPMSegments.empty() )
|
||||
{
|
||||
LOG->UserLog( "Song file", m_sSongDir + m_sSongFileName, "has no BPM segments, default provided." );
|
||||
|
||||
m_Timing.AddBPMSegment( BPMSegment(0, 60) );
|
||||
m_SongTiming.AddBPMSegment( BPMSegment(0, 60) );
|
||||
}
|
||||
|
||||
// Make sure the first BPM segment starts at beat 0.
|
||||
if( m_Timing.m_BPMSegments[0].m_iStartRow != 0 )
|
||||
m_Timing.m_BPMSegments[0].m_iStartRow = 0;
|
||||
if( m_SongTiming.m_BPMSegments[0].m_iStartRow != 0 )
|
||||
m_SongTiming.m_BPMSegments[0].m_iStartRow = 0;
|
||||
|
||||
|
||||
if( m_fMusicSampleStartSeconds == -1 ||
|
||||
m_fMusicSampleStartSeconds == 0 ||
|
||||
m_fMusicSampleStartSeconds+m_fMusicSampleLengthSeconds > this->m_fMusicLengthSeconds )
|
||||
{
|
||||
m_fMusicSampleStartSeconds = this->GetElapsedTimeFromBeat( 100 );
|
||||
const TimingData &timing = this->m_SongTiming;
|
||||
m_fMusicSampleStartSeconds = timing.GetElapsedTimeFromBeat( 100 );
|
||||
|
||||
if( m_fMusicSampleStartSeconds+m_fMusicSampleLengthSeconds > this->m_fMusicLengthSeconds )
|
||||
{
|
||||
int iBeat = lrintf( m_fLastBeat/2 );
|
||||
iBeat -= iBeat%4;
|
||||
m_fMusicSampleStartSeconds = this->GetElapsedTimeFromBeat( (float)iBeat );
|
||||
m_fMusicSampleStartSeconds = timing.GetElapsedTimeFromBeat( (float)iBeat );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,10 +792,10 @@ void Song::TidyUpData()
|
||||
}
|
||||
|
||||
// If no time signature specified, assume 4/4 time for the whole song.
|
||||
if( m_Timing.m_vTimeSignatureSegments.empty() )
|
||||
if( m_SongTiming.m_vTimeSignatureSegments.empty() )
|
||||
{
|
||||
TimeSignatureSegment seg(0, 4, 4);
|
||||
m_Timing.m_vTimeSignatureSegments.push_back( seg );
|
||||
m_SongTiming.m_vTimeSignatureSegments.push_back( seg );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -802,24 +803,24 @@ void Song::TidyUpData()
|
||||
* per beat for the entire song. The default of 2 is chosen more
|
||||
* for compatibility with the Pump Pro series than anything else.
|
||||
*/
|
||||
if( m_Timing.m_TickcountSegments.empty() )
|
||||
if( m_SongTiming.m_TickcountSegments.empty() )
|
||||
{
|
||||
TickcountSegment seg(0, 2);
|
||||
m_Timing.m_TickcountSegments.push_back( seg );
|
||||
m_SongTiming.m_TickcountSegments.push_back( seg );
|
||||
}
|
||||
|
||||
// Have a default combo segment of one just in case.
|
||||
if( m_Timing.m_ComboSegments.empty() )
|
||||
if( m_SongTiming.m_ComboSegments.empty() )
|
||||
{
|
||||
ComboSegment seg(0, 1);
|
||||
m_Timing.m_ComboSegments.push_back( seg );
|
||||
m_SongTiming.m_ComboSegments.push_back( seg );
|
||||
}
|
||||
|
||||
// Have a default label segment just in case.
|
||||
if( m_Timing.m_LabelSegments.empty() )
|
||||
if( m_SongTiming.m_LabelSegments.empty() )
|
||||
{
|
||||
LabelSegment seg(0, "Song Start");
|
||||
m_Timing.m_LabelSegments.push_back( seg );
|
||||
m_SongTiming.m_LabelSegments.push_back( seg );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1465,7 +1466,7 @@ bool Song::IsEditAlreadyLoaded( Steps* pSteps ) const
|
||||
|
||||
bool Song::HasSignificantBpmChangesOrStops() const
|
||||
{
|
||||
if( m_Timing.HasStops() )
|
||||
if( m_SongTiming.HasStops() )
|
||||
return true;
|
||||
|
||||
// Don't consider BPM changes that only are only for maintaining sync as
|
||||
@@ -1475,7 +1476,7 @@ bool Song::HasSignificantBpmChangesOrStops() const
|
||||
if( m_fSpecifiedBPMMin != m_fSpecifiedBPMMax )
|
||||
return true;
|
||||
}
|
||||
else if( m_Timing.HasBpmChanges() )
|
||||
else if( m_SongTiming.HasBpmChanges() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1485,7 +1486,8 @@ bool Song::HasSignificantBpmChangesOrStops() const
|
||||
|
||||
float Song::GetStepsSeconds() const
|
||||
{
|
||||
return GetElapsedTimeFromBeat( m_fLastBeat ) - GetElapsedTimeFromBeat( m_fFirstBeat );
|
||||
const TimingData &timing = this->m_SongTiming;
|
||||
return timing.GetElapsedTimeFromBeat( m_fLastBeat ) - timing.GetElapsedTimeFromBeat( m_fFirstBeat );
|
||||
}
|
||||
|
||||
bool Song::IsLong() const
|
||||
@@ -1568,7 +1570,7 @@ public:
|
||||
}
|
||||
static int GetTimingData( T* p, lua_State *L )
|
||||
{
|
||||
p->m_Timing.PushSelf(L);
|
||||
p->m_SongTiming.PushSelf(L);
|
||||
return 1;
|
||||
}
|
||||
// has functions
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ struct lua_State;
|
||||
struct BackgroundChange;
|
||||
|
||||
/** @brief The version of the .ssc file format. */
|
||||
const static float STEPFILE_VERSION_NUMBER = 0.59f;
|
||||
const static float STEPFILE_VERSION_NUMBER = 0.7f;
|
||||
|
||||
/** @brief How many edits for this song can each profile have? */
|
||||
const int MAX_EDITS_PER_SONG_PER_PROFILE = 5;
|
||||
|
||||
+9
-3
@@ -8,10 +8,16 @@
|
||||
#include <float.h>
|
||||
|
||||
|
||||
TimingData::TimingData()
|
||||
TimingData::TimingData() :
|
||||
m_fBeat0OffsetInSeconds(0),
|
||||
m_bHasNegativeBpms(false)
|
||||
{
|
||||
m_fBeat0OffsetInSeconds = 0;
|
||||
m_bHasNegativeBpms = false;
|
||||
}
|
||||
|
||||
TimingData::TimingData(float fOffset) :
|
||||
m_fBeat0OffsetInSeconds(fOffset),
|
||||
m_bHasNegativeBpms(false)
|
||||
{
|
||||
}
|
||||
|
||||
void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const
|
||||
|
||||
@@ -658,6 +658,10 @@ public:
|
||||
* @brief Sets up initial timing data.
|
||||
*/
|
||||
TimingData();
|
||||
/**
|
||||
* @brief Sets up initial timing data with a defined offset.
|
||||
* @param fOffset the offset from the 0th beat. */
|
||||
TimingData(float fOffset);
|
||||
/**
|
||||
* @brief Gets the actual BPM of the song.
|
||||
* @param fMinBPMOut the minimium specified BPM.
|
||||
|
||||
Reference in New Issue
Block a user