diff --git a/stepmania/src/Background.cpp b/stepmania/src/Background.cpp index b5abc32e78..584ef7a473 100644 --- a/stepmania/src/Background.cpp +++ b/stepmania/src/Background.cpp @@ -343,9 +343,9 @@ void Background::LoadFromSong( Song* pSong ) } // change BG every BPM change that is at the beginning of a measure - for( unsigned i=0; im_BPMSegments.size(); i++ ) + for( unsigned i=0; im_Timing.m_BPMSegments.size(); i++ ) { - const BPMSegment& bpmseg = pSong->m_BPMSegments[i]; + const BPMSegment& bpmseg = pSong->m_Timing.m_BPMSegments[i]; if( fmodf(bpmseg.m_fStartBeat, (float)BEATS_PER_MEASURE) != 0 ) continue; // skip diff --git a/stepmania/src/Makefile.am b/stepmania/src/Makefile.am index e398302b79..cd20b9ff8a 100644 --- a/stepmania/src/Makefile.am +++ b/stepmania/src/Makefile.am @@ -65,7 +65,7 @@ NotesLoaderSM.cpp NotesLoaderSM.h NotesWriterDWI.cpp NotesWriterDWI.h NotesWrite PlayerAI.cpp PlayerAI.h PlayerNumber.cpp PlayerNumber.h PlayerOptions.cpp PlayerOptions.h RandomSample.cpp RandomSample.h \ ScoreKeeper.h ScoreKeeperMAX2.cpp ScoreKeeperMAX2.h ScoreKeeperRave.cpp ScoreKeeperRave.h \ Song.cpp song.h SongCacheIndex.cpp SongCacheIndex.h SongOptions.cpp SongOptions.h StageStats.cpp StageStats.h Steps.cpp Steps.h \ -Style.h StyleDef.cpp StyleDef.h StyleInput.h TitleSubstitution.cpp TitleSubstitution.h +Style.h StyleDef.cpp StyleDef.h StyleInput.h TimingData.cpp TimingData.h TitleSubstitution.cpp TitleSubstitution.h FileTypes = IniFile.cpp IniFile.h MsdFile.cpp MsdFile.h diff --git a/stepmania/src/NoteField.cpp b/stepmania/src/NoteField.cpp index cedb70f047..ff36b13183 100644 --- a/stepmania/src/NoteField.cpp +++ b/stepmania/src/NoteField.cpp @@ -441,7 +441,7 @@ void NoteField::DrawPrimitives() // // BPM text // - vector &aBPMSegments = GAMESTATE->m_pCurSong->m_BPMSegments; + vector &aBPMSegments = GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments; for( i=0; i= fFirstBeatToDraw && @@ -451,7 +451,7 @@ void NoteField::DrawPrimitives() // // Freeze text // - vector &aStopSegments = GAMESTATE->m_pCurSong->m_StopSegments; + vector &aStopSegments = GAMESTATE->m_pCurSong->m_Timing.m_StopSegments; for( i=0; i= fFirstBeatToDraw && diff --git a/stepmania/src/NotesLoaderBMS.cpp b/stepmania/src/NotesLoaderBMS.cpp index f047f267c3..649055680b 100644 --- a/stepmania/src/NotesLoaderBMS.cpp +++ b/stepmania/src/NotesLoaderBMS.cpp @@ -541,8 +541,8 @@ bool BMSLoader::LoadFromDir( CString sDir, Song &out ) if( fBeatOffset > 10 ) // some BPMs's play the music again at the end. Why? Who knows... break; float fBPS; - fBPS = out.m_BPMSegments[0].m_fBPM/60.0f; - out.m_fBeat0OffsetInSeconds = fBeatOffset / fBPS; + fBPS = out.m_Timing.m_BPMSegments[0].m_fBPM/60.0f; + out.m_Timing.m_fBeat0OffsetInSeconds = fBeatOffset / fBPS; break; } case 3: { // bpm change @@ -659,18 +659,18 @@ bool BMSLoader::LoadFromDir( CString sDir, Song &out ) { // find the BPM at the time of this freeze float fBPM = -1; - for( unsigned i=0; i fFreezeStartBeat ) + if( out.m_Timing.m_BPMSegments[i].m_fStartBeat <= fFreezeStartBeat && + out.m_Timing.m_BPMSegments[i+1].m_fStartBeat > fFreezeStartBeat ) { - fBPM = out.m_BPMSegments[i].m_fBPM; + fBPM = out.m_Timing.m_BPMSegments[i].m_fBPM; break; } } // the BPM segment of this beat is the last BPM segment if( fBPM == -1 ) - fBPM = out.m_BPMSegments[out.m_BPMSegments.size()-1].m_fBPM; + fBPM = out.m_Timing.m_BPMSegments[out.m_Timing.m_BPMSegments.size()-1].m_fBPM; fFreezeSecs = (float)atof(value_data)/(fBPM*0.81f); // I have no idea what units these are in, so I experimented until finding this factor. break; @@ -695,9 +695,9 @@ bool BMSLoader::LoadFromDir( CString sDir, Song &out ) } } - for( i=0; iTrace( "There is a BPM change at beat %f, BPM %f, index %d", - out.m_BPMSegments[i].m_fStartBeat, out.m_BPMSegments[i].m_fBPM, i ); + out.m_Timing.m_BPMSegments[i].m_fStartBeat, out.m_Timing.m_BPMSegments[i].m_fBPM, i ); return true; } diff --git a/stepmania/src/NotesLoaderDWI.cpp b/stepmania/src/NotesLoaderDWI.cpp index 6a94915131..f051673e85 100644 --- a/stepmania/src/NotesLoaderDWI.cpp +++ b/stepmania/src/NotesLoaderDWI.cpp @@ -390,7 +390,7 @@ bool DWILoader::LoadFromDWIFile( CString sPath, Song &out ) else if( 0==stricmp(sValueName,"GAP") ) // the units of GAP is 1/1000 second - out.m_fBeat0OffsetInSeconds = -atoi( sParams[1] ) / 1000.0f; + out.m_Timing.m_fBeat0OffsetInSeconds = -atoi( sParams[1] ) / 1000.0f; else if( 0==stricmp(sValueName,"SAMPLESTART") ) out.m_fMusicSampleStartSeconds = ParseBrokenDWITimestamp(sParams[1], sParams[2], sParams[3]); diff --git a/stepmania/src/NotesLoaderKSF.cpp b/stepmania/src/NotesLoaderKSF.cpp index d5354cdc4e..98e48c9a6a 100644 --- a/stepmania/src/NotesLoaderKSF.cpp +++ b/stepmania/src/NotesLoaderKSF.cpp @@ -14,19 +14,19 @@ void KSFLoader::RemoveHoles( NoteData &out, const Song &song ) { /* Start at the second BPM segment; the first one is already aligned. */ - for( unsigned seg = 1; seg < song.m_BPMSegments.size(); ++seg ) + for( unsigned seg = 1; seg < song.m_Timing.m_BPMSegments.size(); ++seg ) { -// const float FromBeat = song.m_BPMSegments[seg].m_fStartBeat; - const float FromBeat = song.m_BPMSegments[seg].m_fStartBeat * song.m_BPMSegments[seg].m_fBPM / song.m_BPMSegments[0].m_fBPM; +// const float FromBeat = song.m_Timing.m_BPMSegments[seg].m_fStartBeat; + const float FromBeat = song.m_Timing.m_BPMSegments[seg].m_fStartBeat * song.m_BPMSegments[seg].m_fBPM / song.m_BPMSegments[0].m_fBPM; const int FromRow = (int) BeatToNoteRow(FromBeat); - const int ToRow = (int) BeatToNoteRow(song.m_BPMSegments[seg].m_fStartBeat); + const int ToRow = (int) BeatToNoteRow(song.m_Timing.m_BPMSegments[seg].m_fStartBeat); LOG->Trace("from %f (%i) to (%i)", FromBeat, FromRow, ToRow); -// const int ToRow = (int) roundf(FromRow * song.m_BPMSegments[0].m_fBPM / song.m_BPMSegments[seg].m_fBPM); +// const int ToRow = (int) roundf(FromRow * song.m_Timing.m_BPMSegments[0].m_fBPM / song.m_BPMSegments[seg].m_fBPM); // const int Rows = out.GetLastRow() - FromRow + 1; // int LastRow; -// if(seg+1 < song.m_BPMSegments().size()) -// LastRow = (int) NoteRowToBeat( song.m_BPMSegments[seg+1].m_fStartBeat ) - 1; +// if(seg+1 < song.m_Timing.m_BPMSegments().size()) +// LastRow = (int) NoteRowToBeat( song.m_Timing.m_BPMSegments[seg+1].m_fStartBeat ) - 1; // else // LastRow = out.GetLastRow(); NoteData tmp; @@ -41,7 +41,7 @@ void KSFLoader::RemoveHoles( NoteData &out, const Song &song ) for( t = 0; t < notedata.GetNumTracks(); ++t ) { const float CurBPM = song.GetBPMAtBeat( NoteRowToBeat(row) ); - song.m_BPMSegments.size() + song.m_Timing.m_BPMSegments.size() for( int row = 0; row <= notedata.GetLastRow(); ++row ) { TapNote tn = notedata.GetTapNote(t, row); @@ -204,7 +204,7 @@ bool KSFLoader::LoadFromKSFFile( const CString &sPath, Steps &out, const Song &s } /* We need to remove holes where the BPM increases. */ -// if( song.m_BPMSegments.size() > 1 ) +// if( song.m_Timing.m_BPMSegments.size() > 1 ) // RemoveHoles( notedata, song ); out.SetNoteData(¬edata); @@ -287,7 +287,7 @@ bool KSFLoader::LoadGlobalData( const CString &sPath, Song &out ) else if( 0==stricmp(sValueName,"BUNKI2") ) BPMPos3 = float(atof(sParams[1])) / 100.0f; else if( 0==stricmp(sValueName,"STARTTIME") ) - out.m_fBeat0OffsetInSeconds = -(float)atof(sParams[1])/100; + out.m_Timing.m_fBeat0OffsetInSeconds = -(float)atof(sParams[1])/100; else if( 0==stricmp(sValueName,"TICKCOUNT") || 0==stricmp(sValueName,"STEP") || 0==stricmp(sValueName,"DIFFICULTY")) diff --git a/stepmania/src/NotesLoaderSM.cpp b/stepmania/src/NotesLoaderSM.cpp index cd3d79332b..a0620eca20 100644 --- a/stepmania/src/NotesLoaderSM.cpp +++ b/stepmania/src/NotesLoaderSM.cpp @@ -62,8 +62,8 @@ bool SMLoader::LoadFromSMFile( CString sPath, Song &out ) { LOG->Trace( "Song::LoadFromSMFile(%s)", sPath.c_str() ); - out.m_BPMSegments.clear(); - out.m_StopSegments.clear(); + out.m_Timing.m_BPMSegments.clear(); + out.m_Timing.m_StopSegments.clear(); MsdFile msd; bool bResult = msd.ReadFile( sPath ); @@ -165,7 +165,7 @@ bool SMLoader::LoadFromSMFile( CString sPath, Song &out ) } else if( 0==stricmp(sValueName,"OFFSET") ) - out.m_fBeat0OffsetInSeconds = (float)atof( sParams[1] ); + out.m_Timing.m_fBeat0OffsetInSeconds = (float)atof( sParams[1] ); else if( 0==stricmp(sValueName,"SELECTABLE") ) { diff --git a/stepmania/src/NotesWriterDWI.cpp b/stepmania/src/NotesWriterDWI.cpp index 9c723cf696..0d8c97a187 100644 --- a/stepmania/src/NotesWriterDWI.cpp +++ b/stepmania/src/NotesWriterDWI.cpp @@ -344,10 +344,10 @@ bool NotesWriterDWI::Write( CString sPath, const Song &out ) /* Write transliterations, if we have them, since DWI doesn't support UTF-8. */ f.PutLine( ssprintf("#TITLE:%s;", out.GetFullTranslitTitle().c_str()) ); f.PutLine( ssprintf("#ARTIST:%s;", out.GetTranslitArtist().c_str()) ); - ASSERT( out.m_BPMSegments[0].m_fStartBeat == 0 ); + ASSERT( out.m_Timing.m_BPMSegments[0].m_fStartBeat == 0 ); f.PutLine( ssprintf("#FILE:%s;", out.m_sMusicFile.c_str()) ); - f.PutLine( ssprintf("#BPM:%.3f;", out.m_BPMSegments[0].m_fBPM) ); - f.PutLine( ssprintf("#GAP:%d;", int(-roundf( out.m_fBeat0OffsetInSeconds*1000 ))) ); + f.PutLine( ssprintf("#BPM:%.3f;", out.m_Timing.m_BPMSegments[0].m_fBPM) ); + f.PutLine( ssprintf("#GAP:%d;", int(-roundf( out.m_Timing.m_fBeat0OffsetInSeconds*1000 ))) ); f.PutLine( ssprintf("#SAMPLESTART:%.3f;", out.m_fMusicSampleStartSeconds) ); f.PutLine( ssprintf("#SAMPLELENGTH:%.3f;", out.m_fMusicSampleLengthSeconds) ); if( out.m_sCDTitleFile.size() ) @@ -368,29 +368,29 @@ bool NotesWriterDWI::Write( CString sPath, const Song &out ) break; } - if( !out.m_StopSegments.empty() ) + if( !out.m_Timing.m_StopSegments.empty() ) { f.Write( "#FREEZE:" ); - for( unsigned i=0; i 1) + if( out.m_Timing.m_BPMSegments.size() > 1) { f.Write( "#CHANGEBPM:" ); - for( unsigned i=1; im_pCurSong->m_fBeat0OffsetInSeconds += mean; + GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += mean; LOG->Trace("Offset corrected by %f. Error in steps: %f seconds.", mean, stddev); } else LOG->Trace("Offset NOT corrected. Average offset: %f seconds. Error: %f seconds.", mean, stddev); diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index be7ca716ca..dfd52c6659 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -535,7 +535,7 @@ void ScreenEdit::UpdateTextInfo() sText += ssprintf( "Sub title:\n %s\n", m_pSong->m_sSubTitle.c_str() ); sText += ssprintf( "Tap Steps:\n %d\n", iNumTapNotes ); sText += ssprintf( "Hold Steps:\n %d\n", iNumHoldNotes ); - sText += ssprintf( "Beat 0 Offset:\n %.3f secs\n", m_pSong->m_fBeat0OffsetInSeconds ); + sText += ssprintf( "Beat 0 Offset:\n %.3f secs\n", m_pSong->m_Timing.m_fBeat0OffsetInSeconds ); sText += ssprintf( "Preview Start:\n %.2f secs\n", m_pSong->m_fMusicSampleStartSeconds ); sText += ssprintf( "Preview Length:\n %.2f secs\n",m_pSong->m_fMusicSampleLengthSeconds ); @@ -973,24 +973,24 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ } unsigned i; - for( i=0; im_StopSegments.size(); i++ ) + for( i=0; im_Timing.m_StopSegments.size(); i++ ) { - if( m_pSong->m_StopSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat ) + if( m_pSong->m_Timing.m_StopSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat ) break; } - if( i == m_pSong->m_StopSegments.size() ) // there is no BPMSegment at the current beat + if( i == m_pSong->m_Timing.m_StopSegments.size() ) // there is no BPMSegment at the current beat { // create a new StopSegment if( fStopDelta > 0 ) m_pSong->AddStopSegment( StopSegment(GAMESTATE->m_fSongBeat, fStopDelta) ); } - else // StopSegment being modified is m_StopSegments[i] + else // StopSegment being modified is m_Timing.m_StopSegments[i] { - m_pSong->m_StopSegments[i].m_fStopSeconds += fStopDelta; - if( m_pSong->m_StopSegments[i].m_fStopSeconds <= 0 ) - m_pSong->m_StopSegments.erase( m_pSong->m_StopSegments.begin()+i, - m_pSong->m_StopSegments.begin()+i+1); + m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds += fStopDelta; + if( m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 ) + m_pSong->m_Timing.m_StopSegments.erase( m_pSong->m_Timing.m_StopSegments.begin()+i, + m_pSong->m_Timing.m_StopSegments.begin()+i+1); } } break; @@ -1015,7 +1015,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ case IET_FAST_REPEAT: fOffsetDelta *= 40; break; } - m_pSong->m_fBeat0OffsetInSeconds += fOffsetDelta; + m_pSong->m_Timing.m_fBeat0OffsetInSeconds += fOffsetDelta; } break; case SDLK_LEFTBRACKET: @@ -1169,7 +1169,7 @@ void ScreenEdit::InputPlay( const DeviceInput& DeviceI, const InputEventType typ case IET_FAST_REPEAT: fOffsetDelta *= 40; break; } - m_pSong->m_fBeat0OffsetInSeconds += fOffsetDelta; + m_pSong->m_Timing.m_fBeat0OffsetInSeconds += fOffsetDelta; } break; } @@ -1724,19 +1724,19 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers ) (m_NoteFieldEdit.m_fEndMarker-m_NoteFieldEdit.m_fBeginMarker) ); unsigned i; - for( i=0; im_StopSegments.size(); i++ ) + for( i=0; im_Timing.m_StopSegments.size(); i++ ) { - if( m_pSong->m_StopSegments[i].m_fStartBeat == m_NoteFieldEdit.m_fBeginMarker ) + if( m_pSong->m_Timing.m_StopSegments[i].m_fStartBeat == m_NoteFieldEdit.m_fBeginMarker ) break; } - if( i == m_pSong->m_StopSegments.size() ) // there is no BPMSegment at the current beat + if( i == m_pSong->m_Timing.m_StopSegments.size() ) // there is no BPMSegment at the current beat { m_pSong->AddStopSegment( StopSegment(GAMESTATE->m_fSongBeat, fStopLength) ); } - else // StopSegment being extended is m_StopSegments[i] + else // StopSegment being extended is m_Timing.m_StopSegments[i] { - m_pSong->m_StopSegments[i].m_fStopSeconds += fStopLength; + m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds += fStopLength; } m_NoteFieldEdit.m_fEndMarker = -1; break; @@ -1750,19 +1750,19 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers ) { float fBPMatPause = m_pSong->GetBPMAtBeat( GAMESTATE->m_fSongBeat ); unsigned i; - for( i=0; im_StopSegments.size(); i++ ) + for( i=0; im_Timing.m_StopSegments.size(); i++ ) { - if( m_pSong->m_StopSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat ) + if( m_pSong->m_Timing.m_StopSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat ) break; } - if( i == m_pSong->m_StopSegments.size() ) // there is no BPMSegment at the current beat + if( i == m_pSong->m_Timing.m_StopSegments.size() ) // there is no BPMSegment at the current beat break; - else // StopSegment being modified is m_StopSegments[i] + else // StopSegment being modified is m_Timing.m_StopSegments[i] { - float fStopLength = m_pSong->m_StopSegments[i].m_fStopSeconds; - m_pSong->m_StopSegments.erase( m_pSong->m_StopSegments.begin()+i, - m_pSong->m_StopSegments.begin()+i+1); + float fStopLength = m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds; + m_pSong->m_Timing.m_StopSegments.erase( m_pSong->m_Timing.m_StopSegments.begin()+i, + m_pSong->m_Timing.m_StopSegments.begin()+i+1); fStopLength /= fBPMatPause; fStopLength *= 60; // don't move the step from where it is, just move everything later diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 7962684cc3..3b5fe2d156 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -257,7 +257,7 @@ ScreenGameplay::ScreenGameplay( CString sName, bool bDemonstration ) : Screen("S if( GAMESTATE->IsCourseMode() ) g_fOldOffset = -1000; else - g_fOldOffset = GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds; + g_fOldOffset = GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds; @@ -1512,9 +1512,9 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ case IET_FAST_REPEAT: fOffsetDelta *= 40; break; } - GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds += fOffsetDelta; + GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += fOffsetDelta; - m_textDebug.SetText( ssprintf("Offset = %.3f", GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds) ); + m_textDebug.SetText( ssprintf("Offset = %.3f", GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds) ); m_textDebug.StopTweening(); m_textDebug.SetDiffuse( RageColor(1,1,1,1) ); m_textDebug.BeginTweening( 3 ); // sleep @@ -1614,14 +1614,14 @@ void ScreenGameplay::ShowSavePrompt( ScreenMessage SM_SendWhenDone ) "%s\n", GAMESTATE->m_pCurSong->GetFullDisplayTitle().c_str() ); - if( fabs(GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds - g_fOldOffset) > 0.001 ) + if( fabs(GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds - g_fOldOffset) > 0.001 ) { sMessage += ssprintf( "\n" "Offset was changed from %.3f to %.3f (%.3f).\n", g_fOldOffset, - GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds, - GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds - g_fOldOffset ); + GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds, + GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds - g_fOldOffset ); } sMessage += diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 7a2594e6f5..b1f4232810 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -28,7 +28,6 @@ #include "TitleSubstitution.h" #include "BannerCache.h" #include "Sprite.h" -#include "PrefsManager.h" #include "arch/arch.h" #include "RageFile.h" #include "NoteDataUtil.h" @@ -54,25 +53,6 @@ const int FILE_CACHE_VERSION = 131; // increment this when Song or Steps changes const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f; -static int CompareBPMSegments(const BPMSegment &seg1, const BPMSegment &seg2) -{ - return seg1.m_fStartBeat < seg2.m_fStartBeat; -} - -void SortBPMSegmentsArray( vector &arrayBPMSegments ) -{ - sort( arrayBPMSegments.begin(), arrayBPMSegments.end(), CompareBPMSegments ); -} - -static int CompareStopSegments(const StopSegment &seg1, const StopSegment &seg2) -{ - return seg1.m_fStartBeat < seg2.m_fStartBeat; -} - -void SortStopSegmentsArray( vector &arrayStopSegments ) -{ - sort( arrayStopSegments.begin(), arrayStopSegments.end(), CompareStopSegments ); -} int CompareBackgroundChanges(const BackgroundChange &seg1, const BackgroundChange &seg2) { @@ -91,7 +71,6 @@ void SortBackgroundChangesArray( vector &arrayBackgroundChange Song::Song() { m_bChangedSinceSave = false; - m_fBeat0OffsetInSeconds = 0; m_fMusicSampleStartSeconds = -1; m_fMusicSampleLengthSeconds = DEFAULT_MUSIC_SAMPLE_LENGTH; m_fMusicLengthSeconds = 0; @@ -124,41 +103,6 @@ void Song::Reset() } -void Song::AddBPMSegment( BPMSegment seg ) -{ - m_BPMSegments.push_back( seg ); - SortBPMSegmentsArray( m_BPMSegments ); -} - -void Song::SetBPMAtBeat( float fBeat, float fBPM ) -{ - unsigned i; - for( i=0; i 0 && fabsf(m_BPMSegments[i-1].m_fBPM - fBPM) < 0.009f ) - m_BPMSegments.erase( m_BPMSegments.begin()+i, - m_BPMSegments.begin()+i+1); - else - m_BPMSegments[i].m_fBPM = fBPM; - } -} - -void Song::AddStopSegment( StopSegment seg ) -{ - m_StopSegments.push_back( seg ); - SortStopSegmentsArray( m_StopSegments ); -} - - void Song::AddBackgroundChange( BackgroundChange seg ) { m_BackgroundChanges.push_back( seg ); @@ -171,152 +115,29 @@ void Song::AddLyricSegment( LyricSegment seg ) m_LyricSegments.push_back( seg ); } - -float Song::GetMusicStartBeat() const +void Song::GetDisplayBPM( float &fMinBPMOut, float &fMaxBPMOut ) const { - float fBPS = m_BPMSegments[0].m_fBPM / 60.0f; - return -(PREFSMAN->m_fGlobalOffsetSeconds+m_fBeat0OffsetInSeconds)*fBPS; -}; - -void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const -{ -// LOG->Trace( "GetBeatAndBPSFromElapsedTime( fElapsedTime = %f )", fElapsedTime ); - // This function is a nightmare. Don't even try to understand it. :-) - - fElapsedTime += PREFSMAN->m_fGlobalOffsetSeconds; - - fElapsedTime += m_fBeat0OffsetInSeconds; - - - for( unsigned i=0; i fSecondsInThisSegment ) - { - // this BPMSegement is NOT the current segment - fElapsedTime -= fSecondsInThisSegment; - continue; - } - - // this BPMSegment IS the current segment - - float fBeatEstimate = fStartBeatThisSegment + fElapsedTime*fBPS; - - for( j=0; j m_StopSegments[j].m_fStartBeat || - m_StopSegments[j].m_fStartBeat > fStartBeatNextSegment ) - continue; - - // this freeze lies within this BPMSegment - - if( m_StopSegments[j].m_fStartBeat > fBeatEstimate ) - break; - - fElapsedTime -= m_StopSegments[j].m_fStopSeconds; - // re-estimate - fBeatEstimate = fStartBeatThisSegment + fElapsedTime*fBPS; - if( fBeatEstimate < m_StopSegments[j].m_fStartBeat ) - { - fBeatOut = m_StopSegments[j].m_fStartBeat; - fBPSOut = fBPS; - bFreezeOut = true; - return; - } - } - - fBeatOut = fBeatEstimate; - fBPSOut = fBPS; - bFreezeOut = false; - return; + fMinBPMOut = m_fSpecifiedBPMMin; + fMaxBPMOut = m_fSpecifiedBPMMax; + } + else + { + m_Timing.GetActualBPM( fMinBPMOut, fMaxBPMOut ); } } - -float Song::GetElapsedTimeFromBeat( float fBeat ) const +CString Song::GetBackgroundAtBeat( float fBeat ) const { - float fElapsedTime = 0; - fElapsedTime -= PREFSMAN->m_fGlobalOffsetSeconds; - fElapsedTime -= m_fBeat0OffsetInSeconds; - - for( unsigned j=0; j= fBeat ) + unsigned i; + for( i=0; i fBeat ) break; - fElapsedTime += m_StopSegments[j].m_fStopSeconds; - } - - for( unsigned i=0; im_fMusicLengthSeconds/2; // seconds - float fSecondsToMove = fElapsedTimeBestGuess; // seconds - float fBeatOut, fBPSOut; - bool bFreezeOut; - - /* 0.001 gives higher precision and takes about 7 more iterations than - * 0.100. A 90-second song took about 9 iterations; now it takes about - * 16. -glenn */ - while( fSecondsToMove > 0.001f ) - { - GetBeatAndBPSFromElapsedTime( fElapsedTimeBestGuess, fBeatOut, fBPSOut, bFreezeOut ); - /* If this is an exact match, we're done. However, if we're on a - * freeze segment, keep moving backwards until we're off it, so we - * return the time associated with the beginning of the freeze segment - * and not some random place in its middle. */ - if( fBeatOut == fBeat && !bFreezeOut) - break; - - if( fBeatOut >= fBeat ) - fElapsedTimeBestGuess -= fSecondsToMove; - else - fElapsedTimeBestGuess += fSecondsToMove; - - fSecondsToMove /= 2; - } - - return fElapsedTimeBestGuess; -#endif + return m_BackgroundChanges[i].m_sBGName; } + CString Song::GetCacheFilePath() const { return ssprintf( CACHE_DIR "Songs/%u", GetHashForString(m_sSongDir) ); @@ -686,14 +507,14 @@ void Song::TidyUpData() if( m_sArtist == "" ) m_sArtist = "Unknown artist"; TranslateTitles(); - if( m_BPMSegments.empty() ) + if( m_Timing.m_BPMSegments.empty() ) { /* XXX: Once we have a way to display warnings that the user actually * cares about (unlike most warnings), this should be one of them. */ LOG->Warn( "No BPM segments specified in '%s%s', default provided.", m_sSongDir.c_str(), m_sSongFileName.c_str() ); - AddBPMSegment( BPMSegment(0, 60) ); + m_Timing.AddBPMSegment( BPMSegment(0, 60) ); } /* Only automatically set the sample time if there was no sample length @@ -977,12 +798,10 @@ void Song::ReCalculateRadarValuesAndLastBeat() } - // - // calculate first/last beat - // - /* Many songs have stray, empty song patterns. Ignore them, so + /* Calculate first/last beat. + * + * Many songs have stray, empty song patterns. Ignore them, so * they don't force the first beat of the whole song to 0. */ - if(tempNoteData.GetLastRow() == 0) continue; diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 530b7adcd7..7b8a00d9b9 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -65,7 +65,7 @@ IntDir=.\../Debug6 TargetDir=\temp\stepmania\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -82,28 +82,24 @@ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -XBCP=xbecopy.exe -# ADD BASE XBCP /NOLOGO -# ADD XBCP /NOLOGO -XBE=imagebld.exe -# ADD BASE XBE /nologo /stack:0x10000 /debug -# ADD XBE /nologo /stack:0x10000 /debug /out:"../default.xbe" -LINK32=link.exe -# ADD BASE LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /subsystem:xbox /fixed:no /TMP -# ADD LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /nodefaultlib:"libcd" /nodefaultlib:"libcmt" /out:"../StepManiaXbox-debug.exe" /subsystem:xbox /fixed:no /TMP -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo CPP=cl.exe # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_XBOX" /D "_DEBUG" /YX /FD /G6 /Ztmp /c # ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /D "OGG_ONLY" /YX /FD /G6 /Ztmp /c +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /subsystem:xbox /fixed:no /TMP +# ADD LINK32 xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /incremental:no /debug /machine:I386 /nodefaultlib:"libcd" /nodefaultlib:"libcmt" /out:"../StepManiaXbox-debug.exe" /subsystem:xbox /fixed:no /TMP +XBE=imagebld.exe +# ADD BASE XBE /nologo /stack:0x10000 /debug +# ADD XBE /nologo /stack:0x10000 /debug /out:"../default.xbe" +XBCP=xbecopy.exe +# ADD BASE XBCP /NOLOGO +# ADD XBCP /NOLOGO # Begin Special Build Tool -IntDir=.\Debug -TargetDir=\stepmania\stepmania -TargetName=default -SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp \ - /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp \ + /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -143,7 +139,7 @@ IntDir=.\../Release6 TargetDir=\temp\stepmania\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -161,31 +157,27 @@ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania # PROP Intermediate_Dir "StepMania___Xbox_Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" -XBCP=xbecopy.exe -# ADD BASE XBCP /NOLOGO -# ADD XBCP /NOLOGO -XBE=imagebld.exe -# ADD BASE XBE /nologo /stack:0x10000 /debug -# ADD XBE /nologo /testid:"123456" /stack:0x10000 /debug /out:"../default.xbe" +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /Fr /YX"global.h" /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "NDEBUG" /YX"global.h" /FD /c +# SUBTRACT CPP /Fr +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 $(intdir)\verstub.obj xapilibd.lib d3d8d.lib d3dx8d.lib xgraphicsd.lib dsoundd.lib dmusicd.lib xnetd.lib xboxkrnl.lib /nologo /pdb:"../debug6/StepMania-debug.pdb" /map /debug /machine:IX86 /nodefaultlib:"libcmtd.lib" /out:"../StepMania-debug.exe" # SUBTRACT BASE LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib # ADD LINK32 $(intdir)\verstub.obj xapilib.lib d3d8.lib d3dx8.lib xgraphics.lib dsound.lib dmusic.lib xnet.lib xboxkrnl.lib libcmt.lib /nologo /incremental:no /pdb:"../release6xbox/StepMania.pdb" /machine:I386 /nodefaultlib:"libc" /nodefaultlib:"libcmtd" /out:"../StepManiaXbox.exe" /subsystem:xbox /fixed:no /TMP /OPT:REF # SUBTRACT LINK32 /pdb:none /map /debug -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -CPP=cl.exe -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /Fr /YX"global.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /I "SDL_sound-1.0.0" /D "WIN32" /D "_XBOX" /D "NDEBUG" /YX"global.h" /FD /c -# SUBTRACT CPP /Fr +XBE=imagebld.exe +# ADD BASE XBE /nologo /stack:0x10000 /debug +# ADD XBE /nologo /testid:"123456" /stack:0x10000 /debug /out:"../default.xbe" +XBCP=xbecopy.exe +# ADD BASE XBCP /NOLOGO +# ADD XBCP /NOLOGO # Begin Special Build Tool -IntDir=.\StepMania___Xbox_Release -TargetDir=\stepmania\stepmania -TargetName=default -SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp \ - /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp \ + /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -1812,6 +1804,25 @@ SOURCE=.\StyleInput.h # End Source File # Begin Source File +SOURCE=.\TimingData.cpp + +!IF "$(CFG)" == "StepMania - Win32 Debug" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Debug" + +!ELSEIF "$(CFG)" == "StepMania - Win32 Release" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\TimingData.h +# End Source File +# Begin Source File + SOURCE=.\TitleSubstitution.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index dfe5afb974..ff2f2154bb 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -764,6 +764,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 14cdbdfbab..c863d57cd2 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -14,6 +14,8 @@ #include "PlayerNumber.h" #include "GameConstantsAndTypes.h" #include "Grade.h" +#include "TimingData.h" + class Steps; class StyleDef; class NotesLoader; @@ -23,22 +25,6 @@ class LyricsLoader; extern const int FILE_CACHE_VERSION; -struct BPMSegment -{ - BPMSegment() { m_fStartBeat = m_fBPM = -1; }; - BPMSegment( float s, float b ) { m_fStartBeat = s; m_fBPM = b; }; - float m_fStartBeat; - float m_fBPM; -}; - -struct StopSegment -{ - StopSegment() { m_fStartBeat = m_fStopSeconds = -1; }; - StopSegment( float s, float f ) { m_fStartBeat = s; m_fStopSeconds = f; }; - float m_fStartBeat; - float m_fStopSeconds; -}; - struct BackgroundChange { BackgroundChange() { m_fStartBeat=-1; m_fRate=1; m_bFadeLast=false; m_bRewindMovie=false; m_bLoop=true; }; @@ -134,7 +120,6 @@ public: CString m_sCredit; CString m_sMusicFile; - float m_fBeat0OffsetInSeconds; float m_fMusicLengthSeconds; float m_fFirstBeat; float m_fLastBeat; @@ -144,8 +129,6 @@ public: float m_fSpecifiedBPMMin; float m_fSpecifiedBPMMax; // if a range, then Min != Max - float GetMusicStartBeat() const; - CString m_sBannerFile; CString m_sLyricsFile; CString m_sBackgroundFile; @@ -168,73 +151,24 @@ public: bool Matches(CString sGroup, CString sSong) const; - vector m_BPMSegments; // this must be sorted before gameplay - vector m_StopSegments; // this must be sorted before gameplay + TimingData m_Timing; vector m_BackgroundChanges; // this must be sorted before gameplay vector m_LyricSegments; // same - void AddBPMSegment( BPMSegment seg ); - void AddStopSegment( StopSegment seg ); + void AddBPMSegment( const BPMSegment &seg ) { m_Timing.AddBPMSegment( seg ); } + void AddStopSegment( const StopSegment &seg ) { m_Timing.AddStopSegment( seg ); } void AddBackgroundChange( BackgroundChange seg ); void AddLyricSegment( LyricSegment seg ); - void GetDisplayBPM( float &fMinBPMOut, float &fMaxBPMOut ) const - { - if( m_DisplayBPMType == DISPLAY_SPECIFIED ) - { - fMinBPMOut = m_fSpecifiedBPMMin; - fMaxBPMOut = m_fSpecifiedBPMMax; - } - else - { - GetActualBPM( fMinBPMOut, fMaxBPMOut ); - } - } - void GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const - { - fMaxBPMOut = 0; - fMinBPMOut = 100000; // inf - for( unsigned i=0; i fBeat ) - break; - return m_BPMSegments[i].m_fBPM; - } - void SetBPMAtBeat( float fBeat, float fBPM ); - BPMSegment& GetBPMSegmentAtBeat( float fBeat ) - { - unsigned i; - for( i=0; i fBeat ) - break; - return m_BPMSegments[i]; - }; - CString GetBackgroundAtBeat( float fBeat ) - { - unsigned i; - for( i=0; i fBeat ) - break; - return m_BackgroundChanges[i].m_sBGName; - } - void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const; - float GetBeatFromElapsedTime( float fElapsedTime ) const // shortcut for places that care only about the beat - { - float fBeat, fThrowAway; - bool bThrowAway; - GetBeatAndBPSFromElapsedTime( fElapsedTime, fBeat, fThrowAway, bThrowAway ); - return fBeat; - } - float GetElapsedTimeFromBeat( float fBeat ) const; + void GetDisplayBPM( float &fMinBPMOut, float &fMaxBPMOut ) const; + CString GetBackgroundAtBeat( float fBeat ) const; + + float GetBPMAtBeat( float fBeat ) const { return m_Timing.GetBPMAtBeat( fBeat ); } + void SetBPMAtBeat( float fBeat, float fBPM ) { m_Timing.SetBPMAtBeat( fBeat, fBPM ); } + BPMSegment& GetBPMSegmentAtBeat( float fBeat ) { return m_Timing.GetBPMSegmentAtBeat( fBeat ); } + void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const { m_Timing.GetBeatAndBPSFromElapsedTime( fElapsedTime, fBeatOut, fBPSOut, bFreezeOut ); } + float GetBeatFromElapsedTime( float fElapsedTime ) const { return m_Timing.GetBeatFromElapsedTime( fElapsedTime ); } + float GetElapsedTimeFromBeat( float fBeat ) const { return m_Timing.GetElapsedTimeFromBeat( fBeat ); }