[default -> splittiming] forgot to push my merge. ouch

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