From 94f112e9233d1b21f3ffbb109d6a1a9fe8c380ba Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Sun, 8 May 2011 00:58:03 +0700 Subject: [PATCH 001/197] [timingdata] Let's break things! (for now) --- src/Song.h | 5 ++++- src/Steps.h | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Song.h b/src/Song.h index 9c105a5732..4858080d1a 100644 --- a/src/Song.h +++ b/src/Song.h @@ -284,7 +284,10 @@ public: bool Matches(RString sGroup, RString sSong) const; /** @brief The Song's TimingData. */ - TimingData m_Timing; + TimingData m_SongTiming; + + /** @brief The initial offset of a song. */ + float m_fBeat0OffsetInSeconds; typedef vector VBackgroundChange; private: diff --git a/src/Steps.h b/src/Steps.h index fee6204527..5ffb2b625c 100644 --- a/src/Steps.h +++ b/src/Steps.h @@ -31,6 +31,9 @@ public: /** @brief Destroy the Steps that are no longer needed. */ ~Steps(); + /** @brief Timing data */ + TimingData m_SongTiming; + // initializers void AutogenFrom( const Steps *parent, StepsType ntTo ); void CopyFrom( Steps* pSource, StepsType ntTo, float fMusicLengthSeconds ); From 0e1843ff8049791f071cb1f868b591af225a0644 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Sun, 8 May 2011 01:15:25 +0700 Subject: [PATCH 002/197] [splittiming] 919 errors => 236 errors --- src/Song.h | 29 ++++++++++++++++++++++++++++- src/Steps.h | 8 +++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Song.h b/src/Song.h index 4858080d1a..da2835c79f 100644 --- a/src/Song.h +++ b/src/Song.h @@ -8,9 +8,9 @@ #include "RageUtil_AutoPtr.h" #include "RageUtil_CachedObject.h" #include "RageTypes.h" +#include "Steps.h" #include -class Steps; class Style; class StepsID; struct lua_State; @@ -319,9 +319,11 @@ public: * This must be sorted before gameplay. */ vector m_LyricSegments; +/* [splittiming] void AddBPMSegment( const BPMSegment &seg ) { m_Timing.AddBPMSegment( seg ); } void AddStopSegment( const StopSegment &seg ) { m_Timing.AddStopSegment( seg ); } void AddWarpSegment( const WarpSegment &seg ) { m_Timing.AddWarpSegment( seg ); } +*/ void AddBackgroundChange( BackgroundLayer blLayer, BackgroundChange seg ); void AddForegroundChange( BackgroundChange seg ); void AddLyricSegment( LyricSegment seg ); @@ -329,18 +331,43 @@ public: void GetDisplayBpms( DisplayBpms &AddTo ) const; const BackgroundChange &GetBackgroundAtBeat( BackgroundLayer iLayer, float fBeat ) const; +/* [splittiming] 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 ); } +*/ + /** * @brief Retrieve the beat based on the specified time. * @param fElapsedTime the amount of time since the Song started. * @return the appropriate beat. */ float GetBeatFromElapsedTime( float fElapsedTime ) const + { + return m_SongTiming.GetBeatFromElapsedTime( fElapsedTime ); + } + float GetBeatFromElapsedTime( float fElapsedTime, const Steps &steps ) const + { + return steps.m_Timing.GetBeatFromElapsedTime( fElapsedTime ); + } + + float GetElapsedTimeFromBeat( float fBeat ) const + { + return m_SongTiming.GetElapsedTimeFromBeat( fBeat ); + } + float GetElapsedTimeFromBeat( float fBeat, const Steps &steps ) const + { + return steps.m_Timing.GetElapsedTimeFromBeat( fBeat ); + } + + + /* [splittiming] + float GetBeatFromElapsedTime( float fElapsedTime ) const { return m_Timing.GetBeatFromElapsedTime( fElapsedTime ); } float GetElapsedTimeFromBeat( float fBeat ) const { return m_Timing.GetElapsedTimeFromBeat( fBeat ); } + */ + bool HasSignificantBpmChangesOrStops() const; float GetStepsSeconds() const; bool IsLong() const; diff --git a/src/Steps.h b/src/Steps.h index 5ffb2b625c..e796f99847 100644 --- a/src/Steps.h +++ b/src/Steps.h @@ -8,6 +8,8 @@ #include "Difficulty.h" #include "RageUtil_AutoPtr.h" #include "RageUtil_CachedObject.h" +#include "TimingData.h" + class Profile; class NoteData; struct lua_State; @@ -31,9 +33,6 @@ public: /** @brief Destroy the Steps that are no longer needed. */ ~Steps(); - /** @brief Timing data */ - TimingData m_SongTiming; - // initializers void AutogenFrom( const Steps *parent, StepsType ntTo ); void CopyFrom( Steps* pSource, StepsType ntTo, float fMusicLengthSeconds ); @@ -119,6 +118,9 @@ public: void TidyUpData(); void CalculateRadarValues( float fMusicLengthSeconds ); + /** @brief Timing data */ + TimingData m_Timing; + // Lua void PushSelf( lua_State *L ); From 40651800f0c572a49e8500ac83783d827650eb03 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Sun, 8 May 2011 01:20:58 +0700 Subject: [PATCH 003/197] [splittiming] temporarily rename these functions to make sure that we don't call the wrong one. after it's settled we can rename it back. --- src/Song.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Song.h b/src/Song.h index da2835c79f..2b6769566f 100644 --- a/src/Song.h +++ b/src/Song.h @@ -341,20 +341,20 @@ public: * @brief Retrieve the beat based on the specified time. * @param fElapsedTime the amount of time since the Song started. * @return the appropriate beat. */ - float GetBeatFromElapsedTime( float fElapsedTime ) const + float SongGetBeatFromElapsedTime( float fElapsedTime ) const { return m_SongTiming.GetBeatFromElapsedTime( fElapsedTime ); } - float GetBeatFromElapsedTime( float fElapsedTime, const Steps &steps ) const + float StepsGetBeatFromElapsedTime( float fElapsedTime, const Steps &steps ) const { return steps.m_Timing.GetBeatFromElapsedTime( fElapsedTime ); } - float GetElapsedTimeFromBeat( float fBeat ) const + float SongGetElapsedTimeFromBeat( float fBeat ) const { return m_SongTiming.GetElapsedTimeFromBeat( fBeat ); } - float GetElapsedTimeFromBeat( float fBeat, const Steps &steps ) const + float StepsGetElapsedTimeFromBeat( float fBeat, const Steps &steps ) const { return steps.m_Timing.GetElapsedTimeFromBeat( fBeat ); } From 9384f82ccda5c18c462f1d194b2a6dd600e74266 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 9 May 2011 22:37:15 +0700 Subject: [PATCH 004/197] [splittiming] a function to create steps for the song (259 build errors) --- src/NotesLoaderSM.cpp | 2 +- src/Song.cpp | 12 ++++++++++++ src/Song.h | 6 +++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index f1ab8ec5ad..f937bdf78c 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -458,7 +458,7 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache } out.m_Timing.m_sFile = sPath; - LoadTimingFromSMFile( msd, out.m_Timing ); + LoadTimingFromSMFile( msd, out.m_SongTiming ); for( unsigned i=0; im_Timing = m_SongTiming; +} + void Song::GetDisplayBpms( DisplayBpms &AddTo ) const { if( m_DisplayBPMType == DISPLAY_BPM_SPECIFIED ) diff --git a/src/Song.h b/src/Song.h index 2b6769566f..1d49724795 100644 --- a/src/Song.h +++ b/src/Song.h @@ -336,11 +336,15 @@ public: void SetBPMAtBeat( float fBeat, float fBPM ) { m_Timing.SetBPMAtBeat( fBeat, fBPM ); } BPMSegment& GetBPMSegmentAtBeat( float fBeat ) { return m_Timing.GetBPMSegmentAtBeat( fBeat ); } */ + + Steps *CreateSteps(); + void InitSteps(Steps *pSteps); /** * @brief Retrieve the beat based on the specified time. * @param fElapsedTime the amount of time since the Song started. * @return the appropriate beat. */ + /* [splittiming] float SongGetBeatFromElapsedTime( float fElapsedTime ) const { return m_SongTiming.GetBeatFromElapsedTime( fElapsedTime ); @@ -358,7 +362,7 @@ public: { return steps.m_Timing.GetElapsedTimeFromBeat( fBeat ); } - + */ /* [splittiming] float GetBeatFromElapsedTime( float fElapsedTime ) const From 0d42b00621f0ae1e96cd4931ef00ed7eb66e1be2 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 9 May 2011 22:41:49 +0700 Subject: [PATCH 005/197] [splittiming] Fix NotesLoaderDWI, NotesLoaderSM, NotesWriterSWI, NotesWriterSM by replace occurences of m_Timing with m_SongTiming. (224 build errors) --- src/NotesLoaderDWI.cpp | 10 +++++----- src/NotesLoaderSM.cpp | 2 +- src/NotesWriterDWI.cpp | 22 +++++++++++----------- src/NotesWriterSM.cpp | 34 +++++++++++++++++----------------- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/NotesLoaderDWI.cpp b/src/NotesLoaderDWI.cpp index b15c74252f..0c0f327e98 100644 --- a/src/NotesLoaderDWI.cpp +++ b/src/NotesLoaderDWI.cpp @@ -481,11 +481,11 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set &Bla if( PREFSMAN->m_bQuirksMode ) { - out.AddBPMSegment( BPMSegment(0, fBPM) ); + out.m_SongTiming.AddBPMSegment( BPMSegment(0, fBPM) ); } else{ if( fBPM > 0.0f ) - out.AddBPMSegment( BPMSegment(0, fBPM) ); + out.m_SongTiming.AddBPMSegment( BPMSegment(0, fBPM) ); else LOG->UserLog( "Song file", sPath, "has an invalid BPM change at beat %f, BPM %f.", NoteRowToBeat(0), fBPM ); @@ -517,7 +517,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set &Bla else if( 0==stricmp(sValueName,"GAP") ) // the units of GAP is 1/1000 second - out.m_Timing.m_fBeat0OffsetInSeconds = -atoi( sParams[1] ) / 1000.0f; + out.m_SongTiming.m_fBeat0OffsetInSeconds = -atoi( sParams[1] ) / 1000.0f; else if( 0==stricmp(sValueName,"SAMPLESTART") ) out.m_fMusicSampleStartSeconds = ParseBrokenDWITimestamp(sParams[1], sParams[2], sParams[3]); @@ -542,7 +542,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set &Bla int iFreezeRow = BeatToNoteRow( StringToFloat(arrayFreezeValues[0]) / 4.0f ); float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ) / 1000.0f; - out.AddStopSegment( StopSegment(iFreezeRow, fFreezeSeconds) ); + out.m_SongTiming.AddStopSegment( StopSegment(iFreezeRow, fFreezeSeconds) ); // LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", fFreezeBeat, fFreezeSeconds ); } } @@ -567,7 +567,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set &Bla if( fBPM > 0.0f ) { BPMSegment bs( iStartIndex, fBPM ); - out.AddBPMSegment( bs ); + out.m_SongTiming.AddBPMSegment( bs ); } else { diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index f937bdf78c..dee9aa1fb9 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -457,7 +457,7 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache return false; } - out.m_Timing.m_sFile = sPath; + out.m_SongTiming.m_sFile = sPath; LoadTimingFromSMFile( msd, out.m_SongTiming ); for( unsigned i=0; i 1) + if( out.m_SongTiming.m_BPMSegments.size() > 1) { f.Write( "#CHANGEBPM:" ); - for( unsigned i=1; i 0 ) @@ -111,25 +111,25 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) f.Write( "#BPMS:" ); - for( unsigned i=0; im_iStartRow), iter->m_iNumerator, iter->m_iDenominator ) ); vector::const_iterator iter2 = iter; iter2++; - if( iter2 != out.m_Timing.m_vTimeSignatureSegments.end() ) + if( iter2 != out.m_SongTiming.m_vTimeSignatureSegments.end() ) f.Write( "," ); } f.PutLine( ";" ); - ASSERT( !out.m_Timing.m_TickcountSegments.empty() ); + ASSERT( !out.m_SongTiming.m_TickcountSegments.empty() ); f.Write( "#TICKCOUNTS:" ); - for( unsigned i=0; i Date: Mon, 9 May 2011 22:47:47 +0700 Subject: [PATCH 006/197] [splittiming] replace `new Steps` with `[song].CreateSteps()` (224 build errors) --- src/NotesLoaderBMS.cpp | 2 +- src/NotesLoaderDWI.cpp | 2 +- src/NotesLoaderMidi.cpp | 2 +- src/NotesLoaderPMS.cpp | 2 +- src/NotesLoaderSM.cpp | 4 ++-- src/NotesLoaderSMA.cpp | 4 ++-- src/NotesLoaderSSC.cpp | 6 +++--- src/ScreenEdit.cpp | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/NotesLoaderBMS.cpp b/src/NotesLoaderBMS.cpp index d90a368591..4a95e85d57 100644 --- a/src/NotesLoaderBMS.cpp +++ b/src/NotesLoaderBMS.cpp @@ -1031,7 +1031,7 @@ bool BMSLoader::LoadFromDir( const RString &sDir, Song &out ) // Create a Steps for each. vector apSteps; for( unsigned i=0; i &Bla 0==stricmp(sValueName,"COUPLE") || 0==stricmp(sValueName,"SOLO") ) { - Steps* pNewNotes = new Steps; + Steps* pNewNotes = out.CreateSteps(); LoadFromDWITokens( sParams[0], sParams[1], diff --git a/src/NotesLoaderMidi.cpp b/src/NotesLoaderMidi.cpp index 6de736cabe..a74b3610a8 100644 --- a/src/NotesLoaderMidi.cpp +++ b/src/NotesLoaderMidi.cpp @@ -877,7 +877,7 @@ skip_track: } } - Steps *pSteps = new Steps; + Steps *pSteps = songOut.CreateSteps(); pSteps->m_StepsType = StepsType_guitar_five; pSteps->SetDifficulty( (Difficulty)(gd+1) ); pSteps->SetNoteData( noteData ); diff --git a/src/NotesLoaderPMS.cpp b/src/NotesLoaderPMS.cpp index 08f8efbb79..b733aa3d9f 100644 --- a/src/NotesLoaderPMS.cpp +++ b/src/NotesLoaderPMS.cpp @@ -843,7 +843,7 @@ bool PMSLoader::LoadFromDir( const RString &sDir, Song &out ) /* Create a Steps for each. */ vector apSteps; for( unsigned i=0; iCreateSteps(); LoadFromSMTokens( sParams[1], sParams[2], sParams[3], sParams[4], sParams[5], sParams[6], *pNewNotes); diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index dd6ce2c60f..93dcb65095 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -360,7 +360,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) continue; } - Steps* pNewNotes = new Steps; + Steps* pNewNotes = out.CreateSteps(); LoadFromSMATokens( sParams[1], sParams[2], @@ -702,7 +702,7 @@ bool SMALoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat if( !bAddStepsToSong ) return true; - Steps* pNewNotes = new Steps; + Steps* pNewNotes = pSong->CreateSteps(); LoadFromSMATokens( sParams[1], sParams[2], sParams[3], sParams[4], sParams[5], sParams[6], *pNewNotes); diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index a2308e9fd2..59483ee25f 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -686,7 +686,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach else if( sValueName=="NOTEDATA" ) { state = GETTING_STEP_INFO; - pNewNotes = new Steps; + pNewNotes = out.CreateSteps(); } break; } @@ -957,7 +957,7 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat else if( sValueName=="NOTEDATA" ) { - pNewNotes = new Steps; + pNewNotes = pSong->CreateSteps(); bSSCFormat = true; } if( sValueName=="STEPSTYPE" ) @@ -1062,7 +1062,7 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat } else { - pNewNotes = new Steps; + pNewNotes = pSong->CreateSteps(); SMLoader::LoadFromSMTokens( sParams[1], sParams[2], sParams[3], sParams[4], sParams[5], sParams[6], *pNewNotes); diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 52e9c62ea0..49b057da6d 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3953,7 +3953,7 @@ void ScreenEdit::RevertFromDisk() // put a blank Steps in its place. Note that this does not have to be the // work of someone maliciously changing the simfile; it could happen to // someone editing a new stepchart and reverting from disk, for example. - pNewSteps = new Steps(); + pNewSteps = GAMESTATE->m_pCurSong->CreateSteps(); pNewSteps->CreateBlank( id.GetStepsType() ); pNewSteps->SetDifficulty( id.GetDifficulty() ); GAMESTATE->m_pCurSong->AddSteps( pNewSteps ); From 6162fe519b7ddb6601a067af5e587e81c4e34309 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 9 May 2011 23:00:29 +0700 Subject: [PATCH 007/197] [splittiming] ArrowEffects and ScreenGameplay (222) --- src/ArrowEffects.cpp | 2 +- src/ScreenGameplay.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 7df7a37015..ffb21ae3d8 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -231,7 +231,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f ) { float fSongSeconds = GAMESTATE->m_fMusicSecondsVisible; - float fNoteSeconds = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat(fNoteBeat); + float fNoteSeconds = GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing.GetElapsedTimeFromBeat(fNoteBeat); float fSecondsUntilStep = fNoteSeconds - fSongSeconds; float fBPM = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollBPM; float fBPS = fBPM/60.f; diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index 814093883a..1ac4b6d8c5 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -1325,7 +1325,7 @@ void ScreenGameplay::StartPlayingSong( float fMinTimeToNotes, float fMinTimeToMu { const float fFirstBeat = GAMESTATE->m_pCurSong->m_fFirstBeat; - const float fFirstSecond = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat( fFirstBeat ); + const float fFirstSecond = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( fFirstBeat ); float fStartDelay = fMinTimeToNotes - fFirstSecond; fStartDelay = max( fStartDelay, fMinTimeToMusic ); p.m_StartSecond = -fStartDelay; From 71bf72e964b375481701332c0323e2bee17c2a7a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 20:48:23 -0400 Subject: [PATCH 008/197] [splittiming] More error fixes. (153) Nothing has been tied to the steps yet. --- src/NotesLoaderBMS.cpp | 12 ++++----- src/NotesLoaderKSF.cpp | 24 +++++++++--------- src/NotesLoaderMidi.cpp | 4 +-- src/NotesLoaderPMS.cpp | 12 ++++----- src/NotesLoaderSMA.cpp | 4 +-- src/NotesLoaderSSC.cpp | 26 ++++++++++---------- src/NotesWriterSSC.cpp | 54 ++++++++++++++++++++--------------------- 7 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/NotesLoaderBMS.cpp b/src/NotesLoaderBMS.cpp index 4a95e85d57..9eb58168ed 100644 --- a/src/NotesLoaderBMS.cpp +++ b/src/NotesLoaderBMS.cpp @@ -799,7 +799,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur if( PREFSMAN->m_bQuirksMode ) { BPMSegment newSeg( 0, fBPM ); - out.AddBPMSegment( newSeg ); + out.m_SongTiming.AddBPMSegment( newSeg ); if( fBPM > 0.0f ) LOG->Trace( "Inserting new positive BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM ); else @@ -810,7 +810,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur if( fBPM > 0.0f ) { BPMSegment newSeg( 0, fBPM ); - out.AddBPMSegment( newSeg ); + out.m_SongTiming.AddBPMSegment( newSeg ); LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM ); } else @@ -901,7 +901,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur case BMS_TRACK_BPM: if( iVal > 0 ) { - out.SetBPMAtBeat( fBeat, (float) iVal ); + out.m_SongTiming.SetBPMAtBeat( fBeat, (float) iVal ); LOG->Trace( "Inserting new BPM change at beat %f, BPM %i", fBeat, iVal ); } else @@ -918,7 +918,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur if( GetTagFromMap( mapNameToData, sTagToLookFor, sBPM ) ) { float fBPM = StringToFloat( sBPM ); - out.SetBPMAtBeat( fBeat, fBPM ); + out.m_SongTiming.SetBPMAtBeat( fBeat, fBPM ); } else { @@ -937,12 +937,12 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur if( GetTagFromMap( mapNameToData, sTagToLookFor, sBeats ) ) { // find the BPM at the time of this freeze - float fBPS = out.m_Timing.GetBPMAtBeat(fBeat) / 60.0f; + float fBPS = out.m_SongTiming.GetBPMAtBeat(fBeat) / 60.0f; float fBeats = StringToFloat( sBeats ) / 48.0f; float fFreezeSecs = fBeats / fBPS; StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs ); - out.AddStopSegment( newSeg ); + out.m_SongTiming.AddStopSegment( newSeg ); LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.m_fStopSeconds ); } else diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index b1732cdf81..14e6b4bca7 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -358,7 +358,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant else if( sValueName=="BPM" ) { BPM1 = StringToFloat(sParams[1]); - out.AddBPMSegment( BPMSegment(0, BPM1) ); + out.m_SongTiming.AddBPMSegment( BPMSegment(0, BPM1) ); } else if( sValueName=="BPM2" ) { @@ -383,7 +383,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant else if( sValueName=="STARTTIME" ) { SMGap1 = -StringToFloat( sParams[1] )/100; - out.m_Timing.m_fBeat0OffsetInSeconds = SMGap1; + out.m_SongTiming.m_fBeat0OffsetInSeconds = SMGap1; } // This is currently required for more accurate KIU BPM changes. else if( sValueName=="STARTTIME2" ) @@ -409,7 +409,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant TickcountSegment tcs; tcs.m_iStartRow = BeatToNoteRow(0.0f); tcs.m_iTicks = iTickCount > ROWS_PER_BEAT ? ROWS_PER_BEAT : iTickCount; - out.m_Timing.AddTickcountSegment( tcs ); + out.m_SongTiming.AddTickcountSegment( tcs ); } else if ( sValueName=="STEP" ) { @@ -469,7 +469,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant const float beat = (BPMPos2 + SMGap1) * BeatsPerSecond; LOG->Trace( "BPM %f, BPS %f, BPMPos2 %f, beat %f", BPM1, BeatsPerSecond, BPMPos2, beat ); - out.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM2) ); + out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM2) ); } if( BPM3 > 0 && BPMPos3 > 0 ) @@ -479,7 +479,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant const float beat = (BPMPos3 + SMGap2) * BeatsPerSecond; LOG->Trace( "BPM %f, BPS %f, BPMPos3 %f, beat %f", BPM2, BeatsPerSecond, BPMPos3, beat ); - out.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM3) ); + out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM3) ); } } else @@ -515,7 +515,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant TickcountSegment tcs; tcs.m_iStartRow = BeatToNoteRow(fCurBeat); tcs.m_iTicks = iTickCount > ROWS_PER_BEAT ? ROWS_PER_BEAT : iTickCount; - out.m_Timing.AddTickcountSegment( tcs ); + out.m_SongTiming.AddTickcountSegment( tcs ); continue; } @@ -523,22 +523,22 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant { float fCurBpm = (float)numTemp; //out.m_Timing.AddBPMSegment( BPMSegment( BeatToNoteRow(fCurBeat), (float)numTemp ) ); - out.m_Timing.SetBPMAtBeat( fCurBeat, fCurBpm ); + out.m_SongTiming.SetBPMAtBeat( fCurBeat, fCurBpm ); continue; } else if (BeginsWith(NoteRowString, "|E")) { // Finally! the |E| tag is working as it should. I can die happy now -DaisuMaster - float fCurDelay = 60 / out.m_Timing.GetBPMAtBeat(fCurBeat) * (float)numTemp / iTickCount; - fCurDelay += out.m_Timing.GetStopAtRow(BeatToNoteRow(fCurBeat) ); - out.m_Timing.SetStopAtBeat( fCurBeat, fCurDelay, true ); + float fCurDelay = 60 / out.m_SongTiming.GetBPMAtBeat(fCurBeat) * (float)numTemp / iTickCount; + fCurDelay += out.m_SongTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) ); + out.m_SongTiming.SetStopAtBeat( fCurBeat, fCurDelay, true ); continue; } else if (BeginsWith(NoteRowString, "|D")) { - float fCurDelay = out.m_Timing.GetStopAtRow(BeatToNoteRow(fCurBeat) ); + float fCurDelay = out.m_SongTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) ); fCurDelay += (float)numTemp / 1000; - out.m_Timing.SetStopAtBeat( fCurBeat, fCurDelay, true ); + out.m_SongTiming.SetStopAtBeat( fCurBeat, fCurDelay, true ); continue; } } diff --git a/src/NotesLoaderMidi.cpp b/src/NotesLoaderMidi.cpp index a74b3610a8..ef354d7bfe 100644 --- a/src/NotesLoaderMidi.cpp +++ b/src/NotesLoaderMidi.cpp @@ -682,7 +682,7 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut ) double fSecondsPerBeat = (iter->tickSeconds * GUITAR_MIDI_COUNTS_PER_BEAT); bpmSeg.m_fBPS = float( 1. / fSecondsPerBeat ); - songOut.m_Timing.AddBPMSegment( bpmSeg ); + songOut.m_SongTiming.AddBPMSegment( bpmSeg ); } FOREACH_CONST( MidiFileIn::TimeSignatureChange, midi.timeSignatureEvents_, iter ) @@ -692,7 +692,7 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut ) seg.m_iNumerator = iter->numerator; seg.m_iDenominator = iter->denominator; - songOut.m_Timing.AddTimeSignatureSegment( seg ); + songOut.m_SongTiming.AddTimeSignatureSegment( seg ); } diff --git a/src/NotesLoaderPMS.cpp b/src/NotesLoaderPMS.cpp index b733aa3d9f..44a125e1cb 100644 --- a/src/NotesLoaderPMS.cpp +++ b/src/NotesLoaderPMS.cpp @@ -591,7 +591,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur if( fBPM > 0.0f ) { BPMSegment newSeg( 0, fBPM ); - out.AddBPMSegment( newSeg ); + out.m_SongTiming.AddBPMSegment( newSeg ); LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM ); } else @@ -673,7 +673,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur case PMS_TRACK_BPM: if( iVal > 0 ) { - out.SetBPMAtBeat( fBeat, (float) iVal ); + out.m_SongTiming.SetBPMAtBeat( fBeat, (float) iVal ); LOG->Trace( "Inserting new BPM change at beat %f, BPM %i", fBeat, iVal ); } else @@ -694,7 +694,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur if( fBPM > 0.0f ) { BPMSegment newSeg( BeatToNoteRow(fBeat), fBPM ); - out.AddBPMSegment( newSeg ); + out.m_SongTiming.AddBPMSegment( newSeg ); LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", fBeat, newSeg.GetBPM() ); } else @@ -716,12 +716,12 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur if( GetTagFromMap( mapNameToData, sTagToLookFor, sBeats ) ) { // find the BPM at the time of this freeze - float fBPS = out.m_Timing.GetBPMAtBeat(fBeat) / 60.0f; + float fBPS = out.m_SongTiming.GetBPMAtBeat(fBeat) / 60.0f; float fBeats = StringToFloat( sBeats ) / 48.0f; float fFreezeSecs = fBeats / fBPS; StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs ); - out.AddStopSegment( newSeg ); + out.m_SongTiming.AddStopSegment( newSeg ); LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.m_fStopSeconds ); } else @@ -750,7 +750,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur if( fBPM > 0.0f ) { BPMSegment newSeg( iStepIndex, fBPM ); - out.AddBPMSegment( newSeg ); + out.m_SongTiming.AddBPMSegment( newSeg ); LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(newSeg.m_iStartRow), newSeg.GetBPM() ); } diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 93dcb65095..1fa083136d 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -113,8 +113,8 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) return false; } - out.m_Timing.m_sFile = sPath; - LoadTimingFromSMAFile( msd, out.m_Timing ); + out.m_SongTiming.m_sFile = sPath; + LoadTimingFromSMAFile( msd, out.m_SongTiming ); for( unsigned i=0; i 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 ); + out.m_SongTiming.AddStopSegment( new_seg ); } else { @@ -420,7 +420,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach 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 ); + out.m_SongTiming.AddStopSegment( new_seg ); } else LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid stop at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); @@ -452,7 +452,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach // 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 ); + out.m_SongTiming.AddStopSegment( new_seg ); else LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); } @@ -479,13 +479,13 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); if(fNewBPM > 0.0f) - out.m_Timing.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); + out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); else { - out.m_Timing.m_bHasNegativeBpms = true; + out.m_SongTiming.m_bHasNegativeBpms = true; // only add Negative BPMs in quirks mode -aj if( PREFSMAN->m_bQuirksMode ) - out.m_Timing.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); + out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); else LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM ); } @@ -513,7 +513,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach const float fNewBeat = StringToFloat( arrayWarpValues[1] ); if(fNewBeat > fBeat) - out.m_Timing.AddWarpSegment( WarpSegment(fBeat, fNewBeat) ); + out.m_SongTiming.AddWarpSegment( WarpSegment(fBeat, fNewBeat) ); else { LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Warp at beat %f, BPM %f.", fBeat, fNewBeat ); @@ -541,7 +541,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach RString sLabel = arrayLabelValues[1]; TrimRight(sLabel); if( fBeat >= 0.0f ) - out.m_Timing.AddLabelSegment( LabelSegment(fBeat, sLabel) ); + out.m_SongTiming.AddLabelSegment( LabelSegment(fBeat, sLabel) ); else { LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Label at beat %f called %s.", fBeat, sLabel.c_str() ); @@ -591,7 +591,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach continue; } - out.m_Timing.AddTimeSignatureSegment( seg ); + out.m_SongTiming.AddTimeSignatureSegment( seg ); } } @@ -619,7 +619,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach 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 ); + out.m_SongTiming.AddTickcountSegment( new_seg ); } else { @@ -646,7 +646,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach const float fComboBeat = StringToFloat( arrayComboValues[0] ); const int iCombos = atoi( arrayComboValues[1] ); ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos ); - out.m_Timing.AddComboSegment( new_seg ); + out.m_SongTiming.AddComboSegment( new_seg ); } } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 69ca696756..3c4ff71a3b 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -74,7 +74,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) f.PutLine( "#INSTRUMENTTRACK:" + s + ";\n" ); } } - f.PutLine( ssprintf( "#OFFSET:%.6f;", out.m_Timing.m_fBeat0OffsetInSeconds ) ); + f.PutLine( ssprintf( "#OFFSET:%.6f;", out.m_SongTiming.m_fBeat0OffsetInSeconds ) ); f.PutLine( ssprintf( "#SAMPLESTART:%.6f;", out.m_fMusicSampleStartSeconds ) ); f.PutLine( ssprintf( "#SAMPLELENGTH:%.6f;", out.m_fMusicSampleLengthSeconds ) ); if( out.m_fSpecifiedLastBeat > 0 ) @@ -107,39 +107,39 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) } f.Write( "#BPMS:" ); - for( unsigned i=0; im_iStartRow), iter->m_iNumerator, iter->m_iDenominator ) ); vector::const_iterator iter2 = iter; iter2++; - if( iter2 != out.m_Timing.m_vTimeSignatureSegments.end() ) + if( iter2 != out.m_SongTiming.m_vTimeSignatureSegments.end() ) f.Write( "," ); } f.PutLine( ";" ); - ASSERT( !out.m_Timing.m_TickcountSegments.empty() ); + ASSERT( !out.m_SongTiming.m_TickcountSegments.empty() ); f.Write( "#TICKCOUNTS:" ); - for( unsigned i=0; i Date: Mon, 9 May 2011 21:03:30 -0400 Subject: [PATCH 009/197] [splittiming] Bringing it down. (91) --- src/AdjustSync.cpp | 24 ++++++++++++------------ src/Background.cpp | 6 +++--- src/GameplayAssist.cpp | 2 +- src/MeterDisplay.cpp | 4 ++-- src/NoteField.cpp | 18 +++++++++--------- src/Player.cpp | 24 ++++++++++++------------ src/ScoreKeeperNormal.cpp | 4 ++-- src/ScreenGameplay.cpp | 2 +- src/ScreenSelectMusic.cpp | 2 +- src/Song.cpp | 32 ++++++++++++++++---------------- 10 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/AdjustSync.cpp b/src/AdjustSync.cpp index e669f9cb74..b375928a25 100644 --- a/src/AdjustSync.cpp +++ b/src/AdjustSync.cpp @@ -58,7 +58,7 @@ void AdjustSync::ResetOriginalSyncData() s_pTimingDataOriginal = new TimingData; if( GAMESTATE->m_pCurSong ) - *s_pTimingDataOriginal = GAMESTATE->m_pCurSong->m_Timing; + *s_pTimingDataOriginal = GAMESTATE->m_pCurSong->m_SongTiming; else *s_pTimingDataOriginal = TimingData(); s_fGlobalOffsetSecondsOriginal = PREFSMAN->m_fGlobalOffsetSeconds; @@ -87,7 +87,7 @@ void AdjustSync::SaveSyncChanges() { if( GAMESTATE->IsCourseMode() ) return; - if( GAMESTATE->m_pCurSong && *s_pTimingDataOriginal != GAMESTATE->m_pCurSong->m_Timing ) + if( GAMESTATE->m_pCurSong && *s_pTimingDataOriginal != GAMESTATE->m_pCurSong->m_SongTiming ) { if( GAMESTATE->IsEditing() ) { @@ -110,7 +110,7 @@ void AdjustSync::RevertSyncChanges() if( GAMESTATE->IsCourseMode() ) return; PREFSMAN->m_fGlobalOffsetSeconds.Set( s_fGlobalOffsetSecondsOriginal ); - GAMESTATE->m_pCurSong->m_Timing = *s_pTimingDataOriginal; + GAMESTATE->m_pCurSong->m_SongTiming = *s_pTimingDataOriginal; ResetOriginalSyncData(); s_fStandardDeviation = 0.0f; s_fAverageError = 0.0f; @@ -186,7 +186,7 @@ void AdjustSync::AutosyncOffset() switch( GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType ) { case SongOptions::AUTOSYNC_SONG: - GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += mean; + GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += mean; break; case SongOptions::AUTOSYNC_MACHINE: PREFSMAN->m_fGlobalOffsetSeconds.Set( PREFSMAN->m_fGlobalOffsetSeconds + mean ); @@ -232,15 +232,15 @@ void AdjustSync::AutosyncTempo() if( !CalcLeastSquares( s_vAutosyncTempoData, fSlope, fIntercept, fFilteredError ) ) return; - GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += fIntercept; + GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fIntercept; const float fScaleBPM = 1.0f/(1.0f - fSlope); - FOREACH( BPMSegment, GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments, i ) + FOREACH( BPMSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments, i ) i->SetBPM( i->GetBPM() * fScaleBPM ); // We assume that the stops were measured as a number of beats. // Therefore, if we change the bpms, we need to make a similar // change to the stops. - FOREACH( StopSegment, GAMESTATE->m_pCurSong->m_Timing.m_StopSegments, i ) + FOREACH( StopSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments, i ) i->m_fStopSeconds *= 1.0f - fSlope; SCREENMAN->SystemMessage( AUTOSYNC_CORRECTION_APPLIED.GetValue() ); @@ -296,7 +296,7 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo ) { float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_fBeat0OffsetInSeconds, 0.001f ); - float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds, 0.001f ); + float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds, 0.001f ); float fDelta = fNew - fOld; if( fabsf(fDelta) > 0.0001f ) @@ -309,10 +309,10 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo ) } } - for( unsigned i=0; im_pCurSong->m_Timing.m_BPMSegments.size(); i++ ) + for( unsigned i=0; im_pCurSong->m_SongTiming.m_BPMSegments.size(); i++ ) { float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_BPMSegments[i].GetBPM(), 0.001f ); - float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments[i].GetBPM(), 0.001f ); + float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments[i].GetBPM(), 0.001f ); float fDelta = fNew - fOld; if( fabsf(fDelta) > 0.0001f ) @@ -330,10 +330,10 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo ) } } - for( unsigned i=0; im_pCurSong->m_Timing.m_StopSegments.size(); i++ ) + for( unsigned i=0; im_pCurSong->m_SongTiming.m_StopSegments.size(); i++ ) { float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_StopSegments[i].m_fStopSeconds, 0.001f ); - float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_StopSegments[i].m_fStopSeconds, 0.001f ); + float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds, 0.001f ); float fDelta = fNew - fOld; if( fabsf(fDelta) > 0.0001f ) diff --git a/src/Background.cpp b/src/Background.cpp index 34050aedcc..5047e5fc1e 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -419,7 +419,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac int iStartRow = BeatToNoteRow(fFirstBeat); int iEndRow = BeatToNoteRow(fEndBeat); - const TimingData &timing = m_pSong->m_Timing; + const TimingData &timing = m_pSong->m_SongTiming; // change BG every time signature change or 4 measures FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter ) @@ -697,7 +697,7 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus float fBeat, fBPS, fThrowAway; bool bFreeze; int iThrowAway; - pSong->m_Timing.GetBeatAndBPSFromElapsedTime( fCurrentTime, fBeat, fBPS, bFreeze, bFreeze, iThrowAway, fThrowAway ); + pSong->m_SongTiming.GetBeatAndBPSFromElapsedTime( fCurrentTime, fBeat, fBPS, bFreeze, bFreeze, iThrowAway, fThrowAway ); // Calls to Update() should *not* be scaled by music rate; fCurrentTime is. Undo it. const float fRate = GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; @@ -762,7 +762,7 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus m_pCurrentBGA->PlayCommand( "GainFocus" ); /* How much time of this BGA have we skipped? (This happens with SetSeconds.) */ - const float fStartSecond = pSong->m_Timing.GetElapsedTimeFromBeat( change.m_fStartBeat ); + const float fStartSecond = pSong->m_SongTiming.GetElapsedTimeFromBeat( change.m_fStartBeat ); /* This is affected by the music rate. */ fDeltaTime = fCurrentTime - fStartSecond; diff --git a/src/GameplayAssist.cpp b/src/GameplayAssist.cpp index 7531c77e43..97a324416d 100644 --- a/src/GameplayAssist.cpp +++ b/src/GameplayAssist.cpp @@ -27,7 +27,7 @@ void GameplayAssist::PlayTicks( const NoteData &nd ) * come out on time; the actual precise timing is handled by SetStartTime. */ float fPositionSeconds = GAMESTATE->m_fMusicSeconds; fPositionSeconds += SOUNDMAN->GetPlayLatency() + (float)CommonMetrics::TICK_EARLY_SECONDS + 0.250f; - const TimingData &timing = GAMESTATE->m_pCurSong->m_Timing; + const TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming; const float fSongBeat = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); const int iSongRow = max( 0, BeatToNoteRowNotRounded( fSongBeat ) ); diff --git a/src/MeterDisplay.cpp b/src/MeterDisplay.cpp index 3018125cd1..66c0b19587 100644 --- a/src/MeterDisplay.cpp +++ b/src/MeterDisplay.cpp @@ -73,8 +73,8 @@ void SongMeterDisplay::Update( float fDeltaTime ) { if( GAMESTATE->m_pCurSong ) { - float fSongStartSeconds = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fFirstBeat ); - float fSongEndSeconds = GAMESTATE->m_pCurSong->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat ); + float fSongStartSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fFirstBeat ); + float fSongEndSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat ); float fPercentPositionSong = SCALE( GAMESTATE->m_fMusicSeconds, fSongStartSeconds, fSongEndSeconds, 0.0f, 1.0f ); CLAMP( fPercentPositionSong, 0, 1 ); diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 6895b07234..213d5e1e09 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -742,7 +742,7 @@ void NoteField::DrawPrimitives() // Draw beat bars if( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) { - const vector &vTimeSignatureSegments = GAMESTATE->m_pCurSong->m_Timing.m_vTimeSignatureSegments; + const vector &vTimeSignatureSegments = GAMESTATE->m_pCurSong->m_SongTiming.m_vTimeSignatureSegments; int iMeasureIndex = 0; FOREACH_CONST( TimeSignatureSegment, vTimeSignatureSegments, iter ) { @@ -786,7 +786,7 @@ void NoteField::DrawPrimitives() ASSERT(GAMESTATE->m_pCurSong); // BPM text - FOREACH_CONST( BPMSegment, GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments, seg ) + FOREACH_CONST( BPMSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -797,7 +797,7 @@ void NoteField::DrawPrimitives() } // Freeze text - FOREACH_CONST( StopSegment, GAMESTATE->m_pCurSong->m_Timing.m_StopSegments, seg ) + FOREACH_CONST( StopSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -808,7 +808,7 @@ void NoteField::DrawPrimitives() } // Warp text - FOREACH_CONST( WarpSegment, GAMESTATE->m_pCurSong->m_Timing.m_WarpSegments, seg ) + FOREACH_CONST( WarpSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_WarpSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -819,7 +819,7 @@ void NoteField::DrawPrimitives() } // Time Signature text - FOREACH_CONST( TimeSignatureSegment, GAMESTATE->m_pCurSong->m_Timing.m_vTimeSignatureSegments, seg ) + FOREACH_CONST( TimeSignatureSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_vTimeSignatureSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -830,7 +830,7 @@ void NoteField::DrawPrimitives() } // Tickcount text - FOREACH_CONST( TickcountSegment, GAMESTATE->m_pCurSong->m_Timing.m_TickcountSegments, seg ) + FOREACH_CONST( TickcountSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_TickcountSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -841,7 +841,7 @@ void NoteField::DrawPrimitives() } // Combo text - FOREACH_CONST( ComboSegment, GAMESTATE->m_pCurSong->m_Timing.m_ComboSegments, seg ) + FOREACH_CONST( ComboSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_ComboSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -852,7 +852,7 @@ void NoteField::DrawPrimitives() } // Label text - FOREACH_CONST( LabelSegment, GAMESTATE->m_pCurSong->m_Timing.m_LabelSegments, seg ) + FOREACH_CONST( LabelSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_LabelSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -872,7 +872,7 @@ void NoteField::DrawPrimitives() FOREACH_CONST( Attack, ce.attacks, a ) { float fSecond = a->fStartSecond; - float fBeat = GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTime( fSecond ); + float fBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fSecond ); if( BeatToNoteRow(fBeat) >= iFirstRowToDraw && BeatToNoteRow(fBeat) <= iLastRowToDraw) diff --git a/src/Player.cpp b/src/Player.cpp index 570112bb0e..caa30e5c92 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -1528,7 +1528,7 @@ int Player::GetClosestNoteDirectional( int col, int iStartRow, int iEndRow, bool // Is this the row we want? do { const TapNote &tn = begin->second; - if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( begin->first ) ) + if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( begin->first ) ) break; if( tn.type == TapNote::empty ) break; @@ -1579,7 +1579,7 @@ int Player::GetClosestNonEmptyRowDirectional( int iStartRow, int iEndRow, bool b ++iter; continue; } - if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iter.Row() ) ) + if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iter.Row() ) ) { ++iter; continue; @@ -2011,8 +2011,8 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b * "jack hammers." Hmm. */ const int iStepSearchRows = max( - BeatToNoteRow( GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds + StepSearchDistance ) ) - iSongRow, - iSongRow - BeatToNoteRow( GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds - StepSearchDistance ) ) + BeatToNoteRow( GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds + StepSearchDistance ) ) - iSongRow, + iSongRow - BeatToNoteRow( GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds - StepSearchDistance ) ) ) + ROWS_PER_BEAT; int iRowOfOverlappingNoteOrRow = row; if( row == -1 ) @@ -2089,7 +2089,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b // Stepped too close to mine? if( !bRelease && ( REQUIRE_STEP_ON_MINES == !bHeld ) && fSecondsFromExact <= GetWindowSeconds(TW_Mine) && - !GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow(iSongRow) ) + !GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow(iSongRow) ) score = TNS_HitMine; break; @@ -2564,7 +2564,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) float fThrowAway; int iWarpBeginRow; float fWarpLength; - GAMESTATE->m_pCurSong->m_Timing.GetBeatAndBPSFromElapsedTime( fEarliestTime, fMissIfOlderThanThisBeat, fThrowAway, bFreeze, bDelay, iWarpBeginRow, fWarpLength ); + GAMESTATE->m_pCurSong->m_SongTiming.GetBeatAndBPSFromElapsedTime( fEarliestTime, fMissIfOlderThanThisBeat, fThrowAway, bFreeze, bDelay, iWarpBeginRow, fWarpLength ); iMissIfOlderThanThisRow = BeatToNoteRow( fMissIfOlderThanThisBeat ); if( bFreeze || bDelay ) @@ -2587,7 +2587,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) continue; // Ignore all notes that are skipped via WARPS. - if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iter.Row() ) ) + if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iter.Row() ) ) continue; if( tn.type == TapNote::mine ) @@ -2622,7 +2622,7 @@ void Player::UpdateJudgedRows() int iRow = iter.Row(); // If row is within a warp section, ignore it. -aj - if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow(iRow) ) + if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow(iRow) ) continue; if( iLastSeenRow != iRow ) @@ -2843,13 +2843,13 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now ) int iCheckpointFrequencyRows = ROWS_PER_BEAT/2; if( CHECKPOINTS_USE_TICKCOUNTS ) { - int tickCurrent = GAMESTATE->m_pCurSong->m_Timing.GetTickcountAtRow( iLastRowCrossed ); + int tickCurrent = GAMESTATE->m_pCurSong->m_SongTiming.GetTickcountAtRow( iLastRowCrossed ); // There are some charts that don't want tickcounts involved at all. iCheckpointFrequencyRows = (tickCurrent > 0 ? ROWS_PER_BEAT / tickCurrent : 0); } else if( CHECKPOINTS_USE_TIME_SIGNATURES ) { - TimeSignatureSegment tSignature = GAMESTATE->m_pCurSong->m_Timing.GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) ); + TimeSignatureSegment tSignature = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) ); // Most songs are in 4/4 time. The frequency for checking tick counts should reflect that. iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.m_iDenominator / (tSignature.m_iNumerator * 4); @@ -2957,7 +2957,7 @@ void Player::HandleTapRowScore( unsigned row ) #endif // Warp hackery. -aj - if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( row ) ) + if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( row ) ) return; if( GAMESTATE->m_bDemonstrationOrJukebox ) @@ -3061,7 +3061,7 @@ void Player::HandleHoldCheckpoint( int iRow, int iNumHoldsHeldThisRow, int iNumH #endif // More warp hackery. -aj - if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iRow ) ) + if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iRow ) ) return; // don't accumulate combo if AutoPlay is on. diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index b3e106bfaf..36c405501e 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -443,7 +443,7 @@ void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumH if( iNumBreakCombo == 0 ) { - TimingData td = GAMESTATE->m_pCurSong->m_Timing; + TimingData td = GAMESTATE->m_pCurSong->m_SongTiming; int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo ); m_pPlayerStageStats->m_iCurCombo += iNumHitContinueCombo * multiplier; } @@ -463,7 +463,7 @@ void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsIn if ( tns >= m_MinScoreToContinueCombo ) { m_pPlayerStageStats->m_iCurMissCombo = 0; - TimingData td = GAMESTATE->m_pCurSong->m_Timing; + TimingData td = GAMESTATE->m_pCurSong->m_SongTiming; int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo ); m_pPlayerStageStats->m_iCurCombo += iNumTapsInRow * multiplier; } diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index 1ac4b6d8c5..1a603c7046 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -1423,7 +1423,7 @@ void ScreenGameplay::UpdateSongPosition( float fDeltaTime ) RageTimer tm; const float fSeconds = m_pSoundMusic->GetPositionSeconds( NULL, &tm ); const float fAdjust = SOUND->GetFrameTimingAdjustment( fDeltaTime ); - GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, GAMESTATE->m_pCurSong->m_Timing, tm+fAdjust ); + GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, GAMESTATE->m_pCurSong->m_SongTiming, tm+fAdjust ); } void ScreenGameplay::BeginScreen() diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index fe4aee3aab..4ecb227b3b 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -1763,7 +1763,7 @@ void ScreenSelectMusic::AfterMusicChange() case SampleMusicPreviewMode_LastSong: // fall through // play the sample music m_sSampleMusicToPlay = pSong->GetMusicPath(); - m_pSampleMusicTimingData = &pSong->m_Timing; + m_pSampleMusicTimingData = &pSong->m_SongTiming; m_fSampleStartSeconds = pSong->m_fMusicSampleStartSeconds; m_fSampleLengthSeconds = pSong->m_fMusicSampleLengthSeconds; break; diff --git a/src/Song.cpp b/src/Song.cpp index 6d9022177b..b8882a5ef2 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -167,7 +167,7 @@ void Song::GetDisplayBpms( DisplayBpms &AddTo ) const else { float fMinBPM, fMaxBPM; - m_Timing.GetActualBPM( fMinBPM, fMaxBPM ); + m_SongTiming.GetActualBPM( fMinBPM, fMaxBPM ); AddTo.Add( fMinBPM ); AddTo.Add( fMaxBPM ); } @@ -488,16 +488,16 @@ void Song::TidyUpData() m_sArtist = "Unknown artist"; TranslateTitles(); - if( m_Timing.m_BPMSegments.empty() ) + if( m_SongTiming.m_BPMSegments.empty() ) { LOG->UserLog( "Song file", m_sSongDir + m_sSongFileName, "has no BPM segments, default provided." ); - m_Timing.AddBPMSegment( BPMSegment(0, 60) ); + m_SongTiming.AddBPMSegment( BPMSegment(0, 60) ); } // Make sure the first BPM segment starts at beat 0. - if( m_Timing.m_BPMSegments[0].m_iStartRow != 0 ) - m_Timing.m_BPMSegments[0].m_iStartRow = 0; + if( m_SongTiming.m_BPMSegments[0].m_iStartRow != 0 ) + m_SongTiming.m_BPMSegments[0].m_iStartRow = 0; if( m_fMusicSampleStartSeconds == -1 || @@ -791,10 +791,10 @@ void Song::TidyUpData() } // If no time signature specified, assume 4/4 time for the whole song. - if( m_Timing.m_vTimeSignatureSegments.empty() ) + if( m_SongTiming.m_vTimeSignatureSegments.empty() ) { TimeSignatureSegment seg(0, 4, 4); - m_Timing.m_vTimeSignatureSegments.push_back( seg ); + m_SongTiming.m_vTimeSignatureSegments.push_back( seg ); } /* @@ -802,24 +802,24 @@ void Song::TidyUpData() * per beat for the entire song. The default of 2 is chosen more * for compatibility with the Pump Pro series than anything else. */ - if( m_Timing.m_TickcountSegments.empty() ) + if( m_SongTiming.m_TickcountSegments.empty() ) { TickcountSegment seg(0, 2); - m_Timing.m_TickcountSegments.push_back( seg ); + m_SongTiming.m_TickcountSegments.push_back( seg ); } // Have a default combo segment of one just in case. - if( m_Timing.m_ComboSegments.empty() ) + if( m_SongTiming.m_ComboSegments.empty() ) { ComboSegment seg(0, 1); - m_Timing.m_ComboSegments.push_back( seg ); + m_SongTiming.m_ComboSegments.push_back( seg ); } // Have a default label segment just in case. - if( m_Timing.m_LabelSegments.empty() ) + if( m_SongTiming.m_LabelSegments.empty() ) { LabelSegment seg(0, "Song Start"); - m_Timing.m_LabelSegments.push_back( seg ); + m_SongTiming.m_LabelSegments.push_back( seg ); } } @@ -1465,7 +1465,7 @@ bool Song::IsEditAlreadyLoaded( Steps* pSteps ) const bool Song::HasSignificantBpmChangesOrStops() const { - if( m_Timing.HasStops() ) + if( m_SongTiming.HasStops() ) return true; // Don't consider BPM changes that only are only for maintaining sync as @@ -1475,7 +1475,7 @@ bool Song::HasSignificantBpmChangesOrStops() const if( m_fSpecifiedBPMMin != m_fSpecifiedBPMMax ) return true; } - else if( m_Timing.HasBpmChanges() ) + else if( m_SongTiming.HasBpmChanges() ) { return true; } @@ -1568,7 +1568,7 @@ public: } static int GetTimingData( T* p, lua_State *L ) { - p->m_Timing.PushSelf(L); + p->m_SongTiming.PushSelf(L); return 1; } // has functions From 9cb41af5f4b1e349874f8e2d64b9ba79eed99845 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 21:11:33 -0400 Subject: [PATCH 010/197] [splittiming] All but ScreenEdit. (67) --- src/Attack.cpp | 12 +++++++----- src/AutoKeysounds.cpp | 2 +- src/Foreground.cpp | 6 +++--- src/GameSoundManager.cpp | 4 ++-- src/LyricDisplay.cpp | 2 +- src/NoteDataUtil.cpp | 4 ++-- src/Player.cpp | 4 ++-- src/ScreenGameplay.cpp | 6 +++--- src/ScreenHowToPlay.cpp | 2 +- src/ScreenSyncOverlay.cpp | 4 ++-- src/Song.cpp | 8 +++++--- 11 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/Attack.cpp b/src/Attack.cpp index a896944158..1a67cc3181 100644 --- a/src/Attack.cpp +++ b/src/Attack.cpp @@ -11,9 +11,10 @@ void Attack::GetAttackBeats( const Song *pSong, float &fStartBeat, float &fEndBe { ASSERT( pSong ); ASSERT_M( fStartSecond >= 0, ssprintf("StartSecond: %f",fStartSecond) ); - - fStartBeat = pSong->GetBeatFromElapsedTime( fStartSecond ); - fEndBeat = pSong->GetBeatFromElapsedTime( fStartSecond+fSecsRemaining ); + + const TimingData &timing = pSong->m_SongTiming; + fStartBeat = timing.GetBeatFromElapsedTime( fStartSecond ); + fEndBeat = timing.GetBeatFromElapsedTime( fStartSecond+fSecsRemaining ); } /* Get the range for an attack that's being applied in realtime, eg. during battle @@ -34,9 +35,10 @@ void Attack::GetRealtimeAttackBeats( const Song *pSong, const PlayerState* pPlay fStartBeat = min( GAMESTATE->m_fSongBeat+8, pPlayerState->m_fLastDrawnBeat ); fStartBeat = truncf(fStartBeat)+1; - const float lStartSecond = pSong->GetElapsedTimeFromBeat( fStartBeat ); + const TimingData &timing = pSong->m_SongTiming; + const float lStartSecond = timing.GetElapsedTimeFromBeat( fStartBeat ); const float fEndSecond = lStartSecond + fSecsRemaining; - fEndBeat = pSong->GetBeatFromElapsedTime( fEndSecond ); + fEndBeat = timing.GetBeatFromElapsedTime( fEndSecond ); fEndBeat = truncf(fEndBeat)+1; // loading the course should have caught this. diff --git a/src/AutoKeysounds.cpp b/src/AutoKeysounds.cpp index 5aac67976b..aba066200d 100644 --- a/src/AutoKeysounds.cpp +++ b/src/AutoKeysounds.cpp @@ -99,7 +99,7 @@ void AutoKeysounds::LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain ) if( tn[pn].iKeysoundIndex >= 0 ) { RString sKeysoundFilePath = sSongDir + pSong->m_vsKeysoundFile[tn[pn].iKeysoundIndex]; - float fSeconds = pSong->m_Timing.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency(); + float fSeconds = pSong->m_SongTiming.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency(); float fPan = 0; if( !bSoundIsGlobal ) diff --git a/src/Foreground.cpp b/src/Foreground.cpp index 708fbcb608..54ba873d7e 100644 --- a/src/Foreground.cpp +++ b/src/Foreground.cpp @@ -41,9 +41,9 @@ void Foreground::LoadFromSong( const Song *pSong ) bga.m_fStartBeat = change.m_fStartBeat; bga.m_bFinished = false; - const float fStartSecond = pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat ); + const float fStartSecond = pSong->m_SongTiming.GetElapsedTimeFromBeat( bga.m_fStartBeat ); const float fStopSecond = fStartSecond + bga.m_bga->GetTweenTimeLeft(); - bga.m_fStopBeat = pSong->m_Timing.GetBeatFromElapsedTime( fStopSecond ); + bga.m_fStopBeat = pSong->m_SongTiming.GetBeatFromElapsedTime( fStopSecond ); bga.m_bga->SetVisible( false ); @@ -82,7 +82,7 @@ void Foreground::Update( float fDeltaTime ) bga.m_bga->SetVisible( true ); bga.m_bga->PlayCommand( "On" ); - const float fStartSecond = m_pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat ); + const float fStartSecond = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( bga.m_fStartBeat ); lDeltaTime = GAMESTATE->m_fMusicSeconds - fStartSecond; } else diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp index 5b3ba858de..6e517249fb 100644 --- a/src/GameSoundManager.cpp +++ b/src/GameSoundManager.cpp @@ -146,7 +146,7 @@ static void StartMusic( MusicToPlay &ToPlay ) SSCLoader::LoadFromSSCFile(ToPlay.m_sTimingFile, song) ) { ToPlay.HasTiming = true; - ToPlay.m_TimingData = song.m_Timing; + ToPlay.m_TimingData = song.m_SongTiming; // get cabinet lights if any Steps *pStepsCabinetLights = SongUtil::GetOneSteps( &song, StepsType_lights_cabinet ); if( pStepsCabinetLights ) @@ -156,7 +156,7 @@ static void StartMusic( MusicToPlay &ToPlay ) SMLoader::LoadFromSMFile(ToPlay.m_sTimingFile, song) ) { ToPlay.HasTiming = true; - ToPlay.m_TimingData = song.m_Timing; + ToPlay.m_TimingData = song.m_SongTiming; // get cabinet lights if any Steps *pStepsCabinetLights = SongUtil::GetOneSteps( &song, StepsType_lights_cabinet ); if( pStepsCabinetLights ) diff --git a/src/LyricDisplay.cpp b/src/LyricDisplay.cpp index 27263d068c..fec9827e34 100644 --- a/src/LyricDisplay.cpp +++ b/src/LyricDisplay.cpp @@ -59,7 +59,7 @@ void LyricDisplay::Update( float fDeltaTime ) if( m_iCurLyricNumber+1 < GAMESTATE->m_pCurSong->m_LyricSegments.size() ) fEndTime = pSong->m_LyricSegments[m_iCurLyricNumber+1].m_fStartTime; else - fEndTime = pSong->GetElapsedTimeFromBeat( pSong->m_fLastBeat ); + fEndTime = pSong->m_SongTiming.GetElapsedTimeFromBeat( pSong->m_fLastBeat ); const float fDistance = fEndTime - pSong->m_LyricSegments[m_iCurLyricNumber].m_fStartTime; const float fTweenBufferTime = IN_LENGTH.GetValue() + OUT_LENGTH.GetValue(); diff --git a/src/NoteDataUtil.cpp b/src/NoteDataUtil.cpp index 6b7f47cba1..413fd3a425 100644 --- a/src/NoteDataUtil.cpp +++ b/src/NoteDataUtil.cpp @@ -2215,7 +2215,7 @@ void NoteDataUtil::AddTapAttacks( NoteData &nd, Song* pSong ) for( float sec=15; secm_fMusicLengthSeconds; sec+=30 ) { - float fBeat = pSong->GetBeatFromElapsedTime( sec ); + float fBeat = pSong->m_SongTiming.GetBeatFromElapsedTime( sec ); int iBeat = (int)fBeat; int iTrack = iBeat % nd.GetNumTracks(); // deterministically calculates track TapNote tn( @@ -2448,7 +2448,7 @@ void NoteDataUtil::SetHopoPossibleFlags( const Song *pSong, NoteData& ndInOut ) FOREACH_NONEMPTY_ROW_ALL_TRACKS( ndInOut, r ) { float fBeat = NoteRowToBeat( r ); - float fSeconds = pSong->GetElapsedTimeFromBeat( fBeat ); + float fSeconds = pSong->m_SongTiming.GetElapsedTimeFromBeat( fBeat ); int iLastTapTrack = ndInOut.GetLastTrackWithTapOrHoldHead( r ); if( iLastTapTrack != -1 && fSeconds <= fLastRowMusicSeconds + g_fTimingWindowHopo ) diff --git a/src/Player.cpp b/src/Player.cpp index caa30e5c92..2c793bb4c1 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -1873,7 +1873,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b break; } - const float fSongBeat = GAMESTATE->m_pCurSong ? GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds ) : GAMESTATE->m_fSongBeat; + const float fSongBeat = GAMESTATE->m_pCurSong ? GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds ) : GAMESTATE->m_fSongBeat; const int iSongRow = row == -1 ? BeatToNoteRow( fSongBeat ) : row; if( col != -1 && !bRelease ) @@ -2039,7 +2039,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b float fNoteOffset = 0.0f; // we need this later if we are autosyncing const float fStepBeat = NoteRowToBeat( iRowOfOverlappingNoteOrRow ); - const float fStepSeconds = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat(fStepBeat); + const float fStepSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat(fStepBeat); if( row == -1 ) { diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index 1a603c7046..f2cba6c337 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -1480,7 +1480,7 @@ bool ScreenGameplay::AllAreFailing() void ScreenGameplay::GetMusicEndTiming( float &fSecondsToStartFadingOutMusic, float &fSecondsToStartTransitioningOut ) { - float fLastStepSeconds = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat ); + float fLastStepSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat ); fLastStepSeconds += Player::GetMaxStepDistanceSeconds(); float fTransitionLength; @@ -1995,7 +1995,7 @@ void ScreenGameplay::SendCrossedMessages() static int iRowLastCrossed = 0; float fPositionSeconds = GAMESTATE->m_fMusicSeconds; - float fSongBeat = GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds ); + float fSongBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds ); int iRowNow = BeatToNoteRowNotRounded( fSongBeat ); iRowNow = max( 0, iRowNow ); @@ -2033,7 +2033,7 @@ void ScreenGameplay::SendCrossedMessages() float fNoteWillCrossInSeconds = MESSAGE_SPACING_SECONDS * i; float fPositionSeconds = GAMESTATE->m_fMusicSeconds + fNoteWillCrossInSeconds; - float fSongBeat = GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds ); + float fSongBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds ); int iRowNow = BeatToNoteRowNotRounded( fSongBeat ); iRowNow = max( 0, iRowNow ); diff --git a/src/ScreenHowToPlay.cpp b/src/ScreenHowToPlay.cpp index 7deca6dd40..877fb693c4 100644 --- a/src/ScreenHowToPlay.cpp +++ b/src/ScreenHowToPlay.cpp @@ -244,7 +244,7 @@ void ScreenHowToPlay::Update( float fDelta ) { if( GAMESTATE->m_pCurSong != NULL ) { - GAMESTATE->UpdateSongPosition( m_fFakeSecondsIntoSong, GAMESTATE->m_pCurSong->m_Timing ); + GAMESTATE->UpdateSongPosition( m_fFakeSecondsIntoSong, GAMESTATE->m_pCurSong->m_SongTiming ); m_fFakeSecondsIntoSong += fDelta; static int iLastNoteRowCounted = 0; diff --git a/src/ScreenSyncOverlay.cpp b/src/ScreenSyncOverlay.cpp index a0038b083f..baf240d54d 100644 --- a/src/ScreenSyncOverlay.cpp +++ b/src/ScreenSyncOverlay.cpp @@ -221,7 +221,7 @@ bool ScreenSyncOverlay::OverlayInput( const InputEventPlus &input ) } if( GAMESTATE->m_pCurSong != NULL ) { - BPMSegment& seg = GAMESTATE->m_pCurSong->GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat ); + BPMSegment& seg = GAMESTATE->m_pCurSong->m_SongTiming.GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat ); seg.m_fBPS += fDelta; } } @@ -253,7 +253,7 @@ bool ScreenSyncOverlay::OverlayInput( const InputEventPlus &input ) case ChangeSongOffset: if( GAMESTATE->m_pCurSong != NULL ) - GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += fDelta; + GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fDelta; break; } } diff --git a/src/Song.cpp b/src/Song.cpp index b8882a5ef2..a2c5184425 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -504,13 +504,14 @@ void Song::TidyUpData() m_fMusicSampleStartSeconds == 0 || m_fMusicSampleStartSeconds+m_fMusicSampleLengthSeconds > this->m_fMusicLengthSeconds ) { - m_fMusicSampleStartSeconds = this->GetElapsedTimeFromBeat( 100 ); + const TimingData &timing = this->m_SongTiming; + m_fMusicSampleStartSeconds = timing.GetElapsedTimeFromBeat( 100 ); if( m_fMusicSampleStartSeconds+m_fMusicSampleLengthSeconds > this->m_fMusicLengthSeconds ) { int iBeat = lrintf( m_fLastBeat/2 ); iBeat -= iBeat%4; - m_fMusicSampleStartSeconds = this->GetElapsedTimeFromBeat( (float)iBeat ); + m_fMusicSampleStartSeconds = timing.GetElapsedTimeFromBeat( (float)iBeat ); } } @@ -1485,7 +1486,8 @@ bool Song::HasSignificantBpmChangesOrStops() const float Song::GetStepsSeconds() const { - return GetElapsedTimeFromBeat( m_fLastBeat ) - GetElapsedTimeFromBeat( m_fFirstBeat ); + const TimingData &timing = this->m_SongTiming; + return timing.GetElapsedTimeFromBeat( m_fLastBeat ) - timing.GetElapsedTimeFromBeat( m_fFirstBeat ); } bool Song::IsLong() const From cd9fc83029aa95a6519bd9cc2d01860d4bd84711 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 21:17:24 -0400 Subject: [PATCH 011/197] [splittiming] We can build now. How effective the build is, though...that's the question. Time to risk breaking more parts. --- src/ScreenEdit.cpp | 150 ++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index cfa2b4e678..ce69563960 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -913,7 +913,7 @@ void ScreenEdit::Update( float fDeltaTime ) { RageTimer tm; const float fSeconds = m_pSoundMusic->GetPositionSeconds( NULL, &tm ); - GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_Timing, tm ); + GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_SongTiming, tm ); } if( m_EditState == STATE_RECORDING ) @@ -931,7 +931,7 @@ void ScreenEdit::Update( float fDeltaTime ) continue; float fStartedHoldingSeconds = m_pSoundMusic->GetPositionSeconds() - fSecsHeld; - float fStartBeat = max( fStartPlayingAtBeat, m_pSong->GetBeatFromElapsedTime(fStartedHoldingSeconds) ); + float fStartBeat = max( fStartPlayingAtBeat, m_pSong->m_SongTiming.GetBeatFromElapsedTime(fStartedHoldingSeconds) ); float fEndBeat = max( fStartBeat, GAMESTATE->m_fSongBeat ); fEndBeat = min( fEndBeat, NoteRowToBeat(m_iStopPlayingAt) ); @@ -976,11 +976,11 @@ void ScreenEdit::Update( float fDeltaTime ) float fLastBeat = NoteRowToBeat(m_iStopPlayingAt); if( bButtonIsBeingPressed && m_EditState == STATE_RECORDING ) { - float fSeconds = m_pSong->m_Timing.GetElapsedTimeFromBeat( fLastBeat ); - fLastBeat = m_pSong->m_Timing.GetBeatFromElapsedTime( fSeconds + 0.5f ); + float fSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( fLastBeat ); + fLastBeat = m_pSong->m_SongTiming.GetBeatFromElapsedTime( fSeconds + 0.5f ); } - float fStopAtSeconds = m_pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStopPlayingAt) ) + 1; + float fStopAtSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStopPlayingAt) ) + 1; if( GAMESTATE->m_fMusicSeconds > fStopAtSeconds ) { // loop @@ -1071,7 +1071,7 @@ void ScreenEdit::UpdateTextInfo() RString sText; sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GAMESTATE->m_fSongBeat ); - sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSong->GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat) ); + sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSong->m_SongTiming.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat) ); switch( EDIT_MODE.GetValue() ) { DEFAULT_FAIL( EDIT_MODE.GetValue() ); @@ -1129,7 +1129,7 @@ void ScreenEdit::UpdateTextInfo() case EditMode_Home: break; case EditMode_Full: - sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), m_pSong->m_Timing.m_fBeat0OffsetInSeconds ); + sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds ); sText += ssprintf( PREVIEW_START_FORMAT.GetValue(), PREVIEW_START.GetValue().c_str(), m_pSong->m_fMusicSampleStartSeconds ); sText += ssprintf( PREVIEW_LENGTH_FORMAT.GetValue(), PREVIEW_LENGTH.GetValue().c_str(), m_pSong->m_fMusicSampleLengthSeconds ); break; @@ -1243,7 +1243,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) m_iShiftAnchor = -1; return; } - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator; + int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator; switch( EditB ) { @@ -1443,13 +1443,13 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_LABEL_NEXT: { - ScrollTo( GAMESTATE->m_pCurSong->m_Timing. + ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming. GetNextLabelSegmentBeatAtBeat( GAMESTATE->m_fSongBeat ) ); } break; case EDIT_BUTTON_LABEL_PREV: { - ScrollTo( GAMESTATE->m_pCurSong->m_Timing. + ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming. GetPreviousLabelSegmentBeatAtBeat( GAMESTATE->m_fSongBeat ) ); } break; @@ -1579,7 +1579,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_BPM_UP: case EDIT_BUTTON_BPM_DOWN: { - float fBPM = m_pSong->GetBPMAtBeat( GAMESTATE->m_fSongBeat ); + float fBPM = m_pSong->m_SongTiming.GetBPMAtBeat( GAMESTATE->m_fSongBeat ); float fDelta; switch( EditB ) { @@ -1600,7 +1600,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } float fNewBPM = fBPM + fDelta; - m_pSong->SetBPMAtBeat( GAMESTATE->m_fSongBeat, fNewBPM ); + m_pSong->m_SongTiming.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fNewBPM ); (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); } @@ -1627,24 +1627,24 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) fDelta *= 40; } unsigned i; - for( i=0; im_Timing.m_StopSegments.size(); i++ ) + for( i=0; im_SongTiming.m_StopSegments.size(); i++ ) { - if( m_pSong->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) + if( m_pSong->m_SongTiming.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) break; } - if( i == m_pSong->m_Timing.m_StopSegments.size() ) // there is no StopSegment at the current beat + if( i == m_pSong->m_SongTiming.m_StopSegments.size() ) // there is no StopSegment at the current beat { // create a new StopSegment if( fDelta > 0 ) - m_pSong->AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta) ); + m_pSong->m_SongTiming.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta) ); } - else // StopSegment being modified is m_Timing.m_StopSegments[i] + else // StopSegment being modified is m_SongTiming.m_StopSegments[i] { - m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds += fDelta; - if( m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 ) - m_pSong->m_Timing.m_StopSegments.erase( m_pSong->m_Timing.m_StopSegments.begin()+i, - m_pSong->m_Timing.m_StopSegments.begin()+i+1); + m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds += fDelta; + if( m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds <= 0 ) + m_pSong->m_SongTiming.m_StopSegments.erase( m_pSong->m_SongTiming.m_StopSegments.begin()+i, + m_pSong->m_SongTiming.m_StopSegments.begin()+i+1); } (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); @@ -1673,24 +1673,24 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) fDelta *= 40; } unsigned i; - for( i=0; im_Timing.m_StopSegments.size(); i++ ) + for( i=0; im_SongTiming.m_StopSegments.size(); i++ ) { - if( m_pSong->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) + if( m_pSong->m_SongTiming.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) break; } - if( i == m_pSong->m_Timing.m_StopSegments.size() ) // there is no delay segment at the current beat + if( i == m_pSong->m_SongTiming.m_StopSegments.size() ) // there is no delay segment at the current beat { // create a new delay segment if( fDelta > 0 ) m_pSong->AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta, true) ); } - else // delay segment being modified is m_Timing.m_StopSegments[i] + else // delay segment being modified is m_SongTiming.m_StopSegments[i] { - m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds += fDelta; - if( m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 ) - m_pSong->m_Timing.m_StopSegments.erase( m_pSong->m_Timing.m_StopSegments.begin()+i, - m_pSong->m_Timing.m_StopSegments.begin()+i+1); + m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds += fDelta; + if( m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds <= 0 ) + m_pSong->m_SongTiming.m_StopSegments.erase( m_pSong->m_SongTiming.m_StopSegments.begin()+i, + m_pSong->m_SongTiming.m_StopSegments.begin()+i+1); } (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); @@ -1718,7 +1718,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) else fDelta *= 40; } - m_pSong->m_Timing.m_fBeat0OffsetInSeconds += fDelta; + m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds += fDelta; (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); } @@ -1900,7 +1900,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( pCourse == NULL ) break; CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; - float fStartTime = m_pSong->GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); + float fStartTime = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); int iAttack = FindAttackAtTime( ce.attacks, fStartTime ); if( iAttack >= 0 ) @@ -1941,7 +1941,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } else { - fStart = m_pSong->GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); + fStart = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); int iAttack = FindAttackAtTime( ce.attacks, fStart ); if( iAttack >= 0 ) @@ -1950,7 +1950,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( m_NoteFieldEdit.m_iEndMarker == -1 ) fEnd = m_pSong->m_fMusicLengthSeconds; else - fEnd = m_pSong->GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); + fEnd = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); } g_fLastInsertAttackPositionSeconds = fStart; g_fLastInsertAttackDurationSeconds = fEnd - fStart; @@ -2265,7 +2265,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB ) fOffsetDelta *= 40; } - m_pSong->m_Timing.m_fBeat0OffsetInSeconds += fOffsetDelta; + m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds += fOffsetDelta; } break; } @@ -2381,8 +2381,8 @@ void ScreenEdit::TransitionEditState( EditState em ) AdjustSync::ResetOriginalSyncData(); /* Give a 1 second lead-in. If we're loading Player, this must be done first. */ - float fSeconds = m_pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1; - GAMESTATE->UpdateSongPosition( fSeconds, m_pSong->m_Timing ); + float fSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1; + GAMESTATE->UpdateSongPosition( fSeconds, m_pSong->m_SongTiming ); GAMESTATE->m_bGameplayLeadIn.Set( false ); @@ -2463,7 +2463,7 @@ void ScreenEdit::TransitionEditState( EditState em ) { case STATE_PLAYING: case STATE_RECORDING: - const float fStartSeconds = m_pSong->GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat); + const float fStartSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat); LOG->Trace( "Starting playback at %f", fStartSeconds ); RageSoundParams p; @@ -2627,21 +2627,21 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { float fBPM = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fBPM > 0 ) - m_pSong->SetBPMAtBeat( GAMESTATE->m_fSongBeat, fBPM ); + m_pSong->m_SongTiming.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fBPM ); SetDirty( true ); } else if( SM == SM_BackFromStopChange ) { float fStop = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fStop >= 0 ) - m_pSong->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, fStop ); + m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, fStop ); SetDirty( true ); } else if( SM == SM_BackFromDelayChange ) { float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fDelay >= 0 ) - m_pSong->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, fDelay, true ); + m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, fDelay, true ); SetDirty( true ); } else if( SM == SM_BackFromTimeSignatureNumeratorChange ) @@ -2649,7 +2649,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iNum = atoi( ScreenTextEntry::s_sLastAnswer ); if( iNum > 0 ) { - m_pSong->m_Timing.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_fSongBeat, iNum ); + m_pSong->m_SongTiming.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_fSongBeat, iNum ); } SetDirty( true ); } @@ -2658,7 +2658,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iDen = atoi( ScreenTextEntry::s_sLastAnswer ); if( iDen > 0) { - m_pSong->m_Timing.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_fSongBeat, iDen ); + m_pSong->m_SongTiming.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_fSongBeat, iDen ); } SetDirty( true ); } @@ -2667,7 +2667,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iTick = atoi( ScreenTextEntry::s_sLastAnswer ); if ( iTick >= 0 && iTick <= ROWS_PER_BEAT ) { - m_pSong->m_Timing.SetTickcountAtBeat( GAMESTATE->m_fSongBeat, iTick ); + m_pSong->m_SongTiming.SetTickcountAtBeat( GAMESTATE->m_fSongBeat, iTick ); } SetDirty( true ); } @@ -2676,25 +2676,25 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iCombo = atoi( ScreenTextEntry::s_sLastAnswer ); if ( iCombo >= 0 ) { - m_pSong->m_Timing.SetComboAtBeat( GAMESTATE->m_fSongBeat, iCombo ); + m_pSong->m_SongTiming.SetComboAtBeat( GAMESTATE->m_fSongBeat, iCombo ); } SetDirty( true ); } else if ( SM == SM_BackFromLabelChange ) { RString sLabel = ScreenTextEntry::s_sLastAnswer; - if ( !m_pSong->m_Timing.DoesLabelExist(sLabel) ) + if ( !m_pSong->m_SongTiming.DoesLabelExist(sLabel) ) { sLabel.Replace("=", "_"); sLabel.Replace(",", "_"); - m_pSong->m_Timing.SetLabelAtBeat( GAMESTATE->m_fSongBeat, sLabel ); + m_pSong->m_SongTiming.SetLabelAtBeat( GAMESTATE->m_fSongBeat, sLabel ); SetDirty( true ); } } else if ( SM == SM_BackFromWarpChange ) { float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer ); - m_pSong->m_Timing.SetWarpAtBeat( GAMESTATE->m_fSongBeat, fWarp ); + m_pSong->m_SongTiming.SetWarpAtBeat( GAMESTATE->m_fSongBeat, fWarp ); SetDirty( true ); } else if( SM == SM_BackFromBGChange ) @@ -2767,7 +2767,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; int iAttack; - g_fLastInsertAttackPositionSeconds = m_pSong->GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); + g_fLastInsertAttackPositionSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); g_fLastInsertAttackDurationSeconds = StringToFloat( g_InsertCourseAttack.rows[0].choices[iDurationChoice] ); iAttack = FindAttackAtTime( ce.attacks, g_fLastInsertAttackPositionSeconds ); @@ -3024,7 +3024,7 @@ static void ChangeArtistTranslit( const RString &sNew ) static void ChangeBeat0Offset( const RString &sNew ) { - GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); + GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); } static void ChangeLastBeatHint( const RString &sNew ) @@ -3242,7 +3242,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns g_SongInformation.rows[main_title_transliteration].SetOneUnthemedChoice( pSong->m_sMainTitleTranslit ); g_SongInformation.rows[sub_title_transliteration].SetOneUnthemedChoice( pSong->m_sSubTitleTranslit ); g_SongInformation.rows[artist_transliteration].SetOneUnthemedChoice( pSong->m_sArtistTranslit ); - g_SongInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_Timing.m_fBeat0OffsetInSeconds) ); + g_SongInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_SongTiming.m_fBeat0OffsetInSeconds) ); g_SongInformation.rows[last_beat_hint].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fSpecifiedLastBeat) ); g_SongInformation.rows[preview_start].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fMusicSampleStartSeconds) ); g_SongInformation.rows[preview_length].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fMusicSampleLengthSeconds) ); @@ -3256,9 +3256,9 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns case edit_timing_data: { const Song* pSong = GAMESTATE->m_pCurSong; - TimingData pTime = pSong->m_Timing; + TimingData pTime = pSong->m_SongTiming; const float fBeat = GAMESTATE->m_fSongBeat; - g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pSong->GetBPMAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[time_signature_numerator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ) ) ); @@ -3501,7 +3501,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex ); // scale timing data - m_pSong->m_Timing.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); + m_pSong->m_SongTiming.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); // scale all other steps. const vector sIter = m_pSong->GetAllSteps(); @@ -3546,16 +3546,16 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); break; case shift_pauses_forward: - m_pSong->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); + m_pSong->m_SongTiming.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); break; case shift_pauses_backward: - m_pSong->m_Timing.DeleteRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); + m_pSong->m_SongTiming.DeleteRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); break; case convert_to_pause: { ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - float fMarkerStart = m_pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); - float fMarkerEnd = m_pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); + float fMarkerStart = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); + float fMarkerEnd = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); // The length of the stop segment we're going to create. This includes time spent in any // stops in the selection, which will be deleted and subsumed into the new stop. @@ -3567,9 +3567,9 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns m_NoteFieldEdit.m_iBeginMarker + 1, m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); - m_pSong->m_Timing.DeleteRows( m_NoteFieldEdit.m_iBeginMarker, + m_pSong->m_SongTiming.DeleteRows( m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); - m_pSong->m_Timing.SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); + m_pSong->m_SongTiming.SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); m_NoteFieldEdit.m_iBeginMarker = -1; m_NoteFieldEdit.m_iEndMarker = -1; break; @@ -3577,14 +3577,14 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case convert_pause_to_beat: { // TODO: Convert both Delays and Stops at once. - float fStopSeconds = m_pSong->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ); - m_pSong->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, 0 ); + float fStopSeconds = m_pSong->m_SongTiming.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ); + m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, 0 ); - float fStopBeats = fStopSeconds * m_pSong->GetBPMAtBeat(GAMESTATE->m_fSongBeat) / 60; + float fStopBeats = fStopSeconds * m_pSong->m_SongTiming.GetBPMAtBeat(GAMESTATE->m_fSongBeat) / 60; // don't move the step from where it is, just move everything later NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); - m_pSong->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); + m_pSong->m_SongTiming.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); } break; case undo: @@ -3701,7 +3701,7 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec break; case beat_0_offset: ScreenTextEntry::TextEntry( SM_None, ENTER_BEAT_0_OFFSET, - ssprintf("%.5f", pSong->m_Timing.m_fBeat0OffsetInSeconds), 20, + ssprintf("%.5f", pSong->m_SongTiming.m_fBeat0OffsetInSeconds), 20, ScreenTextEntry::FloatValidate, ChangeBeat0Offset, NULL ); break; case last_beat_hint: @@ -3750,7 +3750,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromBPMChange, ENTER_BPM_VALUE, - ssprintf( "%.4f", m_pSong->GetBPMAtBeat(GAMESTATE->m_fSongBeat) ), + ssprintf( "%.4f", m_pSong->m_SongTiming.GetBPMAtBeat(GAMESTATE->m_fSongBeat) ), 10 ); break; @@ -3758,7 +3758,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromStopChange, ENTER_STOP_VALUE, - ssprintf( "%.4f", m_pSong->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSong->m_SongTiming.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), 10 ); break; @@ -3766,7 +3766,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromDelayChange, ENTER_DELAY_VALUE, - ssprintf( "%.4f", m_pSong->m_Timing.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSong->m_SongTiming.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), 10 ); break; @@ -3774,7 +3774,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureNumeratorChange, ENTER_TIME_SIGNATURE_NUMERATOR_VALUE, - ssprintf( "%d", m_pSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator ), + ssprintf( "%d", m_pSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator ), 3 ); break; @@ -3782,7 +3782,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureDenominatorChange, ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE, - ssprintf( "%d", m_pSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iDenominator ), + ssprintf( "%d", m_pSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iDenominator ), 3 ); break; @@ -3790,7 +3790,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTickcountChange, ENTER_TICKCOUNT_VALUE, - ssprintf( "%d", m_pSong->m_Timing.GetTickcountAtBeat( GAMESTATE->m_fSongBeat ) ), + ssprintf( "%d", m_pSong->m_SongTiming.GetTickcountAtBeat( GAMESTATE->m_fSongBeat ) ), 2 ); break; @@ -3798,7 +3798,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromComboChange, ENTER_COMBO_VALUE, - ssprintf( "%d", m_pSong->m_Timing.GetComboAtBeat( GAMESTATE->m_fSongBeat ) ), + ssprintf( "%d", m_pSong->m_SongTiming.GetComboAtBeat( GAMESTATE->m_fSongBeat ) ), 4 ); break; @@ -3806,7 +3806,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromLabelChange, ENTER_LABEL_VALUE, - ssprintf( "%s", m_pSong->m_Timing.GetLabelAtBeat( GAMESTATE->m_fSongBeat ).c_str() ), + ssprintf( "%s", m_pSong->m_SongTiming.GetLabelAtBeat( GAMESTATE->m_fSongBeat ).c_str() ), 64 ); break; @@ -3814,7 +3814,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromWarpChange, ENTER_WARP_VALUE, - ssprintf( "%.4f", m_pSong->m_Timing.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSong->m_SongTiming.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), 10 ); break; @@ -4021,7 +4021,7 @@ void ScreenEdit::CheckNumberOfNotesAndUndo() if( EDIT_MODE.GetValue() != EditMode_Home ) return; - TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ); + TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ); int rowsPerMeasure = curTime.m_iDenominator * curTime.m_iNumerator; for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure ) @@ -4073,7 +4073,7 @@ float ScreenEdit::GetMaximumBeatForNewNote() const /* Round up to the next measure end. Some songs end on weird beats * mid-measure, and it's odd to have movement capped to these weird * beats. */ - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator; + int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator; fEndBeat += beatsPerMeasure; fEndBeat = ftruncf( fEndBeat, (float)beatsPerMeasure ); From 44ee6fc0de51f2bc8a75e44e9228f2803fd50d10 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 21:19:40 -0400 Subject: [PATCH 012/197] [splittiming] Simplify. --- src/NoteField.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 213d5e1e09..20e7c08f8b 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -785,8 +785,10 @@ void NoteField::DrawPrimitives() { ASSERT(GAMESTATE->m_pCurSong); + const TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming; + // BPM text - FOREACH_CONST( BPMSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments, seg ) + FOREACH_CONST( BPMSegment, timing.m_BPMSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -797,7 +799,7 @@ void NoteField::DrawPrimitives() } // Freeze text - FOREACH_CONST( StopSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments, seg ) + FOREACH_CONST( StopSegment, timing.m_StopSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -808,7 +810,7 @@ void NoteField::DrawPrimitives() } // Warp text - FOREACH_CONST( WarpSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_WarpSegments, seg ) + FOREACH_CONST( WarpSegment, timing.m_WarpSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -819,7 +821,7 @@ void NoteField::DrawPrimitives() } // Time Signature text - FOREACH_CONST( TimeSignatureSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_vTimeSignatureSegments, seg ) + FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -830,7 +832,7 @@ void NoteField::DrawPrimitives() } // Tickcount text - FOREACH_CONST( TickcountSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_TickcountSegments, seg ) + FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -841,7 +843,7 @@ void NoteField::DrawPrimitives() } // Combo text - FOREACH_CONST( ComboSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_ComboSegments, seg ) + FOREACH_CONST( ComboSegment, timing.m_ComboSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -852,7 +854,7 @@ void NoteField::DrawPrimitives() } // Label text - FOREACH_CONST( LabelSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_LabelSegments, seg ) + FOREACH_CONST( LabelSegment, timing.m_LabelSegments, seg ) { if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) { @@ -872,7 +874,7 @@ void NoteField::DrawPrimitives() FOREACH_CONST( Attack, ce.attacks, a ) { float fSecond = a->fStartSecond; - float fBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fSecond ); + float fBeat = timing.GetBeatFromElapsedTime( fSecond ); if( BeatToNoteRow(fBeat) >= iFirstRowToDraw && BeatToNoteRow(fBeat) <= iLastRowToDraw) From f629f06c34a84806360ae8f0c26a3e2e4d500ee0 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 22:42:46 -0400 Subject: [PATCH 013/197] [splittiming] Abstract functionality for later. I don't want to repeat code for Steps. --- src/NotesLoaderSM.cpp | 476 +++++++++++++++++++++-------------------- src/NotesLoaderSM.h | 7 + src/NotesLoaderSSC.cpp | 319 ++++++++------------------- src/NotesLoaderSSC.h | 5 + 4 files changed, 343 insertions(+), 464 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 3ee9994332..3fa6432713 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -103,6 +103,244 @@ bool SMLoader::LoadTimingFromFile( const RString &fn, TimingData &out ) return true; } +void SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) +{ + vector arrayBPMChangeExpressions; + split( sParam, ",", arrayBPMChangeExpressions ); + + // prepare storage variables for negative BPMs -> Warps. + float negBeat = -1; + float negBPM = 1; + float highspeedBeat = -1; + + for( unsigned b=0; b arrayBPMChangeValues; + split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); + // XXX: Hard to tell which file caused this. + if( arrayBPMChangeValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #BPMs value \"%s\" (must have exactly one '='), ignored.", + arrayBPMChangeExpressions[b].c_str() ); + continue; + } + + const float fBeat = StringToFloat( arrayBPMChangeValues[0] ); + const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); + + if( fNewBPM < 0.0f ) + { + out.m_bHasNegativeBpms = true; + negBeat = fBeat; + negBPM = fNewBPM; + } + else if( fNewBPM > 0.0f ) + { + // add in a warp. + if( negBPM < 0 ) + { + float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat); + WarpSegment new_seg(negBeat, endBeat); + out.AddWarpSegment( new_seg ); + + negBeat = -1; + negBPM = 1; + } + // too fast. make it a warp. + if( fNewBPM > FAST_BPM_WARP ) + { + highspeedBeat = fBeat; + } + else + { + // add in a warp. + if( highspeedBeat > 0 ) + { + WarpSegment new_seg(highspeedBeat, fBeat); + out.AddWarpSegment( new_seg ); + highspeedBeat = -1; + } + { + BPMSegment new_seg; + new_seg.m_iStartRow = BeatToNoteRow(fBeat); + new_seg.SetBPM( fNewBPM ); + out.AddBPMSegment( new_seg ); + } + } + } + } +} + +void SMLoader::ProcessStops( TimingData &out, const RString sParam ) +{ + vector arrayFreezeExpressions; + split( sParam, ",", arrayFreezeExpressions ); + + // Prepare variables for negative stop conversion. + float negBeat = -1; + float negPause = 0; + + for( unsigned f=0; f arrayFreezeValues; + split( arrayFreezeExpressions[f], "=", arrayFreezeValues ); + if( arrayFreezeValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #STOPS value \"%s\" (must have exactly one '='), ignored.", + arrayFreezeExpressions[f].c_str() ); + continue; + } + + const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] ); + const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ); + + // Process the prior stop. + if( negPause > 0 ) + { + BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); + float fSecondsPerBeat = 60 / oldBPM.GetBPM(); + float fSkipBeats = negPause / fSecondsPerBeat; + + if( negBeat + fSkipBeats > fFreezeBeat ) + fSkipBeats = fFreezeBeat - negBeat; + + WarpSegment ws( negBeat, negBeat + fSkipBeats); + out.AddWarpSegment( ws ); + + negBeat = -1; + negPause = 0; + } + + if( fFreezeSeconds < 0.0f ) + { + negBeat = fFreezeBeat; + negPause = -fFreezeSeconds; + } + else if( fFreezeSeconds > 0.0f ) + { + StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); + out.AddStopSegment( ss ); + } + + } + + // Process the prior stop if there was one. + if( negPause > 0 ) + { + BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); + float fSecondsPerBeat = 60 / oldBPM.GetBPM(); + float fSkipBeats = negPause / fSecondsPerBeat; + + WarpSegment ws( negBeat, negBeat + fSkipBeats); + out.AddWarpSegment( ws ); + } +} + +void SMLoader::ProcessDelays( TimingData &out, const RString sParam ) +{ + vector arrayDelayExpressions; + split( sParam, ",", arrayDelayExpressions ); + + for( unsigned f=0; f arrayDelayValues; + split( arrayDelayExpressions[f], "=", arrayDelayValues ); + if( arrayDelayValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #DELAYS value \"%s\" (must have exactly one '='), ignored.", + arrayDelayExpressions[f].c_str() ); + continue; + } + + const float fFreezeBeat = StringToFloat( arrayDelayValues[0] ); + const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] ); + + StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true ); + // XXX: Remove Negatives Bug? + new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat); + new_seg.m_fStopSeconds = fFreezeSeconds; + + // LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); + + if(fFreezeSeconds > 0.0f) + out.AddStopSegment( new_seg ); + else + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); + } +} + +void SMLoader::ProcessTimeSignatures( TimingData &out, const RString sParam ) +{ + vector vs1; + split( sParam, ",", vs1 ); + + FOREACH_CONST( RString, vs1, s1 ) + { + vector vs2; + split( *s1, "=", vs2 ); + + if( vs2.size() < 3 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() ); + continue; + } + + const float fBeat = StringToFloat( vs2[0] ); + + TimeSignatureSegment seg; + seg.m_iStartRow = BeatToNoteRow(fBeat); + seg.m_iNumerator = atoi( vs2[1] ); + seg.m_iDenominator = atoi( vs2[2] ); + + if( fBeat < 0 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat ); + continue; + } + + if( seg.m_iNumerator < 1 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); + continue; + } + + if( seg.m_iDenominator < 1 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator ); + continue; + } + + out.AddTimeSignatureSegment( seg ); + } +} + +void SMLoader::ProcessTickcounts( TimingData &out, const RString sParam ) +{ + vector arrayTickcountExpressions; + split( sParam, ",", arrayTickcountExpressions ); + + for( unsigned f=0; f arrayTickcountValues; + split( arrayTickcountExpressions[f], "=", arrayTickcountValues ); + if( arrayTickcountValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #TICKCOUNTS value \"%s\" (must have exactly one '='), ignored.", + arrayTickcountExpressions[f].c_str() ); + continue; + } + + const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] ); + int iTicks = clamp(atoi( arrayTickcountValues[1] ), 0, ROWS_PER_BEAT); + + TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks ); + out.AddTickcountSegment( new_seg ); + } +} + void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out ) { out.m_fBeat0OffsetInSeconds = 0; @@ -123,255 +361,27 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out ) } else if( sValueName=="BPMS" ) { - vector arrayBPMChangeExpressions; - split( sParams[1], ",", arrayBPMChangeExpressions ); - - // prepare storage variables for negative BPMs -> Warps. - float negBeat = -1; - float negBPM = 1; - float highspeedBeat = -1; - - for( unsigned b=0; b arrayBPMChangeValues; - split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); - // XXX: Hard to tell which file caused this. - if( arrayBPMChangeValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() ); - continue; - } - - const float fBeat = StringToFloat( arrayBPMChangeValues[0] ); - const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); - - if( fNewBPM < 0.0f ) - { - out.m_bHasNegativeBpms = true; - negBeat = fBeat; - negBPM = fNewBPM; - } - else if( fNewBPM > 0.0f ) - { - // add in a warp. - if( negBPM < 0 ) - { - float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat); - WarpSegment new_seg(negBeat, endBeat); - out.AddWarpSegment( new_seg ); - - negBeat = -1; - negBPM = 1; - } - // too fast. make it a warp. - if( fNewBPM > FAST_BPM_WARP ) - { - highspeedBeat = fBeat; - } - else - { - // add in a warp. - if( highspeedBeat > 0 ) - { - WarpSegment new_seg(highspeedBeat, fBeat); - out.AddWarpSegment( new_seg ); - highspeedBeat = -1; - } - { - BPMSegment new_seg; - new_seg.m_iStartRow = BeatToNoteRow(fBeat); - new_seg.SetBPM( fNewBPM ); - out.AddBPMSegment( new_seg ); - } - } - } - } + ProcessBPMs(out, sParams[1]); } else if( sValueName=="STOPS" || sValueName=="FREEZES" ) { - vector arrayFreezeExpressions; - split( sParams[1], ",", arrayFreezeExpressions ); - - // Prepare variables for negative stop conversion. - float negBeat = -1; - float negPause = 0; - - for( unsigned f=0; f arrayFreezeValues; - split( arrayFreezeExpressions[f], "=", arrayFreezeValues ); - if( arrayFreezeValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayFreezeExpressions[f].c_str() ); - continue; - } - - const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] ); - const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ); - - // Process the prior stop. - if( negPause > 0 ) - { - BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); - float fSecondsPerBeat = 60 / oldBPM.GetBPM(); - float fSkipBeats = negPause / fSecondsPerBeat; - - if( negBeat + fSkipBeats > fFreezeBeat ) - fSkipBeats = fFreezeBeat - negBeat; - - WarpSegment ws( negBeat, negBeat + fSkipBeats); - out.AddWarpSegment( ws ); - - negBeat = -1; - negPause = 0; - } - - if( fFreezeSeconds < 0.0f ) - { - negBeat = fFreezeBeat; - negPause = -fFreezeSeconds; - } - else if( fFreezeSeconds > 0.0f ) - { - StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); - out.AddStopSegment( ss ); - } - - } - - // Process the prior stop if there was one. - if( negPause > 0 ) - { - BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); - float fSecondsPerBeat = 60 / oldBPM.GetBPM(); - float fSkipBeats = negPause / fSecondsPerBeat; - - WarpSegment ws( negBeat, negBeat + fSkipBeats); - out.AddWarpSegment( ws ); - } + ProcessStops(out, sParams[1]); } else if( sValueName=="DELAYS" ) { - vector arrayDelayExpressions; - split( sParams[1], ",", arrayDelayExpressions ); - - for( unsigned f=0; f arrayDelayValues; - split( arrayDelayExpressions[f], "=", arrayDelayValues ); - if( arrayDelayValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayDelayExpressions[f].c_str() ); - continue; - } - - const float fFreezeBeat = StringToFloat( arrayDelayValues[0] ); - const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] ); - - StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true ); - // XXX: Remove Negatives Bug? - new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat); - new_seg.m_fStopSeconds = fFreezeSeconds; - - // LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); - - if(fFreezeSeconds > 0.0f) - out.AddStopSegment( new_seg ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } + ProcessDelays(out, sParams[1]); } else if( sValueName=="TIMESIGNATURES" ) { - vector vs1; - split( sParams[1], ",", vs1 ); - - FOREACH_CONST( RString, vs1, s1 ) - { - vector vs2; - split( *s1, "=", vs2 ); - - if( vs2.size() < 3 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() ); - continue; - } - - const float fBeat = StringToFloat( vs2[0] ); - - TimeSignatureSegment seg; - seg.m_iStartRow = BeatToNoteRow(fBeat); - seg.m_iNumerator = atoi( vs2[1] ); - seg.m_iDenominator = atoi( vs2[2] ); - - if( fBeat < 0 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat ); - continue; - } - - if( seg.m_iNumerator < 1 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); - continue; - } - - if( seg.m_iDenominator < 1 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator ); - continue; - } - - out.AddTimeSignatureSegment( seg ); - } + ProcessTimeSignatures(out, sParams[1]); } else if( sValueName=="TICKCOUNTS" ) { - vector arrayTickcountExpressions; - split( sParams[1], ",", arrayTickcountExpressions ); - - for( unsigned f=0; f arrayTickcountValues; - split( arrayTickcountExpressions[f], "=", arrayTickcountValues ); - if( arrayTickcountValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayTickcountExpressions[f].c_str() ); - continue; - } - - const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] ); - int iTicks = atoi( arrayTickcountValues[1] ); - // you're lazy, let SM do the work for you... -DaisuMaster - if( iTicks < 1) iTicks = 1; - if( iTicks > ROWS_PER_BEAT ) iTicks = ROWS_PER_BEAT; - - TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks ); - out.AddTickcountSegment( new_seg ); - - if(iTicks >= 1 && iTicks <= ROWS_PER_BEAT ) // Constants - { - // LOG->Trace( "Adding a tickcount segment: beat: %f, ticks = %d", fTickcountBeat, iTicks ); - //out.AddTickcountSegment( new_seg ); - } - else - { - //LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid tickcount at beat %f, ticks %d.", fTickcountBeat, iTicks ); - //LOG->UserLog( "Song file", "(UNKNOWN)", "Clamping tickcount value to %d at beat %f.", iTicks, fTickcountBeat); - //etc - } - } + ProcessTickcounts(out, sParams[1]); } // Ensure all of the warps are handled right. sort(out.m_WarpSegments.begin(), out.m_WarpSegments.end()); diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index db1e938528..d61c7b19ff 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -25,6 +25,13 @@ namespace SMLoader bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ); + + + void ProcessBPMs( TimingData &, const RString ); + void ProcessStops( TimingData &, const RString ); + void ProcessDelays( TimingData &, const RString ); + void ProcessTimeSignatures( TimingData &, const RString ); + void ProcessTickcounts( TimingData &, const RString ); } #endif diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index b242781117..51c8b83f66 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -112,6 +112,86 @@ bool SSCLoader::LoadFromDir( const RString &sPath, Song &out ) return LoadFromSSCFile( sPath + aFileNames[0], out ); } +void SSCLoader::ProcessWarps( TimingData &out, const RString sParam ) +{ + vector arrayWarpExpressions; + split( sParam, ",", arrayWarpExpressions ); + + for( unsigned b=0; b 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 arrayLabelExpressions; + split( sParam, ",", arrayLabelExpressions ); + + for( unsigned b=0; b 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 arrayComboExpressions; + split( sParam, ",", arrayComboExpressions ); + + for( unsigned f=0; f arrayComboValues; + split( arrayComboExpressions[f], "=", arrayComboValues ); + if( arrayComboValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #COMBOS value \"%s\" (must have exactly one '='), ignored.", + arrayComboExpressions[f].c_str() ); + continue; + } + const float fComboBeat = StringToFloat( arrayComboValues[0] ); + const int iCombos = atoi( arrayComboValues[1] ); + ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos ); + out.AddComboSegment( new_seg ); + } +} + bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCache ) { LOG->Trace( "Song::LoadFromSSCFile(%s)", sPath.c_str() ); @@ -390,264 +470,41 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach * if the steps do not have their own timing. */ else if( sValueName=="STOPS" ) { - vector arrayFreezeExpressions; - split( sParams[1], ",", arrayFreezeExpressions ); - - for( unsigned f=0; f 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_SongTiming.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_SongTiming.AddStopSegment( new_seg ); - } - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid stop at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } - } + SMLoader::ProcessStops(out.m_SongTiming, sParams[1]); } else if( sValueName=="DELAYS" ) { - vector arrayDelayExpressions; - split( sParams[1], ",", arrayDelayExpressions ); - - for( unsigned f=0; f 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_SongTiming.AddStopSegment( new_seg ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } + SMLoader::ProcessDelays(out.m_SongTiming, sParams[1]); } else if( sValueName=="BPMS" ) { - vector arrayBPMChangeExpressions; - split( sParams[1], ",", arrayBPMChangeExpressions ); - - for( unsigned b=0; b 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_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); - else - { - out.m_SongTiming.m_bHasNegativeBpms = true; - // only add Negative BPMs in quirks mode -aj - if( PREFSMAN->m_bQuirksMode ) - out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM ); - } - } + SMLoader::ProcessBPMs(out.m_SongTiming, sParams[1]); } else if( sValueName=="WARPS" ) { - vector arrayWarpExpressions; - split( sParams[1], ",", arrayWarpExpressions ); - - for( unsigned b=0; b 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_SongTiming.AddWarpSegment( WarpSegment(fBeat, fNewBeat) ); - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Warp at beat %f, BPM %f.", fBeat, fNewBeat ); - } - } + ProcessWarps( out.m_SongTiming, sParams[1] ); } else if( sValueName=="LABELS" ) { - vector arrayLabelExpressions; - split( sParams[1], ",", arrayLabelExpressions ); - - for( unsigned b=0; b 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_SongTiming.AddLabelSegment( LabelSegment(fBeat, sLabel) ); - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Label at beat %f called %s.", fBeat, sLabel.c_str() ); - } - - } + ProcessLabels( out.m_SongTiming, sParams[1] ); } else if( sValueName=="TIMESIGNATURES" ) { - vector vs1; - split( sParams[1], ",", vs1 ); - - FOREACH_CONST( RString, vs1, s1 ) - { - vector 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_SongTiming.AddTimeSignatureSegment( seg ); - } + SMLoader::ProcessTimeSignatures(out.m_SongTiming, sParams[1]); } else if( sValueName=="TICKCOUNTS" ) { - vector arrayTickcountExpressions; - split( sParams[1], ",", arrayTickcountExpressions ); - - for( unsigned f=0; f 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_SongTiming.AddTickcountSegment( new_seg ); - } - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid tickcount at beat %f, ticks %d.", fTickcountBeat, iTicks ); - } - } + SMLoader::ProcessTickcounts(out.m_SongTiming, sParams[1]); } else if( sValueName=="COMBOS" ) { - vector arrayComboExpressions; - split( sParams[1], ",", arrayComboExpressions ); - - for( unsigned f=0; f 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_SongTiming.AddComboSegment( new_seg ); - } + ProcessCombos( out.m_SongTiming, sParams[1] ); } /* The following are cache tags. Never fill their values diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index ff44a23cb5..53c9d5c72b 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -75,6 +75,11 @@ namespace SSCLoader * @param bFromCache a flag to determine if this song is loaded from a cache file. */ void TidyUpData( Song &song, bool bFromCache ); + + + void ProcessWarps( TimingData &, const RString ); + void ProcessLabels( TimingData &, const RString ); + void ProcessCombos( TimingData &, const RString ); } #endif /** From 2ad3b729f1fefb45cbe4f98eab113eeeccb244ac Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 22:49:47 -0400 Subject: [PATCH 014/197] [splittiming] Define far ahead version. This will let other branches develop .ssc if needed while this branch takes its time. --- Docs/Changelog_SSCformat.txt | 3 +++ src/NotesLoaderSSC.h | 2 ++ src/Song.h | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Docs/Changelog_SSCformat.txt b/Docs/Changelog_SSCformat.txt index 95b48cf7d7..fb04d68912 100644 --- a/Docs/Changelog_SSCformat.txt +++ b/Docs/Changelog_SSCformat.txt @@ -9,6 +9,9 @@ change to JSON, but it is unsure if this will be done. Implement .ssc at your own risk. ________________________________________________________________________________ +[v0.7] - theDtTvB, Wolfman2000 +* Split Timing officially implemented. + [v0.59] - Wolfman2000 * Typo fix: #RADARVALUES needed a semicolon at the end, not a colon. diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index 53c9d5c72b..bf85bdd73c 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -25,6 +25,8 @@ enum SSCLoadingStates const float VERSION_RADAR_FAKE = 0.53f; /** @brief The version where WarpSegments started to be utilized. */ const float VERSION_WARP_SEGMENT = 0.56f; +/** @brief The version that formally introduced Split Timing. */ +const float VERSION_SPLIT_TIMING = 0.7f; /** * @brief The SSCLoader handles all of the parsing needed for .ssc files. diff --git a/src/Song.h b/src/Song.h index 1d49724795..ac41bf476c 100644 --- a/src/Song.h +++ b/src/Song.h @@ -17,7 +17,7 @@ struct lua_State; struct BackgroundChange; /** @brief The version of the .ssc file format. */ -const static float STEPFILE_VERSION_NUMBER = 0.59f; +const static float STEPFILE_VERSION_NUMBER = 0.7f; /** @brief How many edits for this song can each profile have? */ const int MAX_EDITS_PER_SONG_PER_PROFILE = 5; From 1ea093cd5f757073361158f66faedc5b290344e6 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 23:16:56 -0400 Subject: [PATCH 015/197] [splittiming] Cleanup, more prepwork. --- src/NotesLoaderSSC.cpp | 178 +++++------------------------------------ src/TimingData.cpp | 12 ++- src/TimingData.h | 4 + 3 files changed, 34 insertions(+), 160 deletions(-) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 51c8b83f66..8af0e084ea 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -4,7 +4,7 @@ #include "GameManager.h" #include "MsdFile.h" // No JSON here. #include "NoteTypes.h" -#include "NotesLoaderSM.h" // For loading SM style edits. +#include "NotesLoaderSM.h" // For programming shortcuts. #include "RageFileManager.h" #include "RageLog.h" #include "RageUtil.h" @@ -30,70 +30,7 @@ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60 KB */ bool LoadFromBGSSCChangesString( BackgroundChange &change, const RString &sBGChangeExpression ) { - vector aBGChangeValues; - split( sBGChangeExpression, "=", aBGChangeValues, false ); - - aBGChangeValues.resize( min((int)aBGChangeValues.size(),11) ); - - switch( aBGChangeValues.size() ) - { - case 11: - change.m_def.m_sColor2 = aBGChangeValues[10]; - change.m_def.m_sColor2.Replace( '^', ',' ); - change.m_def.m_sColor2 = RageColor::NormalizeColorString( change.m_def.m_sColor2 ); - // fall through - case 10: - change.m_def.m_sColor1 = aBGChangeValues[9]; - change.m_def.m_sColor1.Replace( '^', ',' ); - change.m_def.m_sColor1 = RageColor::NormalizeColorString( change.m_def.m_sColor1 ); - // fall through - case 9: - change.m_sTransition = aBGChangeValues[8]; - // fall through - case 8: - change.m_def.m_sFile2 = aBGChangeValues[7]; - // fall through - case 7: - change.m_def.m_sEffect = aBGChangeValues[6]; - // fall through - case 6: - // param 7 overrides this. - // Backward compatibility: - if( change.m_def.m_sEffect.empty() ) - { - bool bLoop = atoi( aBGChangeValues[5] ) != 0; - if( !bLoop ) - change.m_def.m_sEffect = SBE_StretchNoLoop; - } - // fall through - case 5: - // param 7 overrides this. - // Backward compatibility: - if( change.m_def.m_sEffect.empty() ) - { - bool bRewindMovie = atoi( aBGChangeValues[4] ) != 0; - if( bRewindMovie ) - change.m_def.m_sEffect = SBE_StretchRewind; - } - // fall through - case 4: - // param 9 overrides this. - // Backward compatibility: - if( change.m_sTransition.empty() ) - change.m_sTransition = (atoi( aBGChangeValues[3] ) != 0) ? "CrossFade" : ""; - // fall through - case 3: - change.m_fRate = StringToFloat( aBGChangeValues[2] ); - // fall through - case 2: - change.m_def.m_sFile1 = aBGChangeValues[1]; - // fall through - case 1: - change.m_fStartBeat = StringToFloat( aBGChangeValues[0] ); - // fall through - } - - return aBGChangeValues.size() >= 2; + return SMLoader::LoadFromBGChangesString( change, sBGChangeExpression ); } bool SSCLoader::LoadFromDir( const RString &sPath, Song &out ) @@ -613,41 +550,14 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach out.AddSteps( pNewNotes ); } - else if( sValueName=="BPMS" ) + else if( sValueName=="BPMS" ) // This must ALWAYS be here in Split Timing. { - /* state = GETTING_STEP_TIMING_INFO; - vector arrayBPMChangeExpressions; - split( sParams[1], ",", arrayBPMChangeExpressions ); - - for( unsigned b=0; b arrayBPMChangeValues; - split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); - // XXX: Hard to tell which file caused this. - if( arrayBPMChangeValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() ); - continue; - } - - const float fBeat = StringToFloat( arrayBPMChangeValues[0] ); - const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); - - if(fNewBPM > 0.0f) - pNewNotes->m_Timing.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); - else - { - pNewNotes->m_Timing.m_bHasNegativeBpms = true; - // only add Negative BPMs in quirks mode -aj - if( PREFSMAN->m_bQuirksMode ) - pNewNotes->m_Timing.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM ); - } - } - */ + /* + pNewNotes->m_Timing = TimingData(out.m_SongTiming.m_fBeat0OffsetInSeconds); + SMLoader::ProcessBPMs(pNewNotes->m_Timing, sParams[1]); + */ + } break; } @@ -655,28 +565,31 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach { if( sValueName=="STOPS" ) { - // copy from above when it's time. + // SMLoader::ProcessStops(pNewNotes->m_Timing, sParams[1]); } else if( sValueName=="DELAYS" ) { - // copy from above when it's time. + // SMLoader::ProcessDelays(pNewNotes->m_Timing, sParams[1]); } else if( sValueName=="TIMESIGNATURES" ) { - // copy from above when it's time. + // SMLoader::ProcessTimeSignatures(pNewNotes->m_Timing, sParams[1]); } - else if( sValueName=="TICKCOUNTS" ) { - // copy from above when it's time. + // SMLoader::ProcessTickcounts(pNewNotes->m_Timing, sParams[1]); } else if( sValueName=="COMBOS" ) { - // copy from above when it's time. + // ProcessCombos(pNewNotes->m_Timing, sParams[1]); } - else if( sValueName=="WARPS" || sValueName=="LABELS" ) + else if( sValueName=="WARPS" ) { - // copy from above when it's time. + // ProcessWarps(pNewNotes->m_Timing, sParams[1]); + } + else if( sValueName=="LABELS" ) + { + // ProcessLabels(pNewNotes->m_Timing, sParams[1]); } else if( sValueName=="ATTACKS" ) { @@ -731,10 +644,9 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach */ } - else if( sValueName=="NOTES" ) + else if( sValueName=="NOTES" || sValueName=="NOTES2" ) { state = GETTING_SONG_INFO; - // pNewNotes->m_Timing.m_fBeat0OffsetInSeconds = out.m_Timing.m_fBeat0OffsetInSeconds; pNewNotes->SetSMNoteData( sParams[1] ); pNewNotes->TidyUpData(); out.AddSteps( pNewNotes ); @@ -952,55 +864,7 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat void SSCLoader::TidyUpData( Song &song, bool bFromCache ) { - /* - * Hack: if the song has any changes at all (so it won't use a random BGA) - * and doesn't end with "-nosongbg-", add a song background BGC. Remove - * "-nosongbg-" if it exists. - * - * This way, songs that were created earlier, when we added the song BG - * at the end by default, will still behave as expected; all new songs will - * have to add an explicit song BG tag if they want it. This is really a - * formatting hack only; nothing outside of SMLoader ever sees "-nosongbg-". - */ - vector &bg = song.GetBackgroundChanges(BACKGROUND_LAYER_1); - if( !bg.empty() ) - { - /* BGChanges have been sorted. On the odd chance that a BGChange exists - * with a very high beat, search the whole list. */ - bool bHasNoSongBgTag = false; - - for( unsigned i = 0; !bHasNoSongBgTag && i < bg.size(); ++i ) - { - if( !bg[i].m_def.m_sFile1.CompareNoCase(NO_SONG_BG_FILE) ) - { - bg.erase( bg.begin()+i ); - bHasNoSongBgTag = true; - } - } - - // If there's no -nosongbg- tag, add the song BG. - if( !bHasNoSongBgTag ) do - { - /* If we're loading cache, -nosongbg- should always be in there. We - * must not call IsAFile(song.GetBackgroundPath()) when loading cache. */ - if( bFromCache ) - break; - - /* If BGChanges already exist after the last beat, don't add the - * background in the middle. */ - if( !bg.empty() && bg.back().m_fStartBeat-0.0001f >= song.m_fLastBeat ) - break; - - // If the last BGA is already the song BGA, don't add a duplicate. - if( !bg.empty() && !bg.back().m_def.m_sFile1.CompareNoCase(song.m_sBackgroundFile) ) - break; - - if( !IsAFile( song.GetBackgroundPath() ) ) - break; - - bg.push_back( BackgroundChange(song.m_fLastBeat,song.m_sBackgroundFile) ); - } while(0); - } + SMLoader::TidyUpData(song, bFromCache); } /* diff --git a/src/TimingData.cpp b/src/TimingData.cpp index bb6911fad4..022976a349 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -8,10 +8,16 @@ #include -TimingData::TimingData() +TimingData::TimingData() : + m_fBeat0OffsetInSeconds(0), + m_bHasNegativeBpms(false) { - m_fBeat0OffsetInSeconds = 0; - m_bHasNegativeBpms = false; +} + +TimingData::TimingData(float fOffset) : + m_fBeat0OffsetInSeconds(fOffset), + m_bHasNegativeBpms(false) +{ } void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const diff --git a/src/TimingData.h b/src/TimingData.h index 5464a8748e..36f1d33456 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -658,6 +658,10 @@ public: * @brief Sets up initial timing data. */ TimingData(); + /** + * @brief Sets up initial timing data with a defined offset. + * @param fOffset the offset from the 0th beat. */ + TimingData(float fOffset); /** * @brief Gets the actual BPM of the song. * @param fMinBPMOut the minimium specified BPM. From fab4cda5ff86d72417c0b166e4fde57485c03435 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 23:35:21 -0400 Subject: [PATCH 016/197] [splittiming] Comment cleanup. --- src/NotesLoaderSSC.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 8af0e084ea..dde0d86e4a 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -21,9 +21,6 @@ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60 KB /** * @brief Attempt to load any background changes in use by this song. - * - * This code is right now copied from NotesLoaderSM. There may be a time - * when we add to this code, or perhaps just refactor it properly. * @param change a reference to the background change. * @param sBGChangeExpression a reference to the list of changes to be made. * @return its success or failure. From 285f227851b31277a8637e9d21cd2c7721186891 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 13:27:35 +0700 Subject: [PATCH 017/197] [splittiming] tie Step's TimingData to player. --- src/Player.cpp | 39 +++++++++++++++++++++++++-------------- src/Player.h | 2 ++ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/Player.cpp b/src/Player.cpp index 2c793bb4c1..95353c1669 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -541,6 +541,8 @@ void Player::Load() if( GAMESTATE->m_pCurGame->m_bAllowHopos ) NoteDataUtil::SetHopoPossibleFlags( pSong, m_NoteData ); + m_Timing = &GAMESTATE->m_pCurSteps[pn]->m_Timing; + switch( GAMESTATE->m_PlayMode ) { case PLAY_MODE_RAVE: @@ -1528,7 +1530,7 @@ int Player::GetClosestNoteDirectional( int col, int iStartRow, int iEndRow, bool // Is this the row we want? do { const TapNote &tn = begin->second; - if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( begin->first ) ) + if( m_Timing->IsWarpAtRow( begin->first ) ) break; if( tn.type == TapNote::empty ) break; @@ -1579,7 +1581,7 @@ int Player::GetClosestNonEmptyRowDirectional( int iStartRow, int iEndRow, bool b ++iter; continue; } - if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iter.Row() ) ) + if( m_Timing->IsWarpAtRow( iter.Row() ) ) { ++iter; continue; @@ -1873,7 +1875,16 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b break; } - const float fSongBeat = GAMESTATE->m_pCurSong ? GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds ) : GAMESTATE->m_fSongBeat; + float fSongBeat = GAMESTATE->m_fSongBeat; + + if( GAMESTATE->m_pCurSong ) + { + fSongBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds ); + + if( GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber] ) + fSongBeat = m_Timing->GetBeatFromElapsedTime( fPositionSeconds ); + } + const int iSongRow = row == -1 ? BeatToNoteRow( fSongBeat ) : row; if( col != -1 && !bRelease ) @@ -2011,8 +2022,8 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b * "jack hammers." Hmm. */ const int iStepSearchRows = max( - BeatToNoteRow( GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds + StepSearchDistance ) ) - iSongRow, - iSongRow - BeatToNoteRow( GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds - StepSearchDistance ) ) + BeatToNoteRow( m_Timing->GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds + StepSearchDistance ) ) - iSongRow, + iSongRow - BeatToNoteRow( m_Timing->GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds - StepSearchDistance ) ) ) + ROWS_PER_BEAT; int iRowOfOverlappingNoteOrRow = row; if( row == -1 ) @@ -2039,7 +2050,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b float fNoteOffset = 0.0f; // we need this later if we are autosyncing const float fStepBeat = NoteRowToBeat( iRowOfOverlappingNoteOrRow ); - const float fStepSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat(fStepBeat); + const float fStepSeconds = m_Timing->GetElapsedTimeFromBeat(fStepBeat); if( row == -1 ) { @@ -2089,7 +2100,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b // Stepped too close to mine? if( !bRelease && ( REQUIRE_STEP_ON_MINES == !bHeld ) && fSecondsFromExact <= GetWindowSeconds(TW_Mine) && - !GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow(iSongRow) ) + !m_Timing->IsWarpAtRow(iSongRow) ) score = TNS_HitMine; break; @@ -2564,7 +2575,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) float fThrowAway; int iWarpBeginRow; float fWarpLength; - GAMESTATE->m_pCurSong->m_SongTiming.GetBeatAndBPSFromElapsedTime( fEarliestTime, fMissIfOlderThanThisBeat, fThrowAway, bFreeze, bDelay, iWarpBeginRow, fWarpLength ); + m_Timing->GetBeatAndBPSFromElapsedTime( fEarliestTime, fMissIfOlderThanThisBeat, fThrowAway, bFreeze, bDelay, iWarpBeginRow, fWarpLength ); iMissIfOlderThanThisRow = BeatToNoteRow( fMissIfOlderThanThisBeat ); if( bFreeze || bDelay ) @@ -2587,7 +2598,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) continue; // Ignore all notes that are skipped via WARPS. - if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iter.Row() ) ) + if( m_Timing->IsWarpAtRow( iter.Row() ) ) continue; if( tn.type == TapNote::mine ) @@ -2622,7 +2633,7 @@ void Player::UpdateJudgedRows() int iRow = iter.Row(); // If row is within a warp section, ignore it. -aj - if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow(iRow) ) + if( m_Timing->IsWarpAtRow(iRow) ) continue; if( iLastSeenRow != iRow ) @@ -2843,13 +2854,13 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now ) int iCheckpointFrequencyRows = ROWS_PER_BEAT/2; if( CHECKPOINTS_USE_TICKCOUNTS ) { - int tickCurrent = GAMESTATE->m_pCurSong->m_SongTiming.GetTickcountAtRow( iLastRowCrossed ); + int tickCurrent = m_Timing->GetTickcountAtRow( iLastRowCrossed ); // There are some charts that don't want tickcounts involved at all. iCheckpointFrequencyRows = (tickCurrent > 0 ? ROWS_PER_BEAT / tickCurrent : 0); } else if( CHECKPOINTS_USE_TIME_SIGNATURES ) { - TimeSignatureSegment tSignature = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) ); + TimeSignatureSegment tSignature = m_Timing->GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) ); // Most songs are in 4/4 time. The frequency for checking tick counts should reflect that. iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.m_iDenominator / (tSignature.m_iNumerator * 4); @@ -2957,7 +2968,7 @@ void Player::HandleTapRowScore( unsigned row ) #endif // Warp hackery. -aj - if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( row ) ) + if( m_Timing->IsWarpAtRow( row ) ) return; if( GAMESTATE->m_bDemonstrationOrJukebox ) @@ -3061,7 +3072,7 @@ void Player::HandleHoldCheckpoint( int iRow, int iNumHoldsHeldThisRow, int iNumH #endif // More warp hackery. -aj - if( GAMESTATE->m_pCurSong->m_SongTiming.IsWarpAtRow( iRow ) ) + if( m_Timing->IsWarpAtRow( iRow ) ) return; // don't accumulate combo if AutoPlay is on. diff --git a/src/Player.h b/src/Player.h index b8923b9372..2d699e4913 100644 --- a/src/Player.h +++ b/src/Player.h @@ -10,6 +10,7 @@ #include "ScreenMessage.h" #include "ThemeMetric.h" #include "InputEventPlus.h" +#include "TimingData.h" class ScoreDisplay; class LifeMeter; @@ -147,6 +148,7 @@ protected: PlayerState *m_pPlayerState; /** @brief The player's present stage stats. */ PlayerStageStats *m_pPlayerStageStats; + TimingData *m_Timing; float m_fNoteFieldHeight; bool m_bPaused; From b634639e8e99f1c71b317a80eb969ed0ffba240a Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 16:00:47 +0700 Subject: [PATCH 018/197] Write timing tags for SSC files. WARN: This does not work with ScreenEdit, yet! --- src/NotesWriterSSC.cpp | 238 +++++++++++++++++++---------------------- src/Song.cpp | 45 +------- src/TimingData.cpp | 50 +++++++++ src/TimingData.h | 5 + 4 files changed, 168 insertions(+), 170 deletions(-) diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 3c4ff71a3b..d24f7f5e9f 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -41,6 +41,111 @@ static RString BackgroundChangeToString( const BackgroundChange &bgc ) return s; } +/** + * @brief Turn a vector of lines into a single line joined by newline characters. + * @param lines the list of lines to join. + * @return the joined lines. */ +static RString JoinLineList( vector &lines ) +{ + for( unsigned i = 0; i < lines.size(); ++i ) + TrimRight( lines[i] ); + + // Skip leading blanks. + unsigned j = 0; + while( j < lines.size() && lines.size() == 0 ) + ++j; + + return join( "\r\n", lines.begin()+j, lines.end() ); +} + + +// A utility class to write timing tags more easily! +struct TimingTagWriter { + + vector *m_pvsLines; + RString m_sNext; + + TimingTagWriter( vector *pvsLines ): m_pvsLines (pvsLines) { } + + void Write( const int row, const char *value ) + { + m_pvsLines->push_back( m_sNext + ssprintf( "%.6f=%s", NoteRowToBeat(row), value ) ); + m_sNext = ","; + } + + void Write( const int row, const float value ) { Write( row, ssprintf( "%.6f", value ) ); } + void Write( const int row, const int value ) { Write( row, ssprintf( "%d", value ) ); } + void Write( const int row, const int a, const int b ) { Write( row, ssprintf( "%d=%d", a, b ) ); } + + void Init( const RString sTag ) { m_sNext = "#" + sTag + ":"; } + void Finish( ) { m_pvsLines->push_back( ( m_sNext != "," ? m_sNext : "" ) + ";" ); } + +}; + +static void GetTimingTags( vector &lines, TimingData timing ) +{ + TimingTagWriter w ( &lines ); + + timing.TidyUpData(); + + w.Init( "BPMS" ); + FOREACH_CONST( BPMSegment, timing.m_BPMSegments, bs ) + w.Write( bs->m_iStartRow, bs->GetBPM() ); + w.Finish(); + + w.Init( "STOPS" ); + FOREACH_CONST( StopSegment, timing.m_StopSegments, ss ) + if( !ss->m_bDelay ) + w.Write( ss->m_iStartRow, ss->m_fStopSeconds ); + w.Finish(); + + w.Init( "DELAYS" ); + FOREACH_CONST( StopSegment, timing.m_StopSegments, ss ) + if( ss->m_bDelay ) + w.Write( ss->m_iStartRow, ss->m_fStopSeconds ); + w.Finish(); + + w.Init( "WARPS" ); + FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws ) + w.Write( ws->m_iStartRow, ws->m_fEndBeat ); + w.Finish(); + + ASSERT( !timing.m_vTimeSignatureSegments.empty() ); + w.Init( "TIMESIGNATURES" ); + FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter ) + w.Write( iter->m_iStartRow, iter->m_iNumerator, iter->m_iDenominator ); + w.Finish(); + + ASSERT( !timing.m_TickcountSegments.empty() ); + w.Init( "TICKCOUNTS" ); + FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, ts ) + w.Write( ts->m_iStartRow, ts->m_iTicks ); + w.Finish(); + + ASSERT( !timing.m_ComboSegments.empty() ); + w.Init( "COMBOS" ); + FOREACH_CONST( ComboSegment, timing.m_ComboSegments, cs ) + w.Write( cs->m_iStartRow, cs->m_iCombo ); + w.Finish(); + + w.Init( "LABELS" ); + FOREACH_CONST( LabelSegment, timing.m_LabelSegments, ls ) + w.Write( ls->m_iStartRow, ls->m_sLabel.c_str() ); + w.Finish(); + +} + +static void WriteTimingTags( RageFile &f, const TimingData &timing ) +{ + + vector lines; + + GetTimingTags( lines, timing ); + + f.PutLine( JoinLineList( lines ) ); + +} + /** * @brief Write out the common tags for .SM files. * @param f the file in question. @@ -106,105 +211,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) break; } - f.Write( "#BPMS:" ); - for( unsigned i=0; im_iStartRow), iter->m_iNumerator, iter->m_iDenominator ) ); - vector::const_iterator iter2 = iter; - iter2++; - if( iter2 != out.m_SongTiming.m_vTimeSignatureSegments.end() ) - f.Write( "," ); - } - f.PutLine( ";" ); - - ASSERT( !out.m_SongTiming.m_TickcountSegments.empty() ); - f.Write( "#TICKCOUNTS:" ); - for( unsigned i=0; i &lines ) -{ - for( unsigned i = 0; i < lines.size(); ++i ) - TrimRight( lines[i] ); - - // Skip leading blanks. - unsigned j = 0; - while( j < lines.size() && lines.size() == 0 ) - ++j; - - return join( "\r\n", lines.begin()+j, lines.end() ); -} - /** * @brief Retrieve the individual batches of NoteData. * @param song the Song in question. @@ -307,19 +297,8 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa lines.push_back( ssprintf( "#CREDIT:%s;", SmEscape(in.GetCredit()).c_str() ) ); - /* - * TODO: Remove this block, transplant above code - * below for Split Timing. -Wolfman2000 */ - lines.push_back( "#BPMS:;" ); - lines.push_back( "#STOPS:;" ); - lines.push_back( "#DELAYS:;" ); - lines.push_back( "#WARPS:;" ); - lines.push_back( "#LABELS:;" ); - lines.push_back( "#TIMESIGNATURES:;" ); - lines.push_back( "#TICKCOUNTS:;" ); - lines.push_back( "#ATTACKS:;" ); - lines.push_back( "#COMBOS:;" ); - + GetTimingTags( lines, in.m_Timing ); + RString sNoteData; in.GetSMNoteData( sNoteData ); @@ -350,6 +329,7 @@ bool NotesWriterSSC::Write( RString sPath, const Song &out, const vector } WriteGlobalTags( f, out ); + if( bSavingCache ) { f.PutLine( ssprintf( "// cache tags:" ) ); diff --git a/src/Song.cpp b/src/Song.cpp index a2c5184425..5e0a6d4287 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -488,18 +488,13 @@ void Song::TidyUpData() m_sArtist = "Unknown artist"; TranslateTitles(); - if( m_SongTiming.m_BPMSegments.empty() ) + m_SongTiming.TidyUpData(); + + FOREACH( Steps *, m_vpSteps, s ) { - LOG->UserLog( "Song file", m_sSongDir + m_sSongFileName, "has no BPM segments, default provided." ); - - m_SongTiming.AddBPMSegment( BPMSegment(0, 60) ); + (*s)->m_Timing.TidyUpData(); } - // Make sure the first BPM segment starts at beat 0. - if( m_SongTiming.m_BPMSegments[0].m_iStartRow != 0 ) - m_SongTiming.m_BPMSegments[0].m_iStartRow = 0; - - if( m_fMusicSampleStartSeconds == -1 || m_fMusicSampleStartSeconds == 0 || m_fMusicSampleStartSeconds+m_fMusicSampleLengthSeconds > this->m_fMusicLengthSeconds ) @@ -790,38 +785,6 @@ void Song::TidyUpData() m_sSongFileName += ".ssc"; } while(0); } - - // If no time signature specified, assume 4/4 time for the whole song. - if( m_SongTiming.m_vTimeSignatureSegments.empty() ) - { - TimeSignatureSegment seg(0, 4, 4); - m_SongTiming.m_vTimeSignatureSegments.push_back( seg ); - } - - /* - * Likewise, if no tickcount signature is specified, assume 2 ticks - * per beat for the entire song. The default of 2 is chosen more - * for compatibility with the Pump Pro series than anything else. - */ - if( m_SongTiming.m_TickcountSegments.empty() ) - { - TickcountSegment seg(0, 2); - m_SongTiming.m_TickcountSegments.push_back( seg ); - } - - // Have a default combo segment of one just in case. - if( m_SongTiming.m_ComboSegments.empty() ) - { - ComboSegment seg(0, 1); - m_SongTiming.m_ComboSegments.push_back( seg ); - } - - // Have a default label segment just in case. - if( m_SongTiming.m_LabelSegments.empty() ) - { - LabelSegment seg(0, "Song Start"); - m_SongTiming.m_LabelSegments.push_back( seg ); - } } void Song::TranslateTitles() diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 022976a349..2f93424bc7 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -1090,6 +1090,56 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) this->SetBPMAtRow( iStartRow, fNewBPM ); } +void TimingData::TidyUpData() +{ + // If there are no BPM segments, provide a default. + if( m_BPMSegments.empty() ) + { + LOG->UserLog( "Song file", m_sFile, "has no BPM segments, default provided." ); + + AddBPMSegment( BPMSegment(0, 60) ); + } + + // Make sure the first BPM segment starts at beat 0. + if( m_BPMSegments[0].m_iStartRow != 0 ) + m_BPMSegments[0].m_iStartRow = 0; + + // If no time signature specified, assume 4/4 time for the whole song. + if( m_vTimeSignatureSegments.empty() ) + { + TimeSignatureSegment seg(0, 4, 4); + m_vTimeSignatureSegments.push_back( seg ); + } + + // Likewise, if no tickcount signature is specified, assume 2 ticks + //per beat for the entire song. The default of 2 is chosen more + //for compatibility with the Pump Pro series than anything else. + if( m_TickcountSegments.empty() ) + { + TickcountSegment seg(0, 2); + m_TickcountSegments.push_back( seg ); + } + + // Have a default combo segment of one just in case. + if( m_ComboSegments.empty() ) + { + ComboSegment seg(0, 1); + m_ComboSegments.push_back( seg ); + } + + // Have a default label segment just in case. + if( m_LabelSegments.empty() ) + { + LabelSegment seg(0, "Song Start"); + m_LabelSegments.push_back( seg ); + } + +} + + + + + bool TimingData::HasBpmChanges() const { return m_BPMSegments.size()>1; diff --git a/src/TimingData.h b/src/TimingData.h index 36f1d33456..2c5ad2ecf6 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -1321,6 +1321,11 @@ public: void InsertRows( int iStartRow, int iRowsToAdd ); void DeleteRows( int iStartRow, int iRowsToDelete ); + /** + * @brief Tidy up the timing data, e.g. provide default BPMs, labels, tickcounts. + */ + void TidyUpData(); + // Lua void PushSelf( lua_State *L ); /** From d0e9e580302232a84b7083df169c2339c9188ff8 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 16:55:00 +0700 Subject: [PATCH 019/197] [splittiming] make ScreenEdit edit the Steps's timing data only. NOTES: now, newly created songs will have the default timing data (60bpm throughout the song) and NoteFields currently doesn't work yet. --- src/NoteField.cpp | 4 +- src/ScreenEdit.cpp | 133 ++++++++++++++++++++--------------------- src/ScreenEditMenu.cpp | 2 +- 3 files changed, 69 insertions(+), 70 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 20e7c08f8b..ea54e2f812 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -742,7 +742,7 @@ void NoteField::DrawPrimitives() // Draw beat bars if( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) { - const vector &vTimeSignatureSegments = GAMESTATE->m_pCurSong->m_SongTiming.m_vTimeSignatureSegments; + const vector &vTimeSignatureSegments = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing.m_vTimeSignatureSegments; int iMeasureIndex = 0; FOREACH_CONST( TimeSignatureSegment, vTimeSignatureSegments, iter ) { @@ -785,7 +785,7 @@ void NoteField::DrawPrimitives() { ASSERT(GAMESTATE->m_pCurSong); - const TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming; + const TimingData &timing = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing; // BPM text FOREACH_CONST( BPMSegment, timing.m_BPMSegments, seg ) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index ce69563960..738c366e32 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -931,7 +931,7 @@ void ScreenEdit::Update( float fDeltaTime ) continue; float fStartedHoldingSeconds = m_pSoundMusic->GetPositionSeconds() - fSecsHeld; - float fStartBeat = max( fStartPlayingAtBeat, m_pSong->m_SongTiming.GetBeatFromElapsedTime(fStartedHoldingSeconds) ); + float fStartBeat = max( fStartPlayingAtBeat, m_pSteps->m_Timing.GetBeatFromElapsedTime(fStartedHoldingSeconds) ); float fEndBeat = max( fStartBeat, GAMESTATE->m_fSongBeat ); fEndBeat = min( fEndBeat, NoteRowToBeat(m_iStopPlayingAt) ); @@ -976,11 +976,11 @@ void ScreenEdit::Update( float fDeltaTime ) float fLastBeat = NoteRowToBeat(m_iStopPlayingAt); if( bButtonIsBeingPressed && m_EditState == STATE_RECORDING ) { - float fSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( fLastBeat ); - fLastBeat = m_pSong->m_SongTiming.GetBeatFromElapsedTime( fSeconds + 0.5f ); + float fSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( fLastBeat ); + fLastBeat = m_pSteps->m_Timing.GetBeatFromElapsedTime( fSeconds + 0.5f ); } - float fStopAtSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStopPlayingAt) ) + 1; + float fStopAtSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStopPlayingAt) ) + 1; if( GAMESTATE->m_fMusicSeconds > fStopAtSeconds ) { // loop @@ -1071,7 +1071,7 @@ void ScreenEdit::UpdateTextInfo() RString sText; sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GAMESTATE->m_fSongBeat ); - sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSong->m_SongTiming.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat) ); + sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat) ); switch( EDIT_MODE.GetValue() ) { DEFAULT_FAIL( EDIT_MODE.GetValue() ); @@ -1129,7 +1129,7 @@ void ScreenEdit::UpdateTextInfo() case EditMode_Home: break; case EditMode_Full: - sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds ); + sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), m_pSteps->m_Timing.m_fBeat0OffsetInSeconds ); sText += ssprintf( PREVIEW_START_FORMAT.GetValue(), PREVIEW_START.GetValue().c_str(), m_pSong->m_fMusicSampleStartSeconds ); sText += ssprintf( PREVIEW_LENGTH_FORMAT.GetValue(), PREVIEW_LENGTH.GetValue().c_str(), m_pSong->m_fMusicSampleLengthSeconds ); break; @@ -1579,7 +1579,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_BPM_UP: case EDIT_BUTTON_BPM_DOWN: { - float fBPM = m_pSong->m_SongTiming.GetBPMAtBeat( GAMESTATE->m_fSongBeat ); + float fBPM = m_pSteps->m_Timing.GetBPMAtBeat( GAMESTATE->m_fSongBeat ); float fDelta; switch( EditB ) { @@ -1600,7 +1600,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } float fNewBPM = fBPM + fDelta; - m_pSong->m_SongTiming.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fNewBPM ); + m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fNewBPM ); (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); } @@ -1627,24 +1627,24 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) fDelta *= 40; } unsigned i; - for( i=0; im_SongTiming.m_StopSegments.size(); i++ ) + for( i=0; im_Timing.m_StopSegments.size(); i++ ) { - if( m_pSong->m_SongTiming.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) + if( m_pSteps->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) break; } - if( i == m_pSong->m_SongTiming.m_StopSegments.size() ) // there is no StopSegment at the current beat + if( i == m_pSteps->m_Timing.m_StopSegments.size() ) // there is no StopSegment at the current beat { // create a new StopSegment if( fDelta > 0 ) - m_pSong->m_SongTiming.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta) ); + m_pSteps->m_Timing.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta) ); } else // StopSegment being modified is m_SongTiming.m_StopSegments[i] { - m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds += fDelta; - if( m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds <= 0 ) - m_pSong->m_SongTiming.m_StopSegments.erase( m_pSong->m_SongTiming.m_StopSegments.begin()+i, - m_pSong->m_SongTiming.m_StopSegments.begin()+i+1); + m_pSteps->m_Timing.m_StopSegments[i].m_fStopSeconds += fDelta; + if( m_pSteps->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 ) + m_pSteps->m_Timing.m_StopSegments.erase( m_pSteps->m_Timing.m_StopSegments.begin()+i, + m_pSteps->m_Timing.m_StopSegments.begin()+i+1); } (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); @@ -1673,13 +1673,13 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) fDelta *= 40; } unsigned i; - for( i=0; im_SongTiming.m_StopSegments.size(); i++ ) + for( i=0; im_Timing.m_StopSegments.size(); i++ ) { - if( m_pSong->m_SongTiming.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) + if( m_pSteps->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) break; } - if( i == m_pSong->m_SongTiming.m_StopSegments.size() ) // there is no delay segment at the current beat + if( i == m_pSteps->m_Timing.m_StopSegments.size() ) // there is no delay segment at the current beat { // create a new delay segment if( fDelta > 0 ) @@ -1687,10 +1687,10 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } else // delay segment being modified is m_SongTiming.m_StopSegments[i] { - m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds += fDelta; - if( m_pSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds <= 0 ) - m_pSong->m_SongTiming.m_StopSegments.erase( m_pSong->m_SongTiming.m_StopSegments.begin()+i, - m_pSong->m_SongTiming.m_StopSegments.begin()+i+1); + m_pSteps->m_Timing.m_StopSegments[i].m_fStopSeconds += fDelta; + if( m_pSteps->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 ) + m_pSteps->m_Timing.m_StopSegments.erase( m_pSteps->m_Timing.m_StopSegments.begin()+i, + m_pSteps->m_Timing.m_StopSegments.begin()+i+1); } (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); @@ -1718,7 +1718,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) else fDelta *= 40; } - m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds += fDelta; + m_pSteps->m_Timing.m_fBeat0OffsetInSeconds += fDelta; (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); } @@ -1900,7 +1900,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( pCourse == NULL ) break; CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; - float fStartTime = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); + float fStartTime = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); int iAttack = FindAttackAtTime( ce.attacks, fStartTime ); if( iAttack >= 0 ) @@ -1941,7 +1941,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } else { - fStart = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); + fStart = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); int iAttack = FindAttackAtTime( ce.attacks, fStart ); if( iAttack >= 0 ) @@ -1950,7 +1950,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( m_NoteFieldEdit.m_iEndMarker == -1 ) fEnd = m_pSong->m_fMusicLengthSeconds; else - fEnd = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); + fEnd = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); } g_fLastInsertAttackPositionSeconds = fStart; g_fLastInsertAttackDurationSeconds = fEnd - fStart; @@ -2265,7 +2265,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB ) fOffsetDelta *= 40; } - m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds += fOffsetDelta; + m_pSteps->m_Timing.m_fBeat0OffsetInSeconds += fOffsetDelta; } break; } @@ -2381,8 +2381,8 @@ void ScreenEdit::TransitionEditState( EditState em ) AdjustSync::ResetOriginalSyncData(); /* Give a 1 second lead-in. If we're loading Player, this must be done first. */ - float fSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1; - GAMESTATE->UpdateSongPosition( fSeconds, m_pSong->m_SongTiming ); + float fSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1; + GAMESTATE->UpdateSongPosition( fSeconds, m_pSteps->m_Timing ); GAMESTATE->m_bGameplayLeadIn.Set( false ); @@ -2463,7 +2463,7 @@ void ScreenEdit::TransitionEditState( EditState em ) { case STATE_PLAYING: case STATE_RECORDING: - const float fStartSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat); + const float fStartSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat); LOG->Trace( "Starting playback at %f", fStartSeconds ); RageSoundParams p; @@ -2627,21 +2627,21 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { float fBPM = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fBPM > 0 ) - m_pSong->m_SongTiming.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fBPM ); + m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fBPM ); SetDirty( true ); } else if( SM == SM_BackFromStopChange ) { float fStop = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fStop >= 0 ) - m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, fStop ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, fStop ); SetDirty( true ); } else if( SM == SM_BackFromDelayChange ) { float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fDelay >= 0 ) - m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, fDelay, true ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, fDelay, true ); SetDirty( true ); } else if( SM == SM_BackFromTimeSignatureNumeratorChange ) @@ -2649,7 +2649,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iNum = atoi( ScreenTextEntry::s_sLastAnswer ); if( iNum > 0 ) { - m_pSong->m_SongTiming.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_fSongBeat, iNum ); + m_pSteps->m_Timing.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_fSongBeat, iNum ); } SetDirty( true ); } @@ -2658,7 +2658,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iDen = atoi( ScreenTextEntry::s_sLastAnswer ); if( iDen > 0) { - m_pSong->m_SongTiming.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_fSongBeat, iDen ); + m_pSteps->m_Timing.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_fSongBeat, iDen ); } SetDirty( true ); } @@ -2667,7 +2667,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iTick = atoi( ScreenTextEntry::s_sLastAnswer ); if ( iTick >= 0 && iTick <= ROWS_PER_BEAT ) { - m_pSong->m_SongTiming.SetTickcountAtBeat( GAMESTATE->m_fSongBeat, iTick ); + m_pSteps->m_Timing.SetTickcountAtBeat( GAMESTATE->m_fSongBeat, iTick ); } SetDirty( true ); } @@ -2676,25 +2676,25 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iCombo = atoi( ScreenTextEntry::s_sLastAnswer ); if ( iCombo >= 0 ) { - m_pSong->m_SongTiming.SetComboAtBeat( GAMESTATE->m_fSongBeat, iCombo ); + m_pSteps->m_Timing.SetComboAtBeat( GAMESTATE->m_fSongBeat, iCombo ); } SetDirty( true ); } else if ( SM == SM_BackFromLabelChange ) { RString sLabel = ScreenTextEntry::s_sLastAnswer; - if ( !m_pSong->m_SongTiming.DoesLabelExist(sLabel) ) + if ( !m_pSteps->m_Timing.DoesLabelExist(sLabel) ) { sLabel.Replace("=", "_"); sLabel.Replace(",", "_"); - m_pSong->m_SongTiming.SetLabelAtBeat( GAMESTATE->m_fSongBeat, sLabel ); + m_pSteps->m_Timing.SetLabelAtBeat( GAMESTATE->m_fSongBeat, sLabel ); SetDirty( true ); } } else if ( SM == SM_BackFromWarpChange ) { float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer ); - m_pSong->m_SongTiming.SetWarpAtBeat( GAMESTATE->m_fSongBeat, fWarp ); + m_pSteps->m_Timing.SetWarpAtBeat( GAMESTATE->m_fSongBeat, fWarp ); SetDirty( true ); } else if( SM == SM_BackFromBGChange ) @@ -2767,7 +2767,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; int iAttack; - g_fLastInsertAttackPositionSeconds = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); + g_fLastInsertAttackPositionSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); g_fLastInsertAttackDurationSeconds = StringToFloat( g_InsertCourseAttack.rows[0].choices[iDurationChoice] ); iAttack = FindAttackAtTime( ce.attacks, g_fLastInsertAttackPositionSeconds ); @@ -3024,7 +3024,7 @@ static void ChangeArtistTranslit( const RString &sNew ) static void ChangeBeat0Offset( const RString &sNew ) { - GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); + GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); } static void ChangeLastBeatHint( const RString &sNew ) @@ -3255,9 +3255,8 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns break; case edit_timing_data: { - const Song* pSong = GAMESTATE->m_pCurSong; - TimingData pTime = pSong->m_SongTiming; - const float fBeat = GAMESTATE->m_fSongBeat; + TimingData pTime = m_pSteps->m_Timing; + const float fBeat = pTime.GetBeatFromElapsedTime(GAMESTATE->m_fMusicSeconds); g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); @@ -3501,7 +3500,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex ); // scale timing data - m_pSong->m_SongTiming.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); + m_pSteps->m_Timing.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); // scale all other steps. const vector sIter = m_pSong->GetAllSteps(); @@ -3546,16 +3545,16 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); break; case shift_pauses_forward: - m_pSong->m_SongTiming.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); + m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); break; case shift_pauses_backward: - m_pSong->m_SongTiming.DeleteRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); + m_pSteps->m_Timing.DeleteRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); break; case convert_to_pause: { ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - float fMarkerStart = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); - float fMarkerEnd = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); + float fMarkerStart = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); + float fMarkerEnd = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); // The length of the stop segment we're going to create. This includes time spent in any // stops in the selection, which will be deleted and subsumed into the new stop. @@ -3567,9 +3566,9 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns m_NoteFieldEdit.m_iBeginMarker + 1, m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); - m_pSong->m_SongTiming.DeleteRows( m_NoteFieldEdit.m_iBeginMarker, + m_pSteps->m_Timing.DeleteRows( m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); - m_pSong->m_SongTiming.SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); + m_pSteps->m_Timing.SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); m_NoteFieldEdit.m_iBeginMarker = -1; m_NoteFieldEdit.m_iEndMarker = -1; break; @@ -3577,14 +3576,14 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case convert_pause_to_beat: { // TODO: Convert both Delays and Stops at once. - float fStopSeconds = m_pSong->m_SongTiming.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ); - m_pSong->m_SongTiming.SetStopAtBeat( GAMESTATE->m_fSongBeat, 0 ); + float fStopSeconds = m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, 0 ); - float fStopBeats = fStopSeconds * m_pSong->m_SongTiming.GetBPMAtBeat(GAMESTATE->m_fSongBeat) / 60; + float fStopBeats = fStopSeconds * m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_fSongBeat) / 60; // don't move the step from where it is, just move everything later NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); - m_pSong->m_SongTiming.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); + m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); } break; case undo: @@ -3701,7 +3700,7 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec break; case beat_0_offset: ScreenTextEntry::TextEntry( SM_None, ENTER_BEAT_0_OFFSET, - ssprintf("%.5f", pSong->m_SongTiming.m_fBeat0OffsetInSeconds), 20, + ssprintf("%.5f", m_pSteps->m_Timing.m_fBeat0OffsetInSeconds), 20, ScreenTextEntry::FloatValidate, ChangeBeat0Offset, NULL ); break; case last_beat_hint: @@ -3750,7 +3749,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromBPMChange, ENTER_BPM_VALUE, - ssprintf( "%.4f", m_pSong->m_SongTiming.GetBPMAtBeat(GAMESTATE->m_fSongBeat) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_fSongBeat) ), 10 ); break; @@ -3758,7 +3757,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromStopChange, ENTER_STOP_VALUE, - ssprintf( "%.4f", m_pSong->m_SongTiming.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), 10 ); break; @@ -3766,7 +3765,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromDelayChange, ENTER_DELAY_VALUE, - ssprintf( "%.4f", m_pSong->m_SongTiming.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), 10 ); break; @@ -3774,7 +3773,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureNumeratorChange, ENTER_TIME_SIGNATURE_NUMERATOR_VALUE, - ssprintf( "%d", m_pSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator ), + ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator ), 3 ); break; @@ -3782,7 +3781,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureDenominatorChange, ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE, - ssprintf( "%d", m_pSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iDenominator ), + ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iDenominator ), 3 ); break; @@ -3790,7 +3789,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTickcountChange, ENTER_TICKCOUNT_VALUE, - ssprintf( "%d", m_pSong->m_SongTiming.GetTickcountAtBeat( GAMESTATE->m_fSongBeat ) ), + ssprintf( "%d", m_pSteps->m_Timing.GetTickcountAtBeat( GAMESTATE->m_fSongBeat ) ), 2 ); break; @@ -3798,7 +3797,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromComboChange, ENTER_COMBO_VALUE, - ssprintf( "%d", m_pSong->m_SongTiming.GetComboAtBeat( GAMESTATE->m_fSongBeat ) ), + ssprintf( "%d", m_pSteps->m_Timing.GetComboAtBeat( GAMESTATE->m_fSongBeat ) ), 4 ); break; @@ -3806,7 +3805,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromLabelChange, ENTER_LABEL_VALUE, - ssprintf( "%s", m_pSong->m_SongTiming.GetLabelAtBeat( GAMESTATE->m_fSongBeat ).c_str() ), + ssprintf( "%s", m_pSteps->m_Timing.GetLabelAtBeat( GAMESTATE->m_fSongBeat ).c_str() ), 64 ); break; @@ -3814,7 +3813,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromWarpChange, ENTER_WARP_VALUE, - ssprintf( "%.4f", m_pSong->m_SongTiming.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), 10 ); break; diff --git a/src/ScreenEditMenu.cpp b/src/ScreenEditMenu.cpp index 04bb81e213..1bf4997aea 100644 --- a/src/ScreenEditMenu.cpp +++ b/src/ScreenEditMenu.cpp @@ -236,7 +236,7 @@ void ScreenEditMenu::MenuStart( const InputEventPlus &input ) case EditMenuAction_Create: ASSERT( !pSteps ); { - pSteps = new Steps; + pSteps = pSong->CreateSteps(); switch( m_Selector.EDIT_MODE ) { From ce91d1a4314e5ab78a00089bf4db0593b04cfe47 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 17:44:12 +0700 Subject: [PATCH 020/197] [splittiming] load split timing from ssc files --- src/NotesLoaderSM.cpp | 7 ++++- src/NotesLoaderSM.h | 2 +- src/NotesLoaderSSC.cpp | 59 ++++++++++++++++++++---------------------- src/NotesLoaderSSC.h | 2 -- src/Song.cpp | 6 +++++ 5 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 3fa6432713..a8633ba3d8 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -103,7 +103,7 @@ bool SMLoader::LoadTimingFromFile( const RString &fn, TimingData &out ) return true; } -void SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) +bool SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) { vector arrayBPMChangeExpressions; split( sParam, ",", arrayBPMChangeExpressions ); @@ -112,6 +112,7 @@ void SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) float negBeat = -1; float negBPM = 1; float highspeedBeat = -1; + bool bNotEmpty = false; for( unsigned b=0; bm_Timing = out.m_Timing; + if( bHasOwnTiming ) + pNewNotes->m_Timing = stepsTiming; pNewNotes->SetSMNoteData( sParams[1] ); pNewNotes->TidyUpData(); out.AddSteps( pNewNotes ); } - - else if( sValueName=="BPMS" ) // This must ALWAYS be here in Split Timing. + + else if( sValueName=="BPMS" ) { - state = GETTING_STEP_TIMING_INFO; - /* - pNewNotes->m_Timing = TimingData(out.m_SongTiming.m_fBeat0OffsetInSeconds); - SMLoader::ProcessBPMs(pNewNotes->m_Timing, sParams[1]); - */ - + if( SMLoader::ProcessBPMs(stepsTiming, sParams[1]) ) + bHasOwnTiming = true; } - break; - } - case GETTING_STEP_TIMING_INFO: - { - if( sValueName=="STOPS" ) + + else if( sValueName=="STOPS" ) { - // SMLoader::ProcessStops(pNewNotes->m_Timing, sParams[1]); + SMLoader::ProcessStops(stepsTiming, sParams[1]); } + else if( sValueName=="DELAYS" ) { - // SMLoader::ProcessDelays(pNewNotes->m_Timing, sParams[1]); + SMLoader::ProcessDelays(stepsTiming, sParams[1]); } + else if( sValueName=="TIMESIGNATURES" ) { - // SMLoader::ProcessTimeSignatures(pNewNotes->m_Timing, sParams[1]); + SMLoader::ProcessTimeSignatures(stepsTiming, sParams[1]); } + else if( sValueName=="TICKCOUNTS" ) { - // SMLoader::ProcessTickcounts(pNewNotes->m_Timing, sParams[1]); + SMLoader::ProcessTickcounts(stepsTiming, sParams[1]); } + else if( sValueName=="COMBOS" ) { - // ProcessCombos(pNewNotes->m_Timing, sParams[1]); + ProcessCombos(stepsTiming, sParams[1]); } + else if( sValueName=="WARPS" ) { - // ProcessWarps(pNewNotes->m_Timing, sParams[1]); + ProcessWarps(stepsTiming, sParams[1]); } + else if( sValueName=="LABELS" ) { - // ProcessLabels(pNewNotes->m_Timing, sParams[1]); + ProcessLabels(stepsTiming, sParams[1]); } + else if( sValueName=="ATTACKS" ) { // TODO: Look into Step attacks vs Song Attacks. -Wolfman2000 @@ -635,18 +640,10 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach } */ } + else if( sValueName=="OFFSET" ) - {/* - pNewNotes->m_Timing.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] ); - */ - } - - else if( sValueName=="NOTES" || sValueName=="NOTES2" ) { - state = GETTING_SONG_INFO; - pNewNotes->SetSMNoteData( sParams[1] ); - pNewNotes->TidyUpData(); - out.AddSteps( pNewNotes ); + stepsTiming.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] ); } break; } diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index bf85bdd73c..7d185cc690 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -16,8 +16,6 @@ enum SSCLoadingStates { GETTING_SONG_INFO, /**< Retrieving song information. */ GETTING_STEP_INFO, /**< Retrieving step information. */ - GETTING_STEP_TIMING_INFO, /**< Retrieving a step's individual timing information. */ - GETTING_NOTE_INFO, /**< Retrieving the specific notes. This state may be deprecated. */ NUM_SSCLoadingStates /**< The number of states used. */ }; diff --git a/src/Song.cpp b/src/Song.cpp index 5e0a6d4287..c5986b0284 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -863,6 +863,12 @@ void Song::Save() ReCalculateRadarValuesAndLastBeat(); TranslateTitles(); + + // TODO: Figure out a better way to save to Song's timing data. + if( m_vpSteps.size() == 1 ) + { + m_SongTiming = m_vpSteps[0]->m_Timing; + } // Save the new files. These calls make backups on their own. if( !SaveToSSCFile(GetSongFilePath(), false) ) From 241738c18b97618bae76a82323d5d94fa483ea28 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 19:54:05 +0700 Subject: [PATCH 021/197] [splittiming] Let's break things again! (222) We introduced a new class, called "SongPosition", that replaces some instance variables in the GameState class. (GameState::m_Position). Then, you also have it in PlayerState class which keeps track of the position based on their steps. (PlayerState::m_Position). Fixing the build errors: - GAMESTATE->m_fSomething should now be: - GAMESTATE->m_Position.m_fSomething - pPlayerState->m_Position.m_fSomething (or m_pPlayerState for some instance!) --- Xcode/stepmania.xcodeproj/project.pbxproj | 8 +++ src/GameState.cpp | 52 ++--------------- src/GameState.h | 25 +------- src/Player.cpp | 6 +- src/PlayerState.h | 4 ++ src/SongPosition.cpp | 63 +++++++++++++++++++++ src/SongPosition.h | 69 +++++++++++++++++++++++ 7 files changed, 156 insertions(+), 71 deletions(-) create mode 100644 src/SongPosition.cpp create mode 100644 src/SongPosition.h diff --git a/Xcode/stepmania.xcodeproj/project.pbxproj b/Xcode/stepmania.xcodeproj/project.pbxproj index a70652bcd4..30eba612d7 100644 --- a/Xcode/stepmania.xcodeproj/project.pbxproj +++ b/Xcode/stepmania.xcodeproj/project.pbxproj @@ -1653,6 +1653,8 @@ AAFF41A40F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.h in Headers */ = {isa = PBXBuildFile; fileRef = AAFF41A20F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.h */; }; AAFF41A50F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAFF41A10F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.cpp */; }; AAFF41A60F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.h in Headers */ = {isa = PBXBuildFile; fileRef = AAFF41A20F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.h */; }; + B75CE3B5137963350076A82D /* SongPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = B75CE3B3137963350076A82D /* SongPosition.h */; }; + B75CE3B6137963350076A82D /* SongPosition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B75CE3B4137963350076A82D /* SongPosition.cpp */; }; EE2153A910A75BEE0074B01B /* NotesLoaderPMS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE2153A710A75BEE0074B01B /* NotesLoaderPMS.cpp */; }; EE2153AA10A75BEE0074B01B /* NotesLoaderPMS.h in Headers */ = {isa = PBXBuildFile; fileRef = EE2153A810A75BEE0074B01B /* NotesLoaderPMS.h */; }; EE879B60132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE879B5C132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp */; }; @@ -3017,6 +3019,8 @@ AAFF55220549F43A00D02EE9 /* ComboGraph.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ComboGraph.h; path = ../src/ComboGraph.h; sourceTree = ""; }; AAFF5541054E736D00D02EE9 /* Attack.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = Attack.cpp; path = ../src/Attack.cpp; sourceTree = ""; }; AAFF5542054E736D00D02EE9 /* Attack.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = Attack.h; path = ../src/Attack.h; sourceTree = ""; }; + B75CE3B3137963350076A82D /* SongPosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SongPosition.h; path = ../src/SongPosition.h; sourceTree = SOURCE_ROOT; }; + B75CE3B4137963350076A82D /* SongPosition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SongPosition.cpp; path = ../src/SongPosition.cpp; sourceTree = SOURCE_ROOT; }; EE2153A710A75BEE0074B01B /* NotesLoaderPMS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesLoaderPMS.cpp; path = ../src/NotesLoaderPMS.cpp; sourceTree = SOURCE_ROOT; }; EE2153A810A75BEE0074B01B /* NotesLoaderPMS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NotesLoaderPMS.h; path = ../src/NotesLoaderPMS.h; sourceTree = SOURCE_ROOT; }; EE879B5C132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RageDisplay_Legacy_Helpers.cpp; path = ../src/RageDisplay_Legacy_Helpers.cpp; sourceTree = SOURCE_ROOT; }; @@ -3925,6 +3929,8 @@ AA7CDD930D8395F90001DAFC /* Song.h */, AA6EFE0704770C79005F316C /* SongOptions.cpp */, AA6EFE0804770C79005F316C /* SongOptions.h */, + B75CE3B4137963350076A82D /* SongPosition.cpp */, + B75CE3B3137963350076A82D /* SongPosition.h */, AA5C73F90637A5F000AFB891 /* SongUtil.cpp */, AA5C73FA0637A5F000AFB891 /* SongUtil.h */, AAEBF57C0B5C83F4005F3C7C /* SoundEffectControl.cpp */, @@ -5042,6 +5048,7 @@ 2BC6132D13773C8E00CC8BBD /* pngpriv.h in Headers */, 2BC6133313773C8E00CC8BBD /* pngstruct.h in Headers */, 2BC6133E13773D2C00CC8BBD /* pnglibconf.h in Headers */, + B75CE3B5137963350076A82D /* SongPosition.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6301,6 +6308,7 @@ 2BC6133813773C8E00CC8BBD /* pngwrite.c in Sources */, 2BC6133913773C8E00CC8BBD /* pngwtran.c in Sources */, 2BC6133A13773C8E00CC8BBD /* pngwutil.c in Sources */, + B75CE3B6137963350076A82D /* SongPosition.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/GameState.cpp b/src/GameState.cpp index 90792cad8c..6f3dc9f6a0 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -951,53 +951,13 @@ static Preference g_fVisualDelaySeconds( "VisualDelaySeconds", 0.0f ); void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp ) { - if( !timestamp.IsZero() ) - m_LastBeatUpdate = timestamp; - else - m_LastBeatUpdate.Touch(); + + m_Position.UpdateSongPosition( fPositionSeconds, timing, timestamp ); - // xxx testing: only do this on monotune survivor - /* - if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" ) - LOG->Trace( ssprintf("[GameState::UpdateSongPosition] cur BPS = %f, fPositionSeconds = %f",m_fCurBPS,fPositionSeconds) ); - */ - - timing.GetBeatAndBPSFromElapsedTime( fPositionSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze, m_bDelay, m_iWarpBeginRow, m_fWarpDestination ); - // "Crash reason : -243478.890625 -48695.773438" - ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds", m_fSongBeat, fPositionSeconds) ); - - m_fMusicSeconds = fPositionSeconds; - - m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds ); - - m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); - - m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get(); - float fThrowAway, fThrowAway2; - bool bThrowAway; - int iThrowAway; - timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway, iThrowAway, fThrowAway2 ); - - /* - // xxx testing: only do this on monotune survivor - if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" ) - { - // and only do it in the known negative bpm region. HACKITY HACK - if(m_fSongBeat >= 445.490f && m_fSongBeat <= 453.72f) - { - LOG->Trace( ssprintf("fPositionSeconds = %f",fPositionSeconds) ); - LOG->Trace( ssprintf("Song beat: %f (%f seconds), BPS = %f (%f BPM)",m_fSongBeat,m_fMusicSecondsVisible,m_fCurBPS,m_fCurBPS*60.0f) ); - //LOG->Trace( ssprintf("Music seconds visible %f = fPositionSeconds %f - g_fVisualDelaySeconds %f", m_fMusicSecondsVisible,fPositionSeconds,g_fVisualDelaySeconds.Get()) ); - } - else if(m_fSongBeat == 445.500f) - { - LOG->Trace( ssprintf("[beat 445.500] fPositionSeconds = %f",fPositionSeconds) ); - LOG->Trace( ssprintf("Song beat: %f (%f seconds), BPS = %f (%f BPM)",m_fSongBeat,m_fMusicSecondsVisible,m_fCurBPS,m_fCurBPS*60.0f) ); - } - } - */ - - Actor::SetBGMTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fPositionSeconds, m_fSongBeatNoOffset ); + FOREACH_EnabledPlayer( pn ) + m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); + + Actor::SetBGMTime( m_Position.m_fMusicSecondsVisible, m_Position.m_fSongBeatVisible, m_Position.fPositionSeconds, m_Position.m_fSongBeatNoOffset ); // LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze ); } diff --git a/src/GameState.h b/src/GameState.h index 406e4784b1..9b192156c3 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -10,6 +10,7 @@ #include "RageTimer.h" #include "PlayerOptions.h" #include "SongOptions.h" +#include "SongPosition.h" #include "Preference.h" #include @@ -194,29 +195,9 @@ public: bool m_bBackedOutOfFinalStage; // Music statistics: - // Arcade - the current stage (one song). - // Oni/Endless - a single song in a course. - // Let a lot of classes access this info here so they don't have to keep their own copies. - // todo: [NUM_PLAYERS] this for split bpm lolol -aj - float m_fMusicSeconds; // time into the current song, not scaled by music rate - float m_fSongBeat; - float m_fSongBeatNoOffset; - float m_fCurBPS; - float m_fLightSongBeat; // g_fLightsFalloffSeconds ahead - //bool m_bStop; // in the middle of a stop (freeze or delay) - /** @brief A flag to determine if we're in the middle of a freeze/stop. */ - bool m_bFreeze; - /** @brief A flag to determine if we're in the middle of a delay (Pump style stop). */ - bool m_bDelay; - /** @brief The row used to start a warp. */ - int m_iWarpBeginRow; - /** @brief The beat to warp to afterwards. */ - float m_fWarpDestination; - RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update - BroadcastOnChange m_bGameplayLeadIn; + SongPosition m_Position; - float m_fMusicSecondsVisible; - float m_fSongBeatVisible; + BroadcastOnChange m_bGameplayLeadIn; // if re-adding noteskin changes in courses, add functions and such here -aj void GetAllUsedNoteSkins( vector &out ) const; diff --git a/src/Player.cpp b/src/Player.cpp index 95353c1669..1843553ade 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -506,7 +506,7 @@ void Player::Load() m_LastTapNoteScore = TNS_None; // The editor can start playing in the middle of the song. - const int iNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ); + const int iNoteRow = BeatToNoteRowNotRounded( m_pPlayerState->m_Position.m_fSongBeat ); m_iFirstUncrossedRow = iNoteRow - 1; m_pJudgedRows->Reset( iNoteRow ); @@ -695,7 +695,7 @@ void Player::Update( float fDeltaTime ) return; } - const float fSongBeat = GAMESTATE->m_fSongBeat; + const float fSongBeat = m_pPlayerState->m_Position.m_fSongBeat; const int iSongRow = BeatToNoteRow( fSongBeat ); // Optimization: Don't spend time processing the things below that won't show @@ -797,7 +797,7 @@ void Player::Update( float fDeltaTime ) // Check for a strum miss if( m_pPlayerState->m_fLastStrumMusicSeconds != -1 && - m_pPlayerState->m_fLastStrumMusicSeconds + g_fTimingWindowStrum < GAMESTATE->m_fMusicSeconds ) + m_pPlayerState->m_fLastStrumMusicSeconds + g_fTimingWindowStrum < m_pPlayerState->m_Position.m_fMusicSeconds ) { DoStrumMiss(); } diff --git a/src/PlayerState.h b/src/PlayerState.h index 6df9dc662d..59239ca915 100644 --- a/src/PlayerState.h +++ b/src/PlayerState.h @@ -3,6 +3,7 @@ #ifndef PlayerState_H #define PlayerState_H +#include "SongPosition.h" #include "Attack.h" #include "ModsGroup.h" #include "PlayerNumber.h" @@ -38,6 +39,9 @@ public: */ MultiPlayer m_mp; + // Music statistics: + SongPosition m_Position; + /** * @brief Change the PlayerOptions to their default. * @param l the level of mods to reset. diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp new file mode 100644 index 0000000000..c3e6c30ffc --- /dev/null +++ b/src/SongPosition.cpp @@ -0,0 +1,63 @@ +/* + * SongPosition.cpp + * stepmania + * + * Created by [Full Username] on 5/10/11. + * Copyright 2011 [Organization Name]. All rights reserved. + * + */ + +#include "SongPosition.h" + +void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp ) +{ + + if( !timestamp.IsZero() ) + m_LastBeatUpdate = timestamp; + else + m_LastBeatUpdate.Touch(); + + // xxx testing: only do this on monotune survivor + /* + if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" ) + LOG->Trace( ssprintf("[GameState::UpdateSongPosition] cur BPS = %f, fPositionSeconds = %f",m_fCurBPS,fPositionSeconds) ); + */ + + timing.GetBeatAndBPSFromElapsedTime( fPositionSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze, m_bDelay, m_iWarpBeginRow, m_fWarpDestination ); + + // "Crash reason : -243478.890625 -48695.773438" + ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds", m_fSongBeat, fPositionSeconds) ); + + m_fMusicSeconds = fPositionSeconds; + + m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds ); + + m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); + + m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get(); + float fThrowAway, fThrowAway2; + bool bThrowAway; + int iThrowAway; + timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway, iThrowAway, fThrowAway2 ); + + /* + // xxx testing: only do this on monotune survivor + if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" ) + { + // and only do it in the known negative bpm region. HACKITY HACK + if(m_fSongBeat >= 445.490f && m_fSongBeat <= 453.72f) + { + LOG->Trace( ssprintf("fPositionSeconds = %f",fPositionSeconds) ); + LOG->Trace( ssprintf("Song beat: %f (%f seconds), BPS = %f (%f BPM)",m_fSongBeat,m_fMusicSecondsVisible,m_fCurBPS,m_fCurBPS*60.0f) ); + //LOG->Trace( ssprintf("Music seconds visible %f = fPositionSeconds %f - g_fVisualDelaySeconds %f", m_fMusicSecondsVisible,fPositionSeconds,g_fVisualDelaySeconds.Get()) ); + } + else if(m_fSongBeat == 445.500f) + { + LOG->Trace( ssprintf("[beat 445.500] fPositionSeconds = %f",fPositionSeconds) ); + LOG->Trace( ssprintf("Song beat: %f (%f seconds), BPS = %f (%f BPM)",m_fSongBeat,m_fMusicSecondsVisible,m_fCurBPS,m_fCurBPS*60.0f) ); + } + } + */ + + +} diff --git a/src/SongPosition.h b/src/SongPosition.h new file mode 100644 index 0000000000..8890e3a87d --- /dev/null +++ b/src/SongPosition.h @@ -0,0 +1,69 @@ +#ifndef SONGPOSITION_H +#define SONGPOSITION_H + +#include "GameConstantsAndTypes.h" +#include "RageTimer.h" +#include "LightsManager.h" +#include "MessageManager.h" +#include "TimingData.h" + +class SongPosition +{ + + public: + + // Arcade - the current stage (one song). + // Oni/Endless - a single song in a course. + // Let a lot of classes access this info here so they don't have to keep their own copies. + // todo: [NUM_PLAYERS] this for split bpm lolol -aj + float m_fMusicSeconds; // time into the current song, not scaled by music rate + float m_fSongBeat; + float m_fSongBeatNoOffset; + float m_fCurBPS; + float m_fLightSongBeat; // g_fLightsFalloffSeconds ahead + //bool m_bStop; // in the middle of a stop (freeze or delay) + /** @brief A flag to determine if we're in the middle of a freeze/stop. */ + bool m_bFreeze; + /** @brief A flag to determine if we're in the middle of a delay (Pump style stop). */ + bool m_bDelay; + /** @brief The row used to start a warp. */ + int m_iWarpBeginRow; + /** @brief The beat to warp to afterwards. */ + float m_fWarpDestination; + RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update + + float m_fMusicSecondsVisible; + float m_fSongBeatVisible; + + void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp = RageZeroTimer ); + +}; + +#endif + +/** + * @file + * @author Chris Danford, Glenn Maynard (c) 2001-2004 + * @section LICENSE + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ From 5d4c63bf5ace421a700f5db02e6d1fbde555481c Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 10 May 2011 08:58:24 -0400 Subject: [PATCH 022/197] [splittiming] The .edit files matter too. Maybe we need a new extension for edits. --- src/NotesLoaderSSC.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index ab7da6b480..59c7aed3ee 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -684,6 +684,8 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat Song* pSong = NULL; Steps* pNewNotes = NULL; bool bSSCFormat = false; + bool bHasOwnTiming = false; + TimingData stepsTiming; for( unsigned i=0; im_Timing = stepsTiming; + } pNewNotes->SetSMNoteData( sParams[1] ); pNewNotes->TidyUpData(); pSong->AddSteps( pNewNotes ); From d8068767bb0bf676a427808b303c343fe1f6c8b4 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 10 May 2011 09:02:31 -0400 Subject: [PATCH 023/197] [splittiming] Thai, your file. Your credit. --- src/SongPosition.cpp | 37 ++++++++++++++++++++++++++++--------- src/SongPosition.h | 2 +- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp index c3e6c30ffc..60c5587016 100644 --- a/src/SongPosition.cpp +++ b/src/SongPosition.cpp @@ -1,12 +1,3 @@ -/* - * SongPosition.cpp - * stepmania - * - * Created by [Full Username] on 5/10/11. - * Copyright 2011 [Organization Name]. All rights reserved. - * - */ - #include "SongPosition.h" void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp ) @@ -61,3 +52,31 @@ void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData } + +/** + * @file + * @author Thai Pangsakulyanont (c) 2011 + * @section LICENSE + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + diff --git a/src/SongPosition.h b/src/SongPosition.h index 8890e3a87d..1e4226ef84 100644 --- a/src/SongPosition.h +++ b/src/SongPosition.h @@ -43,7 +43,7 @@ class SongPosition /** * @file - * @author Chris Danford, Glenn Maynard (c) 2001-2004 + * @author Thai Pangsakulyanont (c) 2011 * @section LICENSE * All rights reserved. * From e1e605b736b369850fccf6b4dcb1239db4202038 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 20:03:51 +0700 Subject: [PATCH 024/197] [splittiming] move bogus variables back to GameState (210) --- src/GameState.cpp | 8 +++++++- src/GameState.h | 2 ++ src/SongPosition.cpp | 7 ------- src/SongPosition.h | 3 --- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index 6f3dc9f6a0..9ad930dcd3 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -957,7 +957,13 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti FOREACH_EnabledPlayer( pn ) m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); - Actor::SetBGMTime( m_Position.m_fMusicSecondsVisible, m_Position.m_fSongBeatVisible, m_Position.fPositionSeconds, m_Position.m_fSongBeatNoOffset ); + m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get(); + float fThrowAway, fThrowAway2; + bool bThrowAway; + int iThrowAway; + timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway, iThrowAway, fThrowAway2 ); + + Actor::SetBGMTime( m_Position.m_fMusicSecondsVisible, m_Position.m_fSongBeatVisible, fPositionSeconds, m_Position.m_fSongBeatNoOffset ); // LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze ); } diff --git a/src/GameState.h b/src/GameState.h index 9b192156c3..f0446c28b8 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -196,6 +196,8 @@ public: // Music statistics: SongPosition m_Position; + float m_fMusicSecondsVisible; + float m_fSongBeatVisible; BroadcastOnChange m_bGameplayLeadIn; diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp index c3e6c30ffc..f6e6afb35b 100644 --- a/src/SongPosition.cpp +++ b/src/SongPosition.cpp @@ -34,12 +34,6 @@ void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); - m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get(); - float fThrowAway, fThrowAway2; - bool bThrowAway; - int iThrowAway; - timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway, iThrowAway, fThrowAway2 ); - /* // xxx testing: only do this on monotune survivor if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" ) @@ -59,5 +53,4 @@ void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData } */ - } diff --git a/src/SongPosition.h b/src/SongPosition.h index 8890e3a87d..4571ca29d4 100644 --- a/src/SongPosition.h +++ b/src/SongPosition.h @@ -32,9 +32,6 @@ class SongPosition float m_fWarpDestination; RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update - float m_fMusicSecondsVisible; - float m_fSongBeatVisible; - void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp = RageZeroTimer ); }; From 38a4852180b28eef3257bc70fbf9a68b4bece22f Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 20:18:17 +0700 Subject: [PATCH 025/197] [splittiming] Fix Player.cpp (198) --- src/Player.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Player.cpp b/src/Player.cpp index 1843553ade..e885c2bf9c 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -919,12 +919,12 @@ void Player::Update( float fDeltaTime ) /* We want to send the crossed row message exactly when we cross the row--not * .5 before the row. Use a very slow song (around 2 BPM) as a test case: without * rounding, autoplay steps early. -glenn */ - const int iRowNow = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ); + const int iRowNow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat ); if( iRowNow >= 0 ) { if( GAMESTATE->IsPlayerEnabled(m_pPlayerState) ) { - if(GAMESTATE->m_bDelay) + if(m_pPlayerState->m_Position.m_bDelay) { if( !m_bDelay ) m_bDelay = true; @@ -1652,7 +1652,7 @@ void Player::Fret( int col, int row, const RageTimer &tm, bool bHeld, bool bRele } // Handle hammer-ons and pull-offs - const float fPositionSeconds = GAMESTATE->m_fMusicSeconds - tm.Ago(); + const float fPositionSeconds = m_pPlayerState->m_Position.m_fMusicSeconds - tm.Ago(); int iHopoCol = -1; bool bDoHopo = m_pPlayerState->m_fLastHopoNoteMusicSeconds != -1 && @@ -1705,7 +1705,7 @@ void Player::Fret( int col, int row, const RageTimer &tm, bool bHeld, bool bRele // Check if this fret breaks all active holds. if( !bRelease ) { - const float fSongBeat = GAMESTATE->m_fSongBeat; + const float fSongBeat = m_pPlayerState->m_Position.m_fSongBeat; const int iSongRow = BeatToNoteRow( fSongBeat ); int iMaxHoldCol = -1; @@ -1747,7 +1747,7 @@ void Player::Strum( int col, int row, const RageTimer &tm, bool bHeld, bool bRel DoStrumMiss(); } - m_pPlayerState->m_fLastStrumMusicSeconds = GAMESTATE->m_fMusicSeconds; + m_pPlayerState->m_fLastStrumMusicSeconds = m_pPlayerState->m_Position.m_fMusicSeconds; StepStrumHopo( col, row, tm, bHeld, bRelease, ButtonType_StrumFretsChanged ); } @@ -1796,7 +1796,7 @@ void Player::ScoreAllActiveHoldsLetGo() { if( PENALIZE_TAP_SCORE_NONE ) { - const float fSongBeat = GAMESTATE->m_fSongBeat; + const float fSongBeat = m_pPlayerState->m_Position.m_fSongBeat; const int iSongRow = BeatToNoteRow( fSongBeat ); // Score all active holds to NotHeld @@ -1859,8 +1859,8 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b // Do everything that depends on a RageTimer here; // set your breakpoints somewhere after this block. - const float fLastBeatUpdate = GAMESTATE->m_LastBeatUpdate.Ago(); - const float fPositionSeconds = GAMESTATE->m_fMusicSeconds - tm.Ago(); + const float fLastBeatUpdate = m_pPlayerState->m_Position.m_LastBeatUpdate.Ago(); + const float fPositionSeconds = m_pPlayerState->m_Position.m_fMusicSeconds - tm.Ago(); const float fTimeSinceStep = tm.Ago(); switch( pbt ) @@ -1875,7 +1875,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b break; } - float fSongBeat = GAMESTATE->m_fSongBeat; + float fSongBeat = m_pPlayerState->m_Position.m_fSongBeat; if( GAMESTATE->m_pCurSong ) { @@ -2059,7 +2059,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b /* GAMESTATE->m_fMusicSeconds is the music time as of GAMESTATE->m_LastBeatUpdate. Figure * out what the music time is as of now. */ - const float fCurrentMusicSeconds = GAMESTATE->m_fMusicSeconds + (fLastBeatUpdate*GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate); + const float fCurrentMusicSeconds = m_pPlayerState->m_Position.m_fMusicSeconds + (fLastBeatUpdate*GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate); // ... which means it happened at this point in the music: const float fMusicSeconds = fCurrentMusicSeconds - fTimeSinceStep * GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; @@ -2568,7 +2568,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) { //LOG->Trace( "Steps::UpdateTapNotesMissedOlderThan(%f)", fMissIfOlderThanThisBeat ); int iMissIfOlderThanThisRow; - const float fEarliestTime = GAMESTATE->m_fMusicSeconds - fMissIfOlderThanSeconds; + const float fEarliestTime = m_pPlayerState->m_Position.m_fMusicSeconds - fMissIfOlderThanSeconds; { bool bFreeze, bDelay; float fMissIfOlderThanThisBeat; @@ -2621,7 +2621,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) void Player::UpdateJudgedRows() { - const int iEndRow = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + const int iEndRow = BeatToNoteRow( m_pPlayerState->m_Position.m_fSongBeat ); bool bAllJudged = true; const bool bSeparately = GAMESTATE->GetCurrentGame()->m_bCountNotesSeparately; @@ -3268,7 +3268,7 @@ void Player::SetCombo( int iCombo, int iMisses ) } else { - bPastBeginning = GAMESTATE->m_fMusicSeconds > GAMESTATE->m_pCurSong->m_fMusicLengthSeconds * PERCENT_UNTIL_COLOR_COMBO; + bPastBeginning = m_pPlayerState->m_Position.m_fMusicSeconds > GAMESTATE->m_pCurSong->m_fMusicLengthSeconds * PERCENT_UNTIL_COLOR_COMBO; } if( m_bSendJudgmentAndComboMessages ) From ab8b76b3b85ad35405f161d7626eda86a34f76c0 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 20:27:12 +0700 Subject: [PATCH 026/197] [splittiming] NoteDisplay, NoteField, Player, PlayerState (182) --- src/NoteDisplay.cpp | 2 +- src/NoteField.cpp | 14 +++++++------- src/Player.cpp | 4 ++-- src/PlayerState.cpp | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/NoteDisplay.cpp b/src/NoteDisplay.cpp index 3998c1fb08..a5c530bd73 100644 --- a/src/NoteDisplay.cpp +++ b/src/NoteDisplay.cpp @@ -286,7 +286,7 @@ void NoteDisplay::Update( float fDeltaTime ) void NoteDisplay::SetActiveFrame( float fNoteBeat, Actor &actorToSet, float fAnimationLength, bool bVivid ) { /* -inf ... inf */ - float fBeatOrSecond = cache->m_bAnimationBasedOnBeats ? GAMESTATE->m_fSongBeat : GAMESTATE->m_fMusicSeconds; + float fBeatOrSecond = cache->m_bAnimationBasedOnBeats ? m_pPlayerState->m_Position.m_fSongBeat : m_pPlayerState->m_Position.m_fMusicSeconds; /* -len ... +len */ float fPercentIntoAnimation = fmodf( fBeatOrSecond, fAnimationLength ); /* -1 ... 1 */ diff --git a/src/NoteField.cpp b/src/NoteField.cpp index ea54e2f812..c4c6826765 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -240,7 +240,7 @@ void NoteField::Update( float fDeltaTime ) ActorFrame::Update( fDeltaTime ); // update m_fBoardOffsetPixels, m_fCurrentBeatLastUpdate, m_fYPosCurrentBeatLastUpdate - const float fCurrentBeat = GAMESTATE->m_fSongBeat; + const float fCurrentBeat = m_pPlayerState->m_Position.m_fSongBeat; bool bTweeningOn = m_sprBoard->GetCurrentDiffuseAlpha() >= 0.98 && m_sprBoard->GetCurrentDiffuseAlpha() < 1.00; // HACK if( !bTweeningOn && m_fCurrentBeatLastUpdate != -1 ) { @@ -606,7 +606,7 @@ void NoteField::DrawBGChangeText( const float fBeat, const RString sNewBGName ) // change this probing to binary search float FindFirstDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceAfterTargetsPixels ) { - float fFirstBeatToDraw = GAMESTATE->m_fSongBeat-4; // Adjust to balance off performance and showing enough notes. + float fFirstBeatToDraw = pPlayerState->m_Position.m_fSongBeat-4; // Adjust to balance off performance and showing enough notes. /* In Boomerang, we'll usually have two sections of notes: before and after * the peak. We always start drawing before the peak, and end after it, or @@ -618,7 +618,7 @@ float FindFirstDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistance bBoomerang = (fAccels[PlayerOptions::ACCEL_BOOMERANG] != 0); } - while( fFirstBeatToDraw < GAMESTATE->m_fSongBeat ) + while( fFirstBeatToDraw < m_pPlayerState->m_Position.m_fSongBeat ) { bool bIsPastPeakYOffset; float fPeakYOffset; @@ -640,7 +640,7 @@ float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceB // Probe for last note to draw. Worst case is 0.25x + boost. // Adjust search distance so that notes don't pop onto the screen. float fSearchDistance = 10; - float fLastBeatToDraw = GAMESTATE->m_fSongBeat+fSearchDistance; + float fLastBeatToDraw = pPlayerState->m_Position.m_fSongBeat+fSearchDistance; const int NUM_ITERATIONS = 20; @@ -1045,7 +1045,7 @@ void NoteField::DrawPrimitives() displayCols->display[c].DrawHold( tn, c, iStartRow, bIsHoldingNote, Result, bUseAdditionColoring, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, m_fYReverseOffsetPixels, (float) iDrawDistanceAfterTargetsPixels, (float) iDrawDistanceBeforeTargetsPixels, iDrawDistanceBeforeTargetsPixels, FADE_BEFORE_TARGETS_PERCENT ); - bool bNoteIsUpcoming = NoteRowToBeat(iStartRow) > GAMESTATE->m_fSongBeat; + bool bNoteIsUpcoming = NoteRowToBeat(iStartRow) > m_pPlayerState->m_Position.m_fSongBeat; bAnyUpcomingInThisCol |= bNoteIsUpcoming; } } @@ -1087,7 +1087,7 @@ void NoteField::DrawPrimitives() continue; // skip ASSERT_M( NoteRowToBeat(q) > -2000, ssprintf("%i %i %i, %f %f", q, iLastRowToDraw, - iFirstRowToDraw, GAMESTATE->m_fSongBeat, GAMESTATE->m_fMusicSeconds) ); + iFirstRowToDraw, m_pPlayerState->m_Position.m_fSongBeat, m_pPlayerState->m_Position.m_fMusicSeconds) ); // See if there is a hold step that begins on this index. // Only do this if the noteskin cares. @@ -1117,7 +1117,7 @@ void NoteField::DrawPrimitives() m_fYReverseOffsetPixels, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels, FADE_BEFORE_TARGETS_PERCENT ); - bool bNoteIsUpcoming = NoteRowToBeat(q) > GAMESTATE->m_fSongBeat; + bool bNoteIsUpcoming = NoteRowToBeat(q) > m_pPlayerState->m_Position.m_fSongBeat; bAnyUpcomingInThisCol |= bNoteIsUpcoming; } diff --git a/src/Player.cpp b/src/Player.cpp index e885c2bf9c..f992b838d5 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2022,8 +2022,8 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b * "jack hammers." Hmm. */ const int iStepSearchRows = max( - BeatToNoteRow( m_Timing->GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds + StepSearchDistance ) ) - iSongRow, - iSongRow - BeatToNoteRow( m_Timing->GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds - StepSearchDistance ) ) + BeatToNoteRow( m_Timing->GetBeatFromElapsedTime( m_pPlayerState->m_Position.m_fMusicSeconds + StepSearchDistance ) ) - iSongRow, + iSongRow - BeatToNoteRow( m_Timing->GetBeatFromElapsedTime( m_pPlayerState->m_Position.m_fMusicSeconds - StepSearchDistance ) ) ) + ROWS_PER_BEAT; int iRowOfOverlappingNoteOrRow = row; if( row == -1 ) diff --git a/src/PlayerState.cpp b/src/PlayerState.cpp index 070e96c7be..d6583059bf 100644 --- a/src/PlayerState.cpp +++ b/src/PlayerState.cpp @@ -69,8 +69,8 @@ void PlayerState::Update( float fDelta ) bool bCurrentlyEnabled = attack.bGlobal || - ( attack.fStartSecond < GAMESTATE->m_fMusicSeconds && - GAMESTATE->m_fMusicSeconds < attack.fStartSecond+attack.fSecsRemaining ); + ( attack.fStartSecond < m_Position.m_fMusicSeconds && + m_Position.m_fMusicSeconds < attack.fStartSecond+attack.fSecsRemaining ); if( m_ActiveAttacks[s].bOn == bCurrentlyEnabled ) continue; // OK @@ -116,7 +116,7 @@ void PlayerState::LaunchAttack( const Attack& a ) * so Player::Update knows to apply attack transforms correctly. (yuck) */ m_ModsToApply.push_back( attack ); if( attack.fStartSecond == -1 ) - attack.fStartSecond = GAMESTATE->m_fMusicSeconds; + attack.fStartSecond = m_Position.m_fMusicSeconds; m_ActiveAttacks.push_back( attack ); RebuildPlayerOptionsFromActiveAttacks(); From 722d22dffc196ef4fe432c127ced5dae551e7c7d Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 21:21:23 +0700 Subject: [PATCH 027/197] [splittiming] temporary fix for ScreenEdit. It uses song position for now. (82) So once it builds we have to test it extensively to see where it could be wrong. --- src/ScreenEdit.cpp | 184 +++++++++++++++++++++++---------------------- 1 file changed, 93 insertions(+), 91 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 738c366e32..929bc974cc 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -722,8 +722,10 @@ void ScreenEdit::Init() GAMESTATE->m_bGameplayLeadIn.Set( true ); GAMESTATE->m_EditMode = EDIT_MODE.GetValue(); - GAMESTATE->m_fSongBeat = 0; - m_fTrailingBeat = GAMESTATE->m_fSongBeat; + GAMESTATE->m_Position.m_fSongBeat = 0; + FOREACH_PlayerNumber( p ) + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = 0; + m_fTrailingBeat = GAMESTATE->m_Position.m_fSongBeat; m_iShiftAnchor = -1; m_iStartPlayingAt = -1; @@ -927,12 +929,12 @@ void ScreenEdit::Update( float fDeltaTime ) continue; float fStartPlayingAtBeat = NoteRowToBeat(m_iStartPlayingAt); - if( GAMESTATE->m_fSongBeat <= fStartPlayingAtBeat ) + if( GAMESTATE->m_Position.m_fSongBeat <= fStartPlayingAtBeat ) continue; float fStartedHoldingSeconds = m_pSoundMusic->GetPositionSeconds() - fSecsHeld; float fStartBeat = max( fStartPlayingAtBeat, m_pSteps->m_Timing.GetBeatFromElapsedTime(fStartedHoldingSeconds) ); - float fEndBeat = max( fStartBeat, GAMESTATE->m_fSongBeat ); + float fEndBeat = max( fStartBeat, GAMESTATE->m_Position.m_fSongBeat ); fEndBeat = min( fEndBeat, NoteRowToBeat(m_iStopPlayingAt) ); // Round start and end to the nearest snap interval @@ -981,7 +983,7 @@ void ScreenEdit::Update( float fDeltaTime ) } float fStopAtSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStopPlayingAt) ) + 1; - if( GAMESTATE->m_fMusicSeconds > fStopAtSeconds ) + if( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fMusicSeconds > fStopAtSeconds ) { // loop TransitionEditState( STATE_PLAYING ); @@ -994,12 +996,12 @@ void ScreenEdit::Update( float fDeltaTime ) // Update trailing beat - float fDelta = GAMESTATE->m_fSongBeat - m_fTrailingBeat; + float fDelta = GAMESTATE->m_Position.m_fSongBeat - m_fTrailingBeat; if( fabsf(fDelta) < 10 ) - fapproach( m_fTrailingBeat, GAMESTATE->m_fSongBeat, + fapproach( m_fTrailingBeat, GAMESTATE->m_Position.m_fSongBeat, fDeltaTime*40 / m_NoteFieldEdit.GetPlayerState()->m_PlayerOptions.GetCurrent().m_fScrollSpeed ); else - fapproach( m_fTrailingBeat, GAMESTATE->m_fSongBeat, + fapproach( m_fTrailingBeat, GAMESTATE->m_Position.m_fSongBeat, fabsf(fDelta) * fDeltaTime*5 ); PlayTicks(); @@ -1070,8 +1072,8 @@ void ScreenEdit::UpdateTextInfo() RString sNoteType = ssprintf( NOTES.GetValue(), NoteTypeToLocalizedString(m_SnapDisplay.GetNoteType()).c_str() ); RString sText; - sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GAMESTATE->m_fSongBeat ); - sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat) ); + sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GAMESTATE->m_Position.m_fSongBeat ); + sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_Position.m_fSongBeat) ); switch( EDIT_MODE.GetValue() ) { DEFAULT_FAIL( EDIT_MODE.GetValue() ); @@ -1141,14 +1143,14 @@ void ScreenEdit::UpdateTextInfo() void ScreenEdit::DrawPrimitives() { // HACK: Draw using the trailing beat - float fSongBeat = GAMESTATE->m_fSongBeat; // save song beat - float fSongBeatNoOffset = GAMESTATE->m_fSongBeatNoOffset; + float fSongBeat = GAMESTATE->m_Position.m_fSongBeat; // save song beat + float fSongBeatNoOffset = GAMESTATE->m_Position.m_fSongBeatNoOffset; float fSongBeatVisible = GAMESTATE->m_fSongBeatVisible; if( !m_pSoundMusic->IsPlaying() ) { - GAMESTATE->m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect - GAMESTATE->m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect + GAMESTATE->m_Position.m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect + GAMESTATE->m_Position.m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect GAMESTATE->m_fSongBeatVisible = m_fTrailingBeat; // put trailing beat in effect } @@ -1156,8 +1158,8 @@ void ScreenEdit::DrawPrimitives() if( !m_pSoundMusic->IsPlaying() ) { - GAMESTATE->m_fSongBeat = fSongBeat; // restore real song beat - GAMESTATE->m_fSongBeatNoOffset = fSongBeatNoOffset; + GAMESTATE->m_Position.m_fSongBeat = fSongBeat; // restore real song beat + GAMESTATE->m_Position.m_fSongBeatNoOffset = fSongBeatNoOffset; GAMESTATE->m_fSongBeatVisible = fSongBeatVisible; } } @@ -1243,7 +1245,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) m_iShiftAnchor = -1; return; } - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator; + int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ).m_iNumerator; switch( EditB ) { @@ -1269,7 +1271,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) ShiftToRightSide( iCol, m_NoteDataEdit.GetNumTracks() ); - const float fSongBeat = GAMESTATE->m_fSongBeat; + const float fSongBeat = GAMESTATE->m_Position.m_fSongBeat; const int iSongIndex = BeatToNoteRow( fSongBeat ); if( iCol >= m_NoteDataEdit.GetNumTracks() ) // this button is not in the range of columns for this Style @@ -1407,7 +1409,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( m_PlayerStateEdit.m_PlayerOptions.GetSong().m_fScrolls[PlayerOptions::SCROLL_REVERSE] > 0.5 ) fBeatsToMove *= -1; - float fDestinationBeat = GAMESTATE->m_fSongBeat + fBeatsToMove; + float fDestinationBeat = GAMESTATE->m_Position.m_fSongBeat + fBeatsToMove; fDestinationBeat = Quantize( fDestinationBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); ScrollTo( fDestinationBeat ); @@ -1415,28 +1417,28 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_SCROLL_NEXT_MEASURE: { - float fDestinationBeat = GAMESTATE->m_fSongBeat + beatsPerMeasure; + float fDestinationBeat = GAMESTATE->m_Position.m_fSongBeat + beatsPerMeasure; fDestinationBeat = ftruncf( fDestinationBeat, (float)beatsPerMeasure ); ScrollTo( fDestinationBeat ); break; } case EDIT_BUTTON_SCROLL_PREV_MEASURE: { - float fDestinationBeat = QuantizeUp( GAMESTATE->m_fSongBeat, (float)beatsPerMeasure ); + float fDestinationBeat = QuantizeUp( GAMESTATE->m_Position.m_fSongBeat, (float)beatsPerMeasure ); fDestinationBeat -= (float)beatsPerMeasure; ScrollTo( fDestinationBeat ); break; } case EDIT_BUTTON_SCROLL_NEXT: { - int iRow = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + int iRow = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); NoteDataUtil::GetNextEditorPosition( m_NoteDataEdit, iRow ); ScrollTo( NoteRowToBeat(iRow) ); } break; case EDIT_BUTTON_SCROLL_PREV: { - int iRow = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + int iRow = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); NoteDataUtil::GetPrevEditorPosition( m_NoteDataEdit, iRow ); ScrollTo( NoteRowToBeat(iRow) ); } @@ -1444,13 +1446,13 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_LABEL_NEXT: { ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming. - GetNextLabelSegmentBeatAtBeat( GAMESTATE->m_fSongBeat ) ); + GetNextLabelSegmentBeatAtBeat( GAMESTATE->m_Position.m_fSongBeat ) ); } break; case EDIT_BUTTON_LABEL_PREV: { ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming. - GetPreviousLabelSegmentBeatAtBeat( GAMESTATE->m_fSongBeat ) ); + GetPreviousLabelSegmentBeatAtBeat( GAMESTATE->m_Position.m_fSongBeat ) ); } break; case EDIT_BUTTON_SNAP_NEXT: @@ -1463,11 +1465,11 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_LAY_SELECT: { - const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_fSongBeat); + const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); if( m_NoteFieldEdit.m_iBeginMarker==-1 && m_NoteFieldEdit.m_iEndMarker==-1 ) { // lay begin marker - m_NoteFieldEdit.m_iBeginMarker = BeatToNoteRow(GAMESTATE->m_fSongBeat); + m_NoteFieldEdit.m_iBeginMarker = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); } else if( m_NoteFieldEdit.m_iEndMarker==-1 ) // only begin marker is laid { @@ -1579,7 +1581,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_BPM_UP: case EDIT_BUTTON_BPM_DOWN: { - float fBPM = m_pSteps->m_Timing.GetBPMAtBeat( GAMESTATE->m_fSongBeat ); + float fBPM = m_pSteps->m_Timing.GetBPMAtBeat( GAMESTATE->m_Position.m_fSongBeat ); float fDelta; switch( EditB ) { @@ -1600,7 +1602,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } float fNewBPM = fBPM + fDelta; - m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fNewBPM ); + m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_Position.m_fSongBeat, fNewBPM ); (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); } @@ -1629,7 +1631,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) unsigned i; for( i=0; im_Timing.m_StopSegments.size(); i++ ) { - if( m_pSteps->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) + if( m_pSteps->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) break; } @@ -1637,7 +1639,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { // create a new StopSegment if( fDelta > 0 ) - m_pSteps->m_Timing.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta) ); + m_pSteps->m_Timing.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), fDelta) ); } else // StopSegment being modified is m_SongTiming.m_StopSegments[i] { @@ -1675,7 +1677,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) unsigned i; for( i=0; im_Timing.m_StopSegments.size(); i++ ) { - if( m_pSteps->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) ) + if( m_pSteps->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) break; } @@ -1683,7 +1685,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { // create a new delay segment if( fDelta > 0 ) - m_pSong->AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fDelta, true) ); + m_pSong->AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), fDelta, true) ); } else // delay segment being modified is m_SongTiming.m_StopSegments[i] { @@ -1807,7 +1809,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) BackgroundChange bgChange; FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer), bgc ) { - if( bgc->m_fStartBeat == GAMESTATE->m_fSongBeat ) + if( bgc->m_fStartBeat == GAMESTATE->m_Position.m_fSongBeat ) { bAlreadyBGChangeHere = true; bgChange = *bgc; @@ -1900,7 +1902,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( pCourse == NULL ) break; CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; - float fStartTime = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); + float fStartTime = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_Position.m_fSongBeat ); int iAttack = FindAttackAtTime( ce.attacks, fStartTime ); if( iAttack >= 0 ) @@ -1974,10 +1976,10 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) bool bAlreadyBGChangeHere = false; BackgroundLayer iLayer = BACKGROUND_LAYER_1; BackgroundChange bgChange; - bgChange.m_fStartBeat = GAMESTATE->m_fSongBeat; + bgChange.m_fStartBeat = GAMESTATE->m_Position.m_fSongBeat; FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(iLayer), bgc ) { - if( bgc->m_fStartBeat == GAMESTATE->m_fSongBeat ) + if( bgc->m_fStartBeat == GAMESTATE->m_Position.m_fSongBeat ) { bAlreadyBGChangeHere = true; bgChange = *bgc; @@ -2012,12 +2014,12 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { if( g_iDefaultRecordLength.Get() == -1 ) { - m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_fSongBeat); + m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); m_iStopPlayingAt = max( m_iStartPlayingAt, m_NoteDataEdit.GetLastRow() + 1 ); } else { - m_iStartPlayingAt = BeatToNoteRow( ftruncf(GAMESTATE->m_fSongBeat, g_iDefaultRecordLength.Get()) ); + m_iStartPlayingAt = BeatToNoteRow( ftruncf(GAMESTATE->m_Position.m_fSongBeat, g_iDefaultRecordLength.Get()) ); m_iStopPlayingAt = m_iStartPlayingAt + BeatToNoteRow( g_iDefaultRecordLength.Get() ); } @@ -2034,7 +2036,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } break; case EDIT_BUTTON_RECORD_FROM_CURSOR: - m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_fSongBeat); + m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); m_iStopPlayingAt = max( m_iStartPlayingAt, m_NoteDataEdit.GetLastRow() ); TransitionEditState( STATE_RECORDING ); break; @@ -2103,7 +2105,7 @@ void ScreenEdit::InputRecord( const InputEventPlus &input, EditButton EditB ) } // Add a tap - float fBeat = GAMESTATE->m_fSongBeat; + float fBeat = GAMESTATE->m_Position.m_fSongBeat; fBeat = Quantize( fBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); const int iRow = BeatToNoteRow( fBeat ); @@ -2239,7 +2241,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB ) { case EDIT_BUTTON_RETURN_TO_EDIT: /* When exiting play mode manually, leave the cursor where it is. */ - m_fBeatToReturnTo = GAMESTATE->m_fSongBeat; + m_fBeatToReturnTo = GAMESTATE->m_Position.m_fSongBeat; TransitionEditState( STATE_EDITING ); break; case EDIT_BUTTON_OFFSET_UP: @@ -2310,7 +2312,7 @@ void ScreenEdit::TransitionEditState( EditState em ) { case STATE_EDITING: // If exiting EDIT mode, save the cursor position. - m_fBeatToReturnTo = GAMESTATE->m_fSongBeat; + m_fBeatToReturnTo = GAMESTATE->m_Position.m_fSongBeat; break; case STATE_PLAYING: @@ -2363,14 +2365,14 @@ void ScreenEdit::TransitionEditState( EditState em ) m_Foreground.Unload(); // Restore the cursor position. - GAMESTATE->m_fSongBeat = m_fBeatToReturnTo; + GAMESTATE->m_Position.m_fSongBeat = m_fBeatToReturnTo; // Make sure we're snapped. - GAMESTATE->m_fSongBeat = Quantize( GAMESTATE->m_fSongBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); + GAMESTATE->m_Position.m_fSongBeat = Quantize( GAMESTATE->m_Position.m_fSongBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); /* Playing and recording have lead-ins, which may start before beat 0; * make sure we don't stay there if we escaped out early. */ - GAMESTATE->m_fSongBeat = max( GAMESTATE->m_fSongBeat, 0 ); + GAMESTATE->m_Position.m_fSongBeat = max( GAMESTATE->m_Position.m_fSongBeat, 0 ); break; @@ -2463,7 +2465,7 @@ void ScreenEdit::TransitionEditState( EditState em ) { case STATE_PLAYING: case STATE_RECORDING: - const float fStartSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_fSongBeat); + const float fStartSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_Position.m_fSongBeat); LOG->Trace( "Starting playback at %f", fStartSeconds ); RageSoundParams p; @@ -2483,11 +2485,11 @@ void ScreenEdit::ScrollTo( float fDestinationBeat ) CLAMP( fDestinationBeat, 0, GetMaximumBeatForMoving() ); // Don't play the sound and do the hold note logic below if our position didn't change. - const float fOriginalBeat = GAMESTATE->m_fSongBeat; + const float fOriginalBeat = GAMESTATE->m_Position.m_fSongBeat; if( fOriginalBeat == fDestinationBeat ) return; - GAMESTATE->m_fSongBeat = fDestinationBeat; + GAMESTATE->m_Position.m_fSongBeat = fDestinationBeat; // check to see if they're holding a button for( int n=0; n 0 ) - m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_fSongBeat, fBPM ); + m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_Position.m_fSongBeat, fBPM ); SetDirty( true ); } else if( SM == SM_BackFromStopChange ) { float fStop = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fStop >= 0 ) - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, fStop ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_Position.m_fSongBeat, fStop ); SetDirty( true ); } else if( SM == SM_BackFromDelayChange ) { float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fDelay >= 0 ) - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, fDelay, true ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_Position.m_fSongBeat, fDelay, true ); SetDirty( true ); } else if( SM == SM_BackFromTimeSignatureNumeratorChange ) @@ -2649,7 +2651,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iNum = atoi( ScreenTextEntry::s_sLastAnswer ); if( iNum > 0 ) { - m_pSteps->m_Timing.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_fSongBeat, iNum ); + m_pSteps->m_Timing.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_Position.m_fSongBeat, iNum ); } SetDirty( true ); } @@ -2658,7 +2660,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iDen = atoi( ScreenTextEntry::s_sLastAnswer ); if( iDen > 0) { - m_pSteps->m_Timing.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_fSongBeat, iDen ); + m_pSteps->m_Timing.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_Position.m_fSongBeat, iDen ); } SetDirty( true ); } @@ -2667,7 +2669,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iTick = atoi( ScreenTextEntry::s_sLastAnswer ); if ( iTick >= 0 && iTick <= ROWS_PER_BEAT ) { - m_pSteps->m_Timing.SetTickcountAtBeat( GAMESTATE->m_fSongBeat, iTick ); + m_pSteps->m_Timing.SetTickcountAtBeat( GAMESTATE->m_Position.m_fSongBeat, iTick ); } SetDirty( true ); } @@ -2676,7 +2678,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iCombo = atoi( ScreenTextEntry::s_sLastAnswer ); if ( iCombo >= 0 ) { - m_pSteps->m_Timing.SetComboAtBeat( GAMESTATE->m_fSongBeat, iCombo ); + m_pSteps->m_Timing.SetComboAtBeat( GAMESTATE->m_Position.m_fSongBeat, iCombo ); } SetDirty( true ); } @@ -2687,14 +2689,14 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { sLabel.Replace("=", "_"); sLabel.Replace(",", "_"); - m_pSteps->m_Timing.SetLabelAtBeat( GAMESTATE->m_fSongBeat, sLabel ); + m_pSteps->m_Timing.SetLabelAtBeat( GAMESTATE->m_Position.m_fSongBeat, sLabel ); SetDirty( true ); } } else if ( SM == SM_BackFromWarpChange ) { float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer ); - m_pSteps->m_Timing.SetWarpAtBeat( GAMESTATE->m_fSongBeat, fWarp ); + m_pSteps->m_Timing.SetWarpAtBeat( GAMESTATE->m_Position.m_fSongBeat, fWarp ); SetDirty( true ); } else if( SM == SM_BackFromBGChange ) @@ -2745,7 +2747,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { PlayerOptions poChosen = GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.GetPreferred(); RString sMods = poChosen.GetString(); - const int row = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + const int row = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); TapNote tn( TapNote::attack, @@ -2767,7 +2769,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; int iAttack; - g_fLastInsertAttackPositionSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_fSongBeat ); + g_fLastInsertAttackPositionSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_Position.m_fSongBeat ); g_fLastInsertAttackDurationSeconds = StringToFloat( g_InsertCourseAttack.rows[0].choices[iDurationChoice] ); iAttack = FindAttackAtTime( ce.attacks, g_fLastInsertAttackPositionSeconds ); @@ -2922,12 +2924,12 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { /* When another screen comes up, RageSounds takes over the sound timer. When we come * back, put the timer back to where it was. */ - GAMESTATE->m_fSongBeat = m_fTrailingBeat; + GAMESTATE->m_Position.m_fSongBeat = m_fTrailingBeat; } else if( SM == SM_LoseFocus ) { // Snap the trailing beat, in case we lose focus while tweening. - m_fTrailingBeat = GAMESTATE->m_fSongBeat; + m_fTrailingBeat = GAMESTATE->m_Position.m_fSongBeat; } ScreenWithMenuElements::HandleScreenMessage( SM ); @@ -2938,10 +2940,10 @@ void ScreenEdit::OnSnapModeChange() m_soundChangeSnap.Play(); NoteType nt = m_SnapDisplay.GetNoteType(); - int iStepIndex = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + int iStepIndex = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); int iElementsPerNoteType = BeatToNoteRow( NoteTypeToBeat(nt) ); int iStepIndexHangover = iStepIndex % iElementsPerNoteType; - GAMESTATE->m_fSongBeat -= NoteRowToBeat( iStepIndexHangover ); + GAMESTATE->m_Position.m_fSongBeat -= NoteRowToBeat( iStepIndexHangover ); } @@ -3088,14 +3090,14 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns break; case play_current_beat_to_end: { - m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_fSongBeat); + m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); m_iStopPlayingAt = max( m_iStartPlayingAt, m_NoteDataEdit.GetLastRow() ); TransitionEditState( STATE_PLAYING ); } break; case set_selection_start: { - const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_fSongBeat); + const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); if( m_NoteFieldEdit.m_iEndMarker!=-1 && iCurrentRow >= m_NoteFieldEdit.m_iEndMarker ) { SCREENMAN->PlayInvalidSound(); @@ -3109,7 +3111,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns break; case set_selection_end: { - const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_fSongBeat); + const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); if( m_NoteFieldEdit.m_iBeginMarker!=-1 && iCurrentRow <= m_NoteFieldEdit.m_iBeginMarker ) { SCREENMAN->PlayInvalidSound(); @@ -3256,7 +3258,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns case edit_timing_data: { TimingData pTime = m_pSteps->m_Timing; - const float fBeat = pTime.GetBeatFromElapsedTime(GAMESTATE->m_fMusicSeconds); + const float fBeat = GAMESTATE->m_Position.m_fSongBeat; g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); @@ -3361,7 +3363,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns { DEFAULT_FAIL( c ); case paste_at_current_beat: - iDestFirstRow = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + iDestFirstRow = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); break; case paste_at_begin_marker: ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 ); @@ -3539,16 +3541,16 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns TransitionEditState( STATE_RECORDING ); break; case insert_and_shift: - NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); + NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), BeatToNoteRow(1) ); break; case delete_and_shift: - NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); + NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), BeatToNoteRow(1) ); break; case shift_pauses_forward: - m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); + m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), BeatToNoteRow(1) ); break; case shift_pauses_backward: - m_pSteps->m_Timing.DeleteRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(1) ); + m_pSteps->m_Timing.DeleteRows( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), BeatToNoteRow(1) ); break; case convert_to_pause: { @@ -3576,14 +3578,14 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case convert_pause_to_beat: { // TODO: Convert both Delays and Stops at once. - float fStopSeconds = m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ); - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_fSongBeat, 0 ); + float fStopSeconds = m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_Position.m_fSongBeat, 0 ); - float fStopBeats = fStopSeconds * m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_fSongBeat) / 60; + float fStopBeats = fStopSeconds * m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_Position.m_fSongBeat) / 60; // don't move the step from where it is, just move everything later - NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); - m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); + NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); + m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); } break; case undo: @@ -3749,7 +3751,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromBPMChange, ENTER_BPM_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_fSongBeat) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_Position.m_fSongBeat) ), 10 ); break; @@ -3757,7 +3759,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromStopChange, ENTER_STOP_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) ), 10 ); break; @@ -3765,7 +3767,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromDelayChange, ENTER_DELAY_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) ), 10 ); break; @@ -3773,7 +3775,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureNumeratorChange, ENTER_TIME_SIGNATURE_NUMERATOR_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator ), + ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ).m_iNumerator ), 3 ); break; @@ -3781,7 +3783,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureDenominatorChange, ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iDenominator ), + ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ).m_iDenominator ), 3 ); break; @@ -3789,7 +3791,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTickcountChange, ENTER_TICKCOUNT_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTickcountAtBeat( GAMESTATE->m_fSongBeat ) ), + ssprintf( "%d", m_pSteps->m_Timing.GetTickcountAtBeat( GAMESTATE->m_Position.m_fSongBeat ) ), 2 ); break; @@ -3797,7 +3799,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromComboChange, ENTER_COMBO_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetComboAtBeat( GAMESTATE->m_fSongBeat ) ), + ssprintf( "%d", m_pSteps->m_Timing.GetComboAtBeat( GAMESTATE->m_Position.m_fSongBeat ) ), 4 ); break; @@ -3805,7 +3807,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromLabelChange, ENTER_LABEL_VALUE, - ssprintf( "%s", m_pSteps->m_Timing.GetLabelAtBeat( GAMESTATE->m_fSongBeat ).c_str() ), + ssprintf( "%s", m_pSteps->m_Timing.GetLabelAtBeat( GAMESTATE->m_Position.m_fSongBeat ).c_str() ), 64 ); break; @@ -3813,7 +3815,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromWarpChange, ENTER_WARP_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) ), 10 ); break; @@ -3826,7 +3828,7 @@ void ScreenEdit::HandleBGChangeChoice( BGChangeChoice c, const vector &iAns FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer), iter ) { - if( iter->m_fStartBeat == GAMESTATE->m_fSongBeat ) + if( iter->m_fStartBeat == GAMESTATE->m_Position.m_fSongBeat ) { newChange = *iter; // delete the old change. We'll add a new one below. @@ -3835,7 +3837,7 @@ void ScreenEdit::HandleBGChangeChoice( BGChangeChoice c, const vector &iAns } } - newChange.m_fStartBeat = GAMESTATE->m_fSongBeat; + newChange.m_fStartBeat = GAMESTATE->m_Position.m_fSongBeat; newChange.m_fRate = StringToFloat( g_BackgroundChange.rows[rate].choices[iAnswers[rate]] )/100.f; newChange.m_sTransition = iAnswers[transition] ? g_BackgroundChange.rows[transition].choices[iAnswers[transition]] : RString(); newChange.m_def.m_sEffect = iAnswers[effect] ? g_BackgroundChange.rows[effect].choices[iAnswers[effect]] : RString(); @@ -4020,7 +4022,7 @@ void ScreenEdit::CheckNumberOfNotesAndUndo() if( EDIT_MODE.GetValue() != EditMode_Home ) return; - TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ); + TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ); int rowsPerMeasure = curTime.m_iDenominator * curTime.m_iNumerator; for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure ) @@ -4072,7 +4074,7 @@ float ScreenEdit::GetMaximumBeatForNewNote() const /* Round up to the next measure end. Some songs end on weird beats * mid-measure, and it's odd to have movement capped to these weird * beats. */ - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_fSongBeat ).m_iNumerator; + int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ).m_iNumerator; fEndBeat += beatsPerMeasure; fEndBeat = ftruncf( fEndBeat, (float)beatsPerMeasure ); From b8a4521f9cdfc7e887dc66d35370fbfddfaf7ecb Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 21:22:01 +0700 Subject: [PATCH 028/197] Move the reset code to SongPosition. --- src/GameState.cpp | 15 +++++---------- src/NoteField.cpp | 2 +- src/SongPosition.cpp | 16 ++++++++++++++++ src/SongPosition.h | 1 + 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index 9ad930dcd3..4df8259744 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -893,22 +893,17 @@ const float GameState::MUSIC_SECONDS_INVALID = -5000.0f; void GameState::ResetMusicStatistics() { - m_fMusicSeconds = 0; // MUSIC_SECONDS_INVALID; - // todo: move me to FOREACH_EnabledPlayer( p ) after [NUM_PLAYERS]ing - m_fSongBeat = 0; - m_fSongBeatNoOffset = 0; - m_fCurBPS = 10; - //m_bStop = false; - m_bFreeze = false; - m_bDelay = false; - m_iWarpBeginRow = -1; // Set to -1 because some song may want to warp to row 0. -aj - m_fWarpDestination = -1; // Set when a warp is encountered. also see above. -aj + m_Position.Reset(); + m_fMusicSecondsVisible = 0; m_fSongBeatVisible = 0; Actor::SetBGMTime( 0, 0, 0, 0 ); FOREACH_PlayerNumber( p ) + { m_pPlayerState[p]->ClearHopoState(); + m_pPlayerState[p]->m_Position.Reset(); + } } void GameState::ResetStageStatistics() diff --git a/src/NoteField.cpp b/src/NoteField.cpp index c4c6826765..72a9ceb90e 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -618,7 +618,7 @@ float FindFirstDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistance bBoomerang = (fAccels[PlayerOptions::ACCEL_BOOMERANG] != 0); } - while( fFirstBeatToDraw < m_pPlayerState->m_Position.m_fSongBeat ) + while( fFirstBeatToDraw < pPlayerState->m_Position.m_fSongBeat ) { bool bIsPastPeakYOffset; float fPeakYOffset; diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp index 1a68e620a6..14a67c1806 100644 --- a/src/SongPosition.cpp +++ b/src/SongPosition.cpp @@ -46,6 +46,22 @@ void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData } +void SongPosition::Reset() +{ + + m_fMusicSeconds = 0; // MUSIC_SECONDS_INVALID; + // todo: move me to FOREACH_EnabledPlayer( p ) after [NUM_PLAYERS]ing + m_fSongBeat = 0; + m_fSongBeatNoOffset = 0; + m_fCurBPS = 10; + //m_bStop = false; + m_bFreeze = false; + m_bDelay = false; + m_iWarpBeginRow = -1; // Set to -1 because some song may want to warp to row 0. -aj + m_fWarpDestination = -1; // Set when a warp is encountered. also see above. -aj + +} + /** * @file * @author Thai Pangsakulyanont (c) 2011 diff --git a/src/SongPosition.h b/src/SongPosition.h index 97d2d6fd3c..abe1dc2a8e 100644 --- a/src/SongPosition.h +++ b/src/SongPosition.h @@ -32,6 +32,7 @@ class SongPosition float m_fWarpDestination; RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update + void Reset(); void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp = RageZeroTimer ); }; From 2c87c34899772f14199456cc23c4250f7295fdc4 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 10 May 2011 21:44:25 +0700 Subject: [PATCH 029/197] [splittiming] ArrowEffects, BPMDisplay, Inventory, MeterDisplay --- src/ArrowEffects.cpp | 30 +++++++++++++++++------------- src/BPMDisplay.cpp | 2 +- src/Inventory.cpp | 2 +- src/MeterDisplay.cpp | 2 +- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index ffb21ae3d8..69372078cd 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -67,13 +67,13 @@ static float GetNoteFieldHeight( const PlayerState* pPlayerState ) namespace { - float g_fExpandSeconds = 0; struct PerPlayerData { float m_fMinTornadoX[MAX_COLS_PER_PLAYER]; float m_fMaxTornadoX[MAX_COLS_PER_PLAYER]; float m_fInvertDistance[MAX_COLS_PER_PLAYER]; float m_fBeatFactor; + float m_fExpandSeconds; }; PerPlayerData g_EffectData[NUM_PLAYERS]; }; @@ -82,22 +82,23 @@ void ArrowEffects::Update() { const Style* pStyle = GAMESTATE->GetCurrentStyle(); - { - static float fLastTime = 0; - float fTime = RageTimer::GetTimeSinceStartFast(); - if( !GAMESTATE->m_bFreeze || !GAMESTATE->m_bDelay ) - { - g_fExpandSeconds += fTime - fLastTime; - g_fExpandSeconds = fmodf( g_fExpandSeconds, PI*2 ); - } - fLastTime = fTime; - } - FOREACH_PlayerNumber( pn ) { const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn]; PerPlayerData &data = g_EffectData[pn]; + + { + static float fLastTime = 0; + float fTime = RageTimer::GetTimeSinceStartFast(); + if( !GAMESTATE->m_pPlayerState[pn]->m_Position.m_bFreeze || !GAMESTATE->m_pPlayerState[pn]->m_Position.m_bDelay ) + { + data.m_fExpandSeconds += fTime - fLastTime; + data.m_fExpandSeconds = fmodf( data.m_fExpandSeconds, PI*2 ); + } + fLastTime = fTime; + } + // Update Tornado for( int iColNum = 0; iColNum < MAX_COLS_PER_PLAYER; ++iColNum ) { @@ -307,7 +308,10 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float if( fAccels[PlayerOptions::ACCEL_EXPAND] != 0 ) { - float fExpandMultiplier = SCALE( RageFastCos(g_fExpandSeconds*EXPAND_MULTIPLIER_FREQUENCY), + // TODO: Don't index by PlayerNumber. + PerPlayerData &data = g_EffectData[pPlayerState->m_PlayerNumber]; + + float fExpandMultiplier = SCALE( RageFastCos(data.m_fExpandSeconds*EXPAND_MULTIPLIER_FREQUENCY), EXPAND_MULTIPLIER_SCALE_FROM_LOW, EXPAND_MULTIPLIER_SCALE_FROM_HIGH, EXPAND_MULTIPLIER_SCALE_TO_LOW, EXPAND_MULTIPLIER_SCALE_TO_HIGH ); fScrollSpeed *= SCALE( fAccels[PlayerOptions::ACCEL_EXPAND], diff --git a/src/BPMDisplay.cpp b/src/BPMDisplay.cpp index 5bdcbd66f4..bf4b8b15c2 100644 --- a/src/BPMDisplay.cpp +++ b/src/BPMDisplay.cpp @@ -276,7 +276,7 @@ SongBPMDisplay::SongBPMDisplay() void SongBPMDisplay::Update( float fDeltaTime ) { - float fGameStateBPM = GAMESTATE->m_fCurBPS * 60.0f; + float fGameStateBPM = GAMESTATE->m_Position.m_fCurBPS * 60.0f; if( m_fLastGameStateBPM != fGameStateBPM ) { m_fLastGameStateBPM = fGameStateBPM; diff --git a/src/Inventory.cpp b/src/Inventory.cpp index 0c0291696d..3b7eb88b32 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -121,7 +121,7 @@ void Inventory::Update( float fDelta ) // use items if this player is CPU-controlled if( m_pPlayerState->m_PlayerController != PC_HUMAN && - GAMESTATE->m_fSongBeat < GAMESTATE->m_pCurSong->m_fLastBeat ) + GAMESTATE->m_Position.m_fSongBeat < GAMESTATE->m_pCurSong->m_fLastBeat ) { // every 1 seconds, try to use an item int iLastSecond = (int)(RageTimer::GetTimeSinceStartFast() - fDelta); diff --git a/src/MeterDisplay.cpp b/src/MeterDisplay.cpp index 66c0b19587..641b50d73c 100644 --- a/src/MeterDisplay.cpp +++ b/src/MeterDisplay.cpp @@ -75,7 +75,7 @@ void SongMeterDisplay::Update( float fDeltaTime ) { float fSongStartSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fFirstBeat ); float fSongEndSeconds = GAMESTATE->m_pCurSong->m_SongTiming.GetElapsedTimeFromBeat( GAMESTATE->m_pCurSong->m_fLastBeat ); - float fPercentPositionSong = SCALE( GAMESTATE->m_fMusicSeconds, fSongStartSeconds, fSongEndSeconds, 0.0f, 1.0f ); + float fPercentPositionSong = SCALE( GAMESTATE->m_Position.m_fMusicSeconds, fSongStartSeconds, fSongEndSeconds, 0.0f, 1.0f ); CLAMP( fPercentPositionSong, 0, 1 ); SetPercent( fPercentPositionSong ); From 7fa6620423e0568e785ed14e380f047ab621fd31 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 10 May 2011 14:45:52 -0400 Subject: [PATCH 030/197] [splittiming] m_Position needed. (50) --- src/Attack.cpp | 2 +- src/Background.cpp | 4 ++-- src/DancingCharacters.cpp | 14 +++++++------- src/Foreground.cpp | 10 +++++----- src/LightsManager.cpp | 6 +++--- src/LyricDisplay.cpp | 6 +++--- src/ScreenNameEntry.cpp | 4 ++-- src/ScreenSyncOverlay.cpp | 2 +- src/SoundEffectControl.cpp | 2 +- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Attack.cpp b/src/Attack.cpp index 1a67cc3181..1bf2c8623b 100644 --- a/src/Attack.cpp +++ b/src/Attack.cpp @@ -32,7 +32,7 @@ void Attack::GetRealtimeAttackBeats( const Song *pSong, const PlayerState* pPlay ASSERT( pSong ); /* If reasonable, push the attack forward 8 beats so that notes on screen don't change suddenly. */ - fStartBeat = min( GAMESTATE->m_fSongBeat+8, pPlayerState->m_fLastDrawnBeat ); + fStartBeat = min( GAMESTATE->m_Position.m_fSongBeat+8, pPlayerState->m_fLastDrawnBeat ); fStartBeat = truncf(fStartBeat)+1; const TimingData &timing = pSong->m_SongTiming; diff --git a/src/Background.cpp b/src/Background.cpp index 5047e5fc1e..8c5a64c5fa 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -800,9 +800,9 @@ void BackgroundImpl::Update( float fDeltaTime ) FOREACH_BackgroundLayer( i ) { Layer &layer = m_Layer[i]; - layer.UpdateCurBGChange( m_pSong, m_fLastMusicSeconds, GAMESTATE->m_fMusicSeconds, m_mapNameToTransition ); + layer.UpdateCurBGChange( m_pSong, m_fLastMusicSeconds, GAMESTATE->m_Position.m_fMusicSeconds, m_mapNameToTransition ); } - m_fLastMusicSeconds = GAMESTATE->m_fMusicSeconds; + m_fLastMusicSeconds = GAMESTATE->m_Position.m_fMusicSeconds; } void BackgroundImpl::DrawPrimitives() diff --git a/src/DancingCharacters.cpp b/src/DancingCharacters.cpp index 6653173f9b..8b5be828c3 100644 --- a/src/DancingCharacters.cpp +++ b/src/DancingCharacters.cpp @@ -175,7 +175,7 @@ int Neg1OrPos1() { return RandomInt( 2 ) ? -1 : +1; } void DancingCharacters::Update( float fDelta ) { - if( GAMESTATE->m_bFreeze || GAMESTATE->m_bDelay ) + if( GAMESTATE->m_Position.m_bFreeze || GAMESTATE->m_Position.m_bDelay ) { // spin the camera Matrix-style m_CameraPanYStart += fDelta*40; @@ -184,7 +184,7 @@ void DancingCharacters::Update( float fDelta ) else { // make the characters move - float fBPM = GAMESTATE->m_fCurBPS*60; + float fBPM = GAMESTATE->m_Position.m_fCurBPS*60; float fUpdateScale = SCALE( fBPM, 60.f, 300.f, 0.75f, 1.5f ); CLAMP( fUpdateScale, 0.75f, 1.5f ); @@ -209,8 +209,8 @@ void DancingCharacters::Update( float fDelta ) } bWasGameplayStarting = bGameplayStarting; - static float fLastBeat = GAMESTATE->m_fSongBeat; - float fThisBeat = GAMESTATE->m_fSongBeat; + static float fLastBeat = GAMESTATE->m_Position.m_fSongBeat; + float fThisBeat = GAMESTATE->m_Position.m_fSongBeat; if( fLastBeat < GAMESTATE->m_pCurSong->m_fFirstBeat && fThisBeat >= GAMESTATE->m_pCurSong->m_fFirstBeat ) { @@ -220,7 +220,7 @@ void DancingCharacters::Update( float fDelta ) fLastBeat = fThisBeat; // time for a new sweep? - if( GAMESTATE->m_fSongBeat > m_fThisCameraEndBeat ) + if( GAMESTATE->m_Position.m_fSongBeat > m_fThisCameraEndBeat ) { if( RandomInt(6) >= 4 ) { @@ -248,7 +248,7 @@ void DancingCharacters::Update( float fDelta ) m_fLookAtHeight = CAMERA_STILL_LOOK_AT_HEIGHT; } - int iCurBeat = (int)GAMESTATE->m_fSongBeat; + int iCurBeat = (int)GAMESTATE->m_Position.m_fSongBeat; iCurBeat -= iCurBeat%8; m_fThisCameraStartBeat = (float) iCurBeat; @@ -313,7 +313,7 @@ void DancingCharacters::DrawPrimitives() if(m_fThisCameraStartBeat == m_fThisCameraEndBeat) fPercentIntoSweep = 0; else - fPercentIntoSweep = SCALE(GAMESTATE->m_fSongBeat, m_fThisCameraStartBeat, m_fThisCameraEndBeat, 0.f, 1.f ); + fPercentIntoSweep = SCALE(GAMESTATE->m_Position.m_fSongBeat, m_fThisCameraStartBeat, m_fThisCameraEndBeat, 0.f, 1.f ); float fCameraPanY = SCALE( fPercentIntoSweep, 0.f, 1.f, m_CameraPanYStart, m_CameraPanYEnd ); float fCameraHeight = SCALE( fPercentIntoSweep, 0.f, 1.f, m_fCameraHeightStart, m_fCameraHeightEnd ); diff --git a/src/Foreground.cpp b/src/Foreground.cpp index 54ba873d7e..f7b7307b37 100644 --- a/src/Foreground.cpp +++ b/src/Foreground.cpp @@ -65,7 +65,7 @@ void Foreground::Update( float fDeltaTime ) { LoadedBGA &bga = m_BGAnimations[i]; - if( GAMESTATE->m_fSongBeat < bga.m_fStartBeat ) + if( GAMESTATE->m_Position.m_fSongBeat < bga.m_fStartBeat ) { // The animation hasn't started yet. continue; @@ -83,11 +83,11 @@ void Foreground::Update( float fDeltaTime ) bga.m_bga->PlayCommand( "On" ); const float fStartSecond = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( bga.m_fStartBeat ); - lDeltaTime = GAMESTATE->m_fMusicSeconds - fStartSecond; + lDeltaTime = GAMESTATE->m_Position.m_fMusicSeconds - fStartSecond; } else { - lDeltaTime = GAMESTATE->m_fMusicSeconds - m_fLastMusicSeconds; + lDeltaTime = GAMESTATE->m_Position.m_fMusicSeconds - m_fLastMusicSeconds; } // This shouldn't go down, but be safe: @@ -95,7 +95,7 @@ void Foreground::Update( float fDeltaTime ) bga.m_bga->Update( lDeltaTime / fRate ); - if( GAMESTATE->m_fSongBeat > bga.m_fStopBeat ) + if( GAMESTATE->m_Position.m_fSongBeat > bga.m_fStopBeat ) { // Finished. bga.m_bga->SetVisible( false ); @@ -104,7 +104,7 @@ void Foreground::Update( float fDeltaTime ) } } - m_fLastMusicSeconds = GAMESTATE->m_fMusicSeconds; + m_fLastMusicSeconds = GAMESTATE->m_Position.m_fMusicSeconds; } /* diff --git a/src/LightsManager.cpp b/src/LightsManager.cpp index b3f05c585b..54e220bf07 100644 --- a/src/LightsManager.cpp +++ b/src/LightsManager.cpp @@ -230,12 +230,12 @@ void LightsManager::Update( float fDeltaTime ) static float fLastBeat; static int iLight; - if( fracf(GAMESTATE->m_fLightSongBeat) < fracf(fLastBeat) ) + if( fracf(GAMESTATE->m_Position.m_fLightSongBeat) < fracf(fLastBeat) ) { ++iLight; wrap( iLight, 4 ); } - fLastBeat = GAMESTATE->m_fLightSongBeat; + fLastBeat = GAMESTATE->m_Position.m_fLightSongBeat; switch( iLight ) { case 0: m_LightsState.m_bCabinetLights[LIGHT_MARQUEE_UP_LEFT] = true; break; @@ -405,7 +405,7 @@ void LightsManager::Update( float fDeltaTime ) // If not joined, has enough credits, and not too late to join, then // blink the menu buttons rapidly so they'll press Start { - int iBeat = (int)(GAMESTATE->m_fLightSongBeat*4); + int iBeat = (int)(GAMESTATE->m_Position.m_fLightSongBeat*4); bool bBlinkOn = (iBeat%2)==0; FOREACH_PlayerNumber( pn ) { diff --git a/src/LyricDisplay.cpp b/src/LyricDisplay.cpp index fec9827e34..7284d2dc17 100644 --- a/src/LyricDisplay.cpp +++ b/src/LyricDisplay.cpp @@ -41,9 +41,9 @@ void LyricDisplay::Update( float fDeltaTime ) return; // If the song has changed (in a course), reset. - if( GAMESTATE->m_fMusicSeconds < m_fLastSecond ) + if( GAMESTATE->m_Position.m_fMusicSeconds < m_fLastSecond ) Init(); - m_fLastSecond = GAMESTATE->m_fMusicSeconds; + m_fLastSecond = GAMESTATE->m_Position.m_fMusicSeconds; if( m_iCurLyricNumber >= GAMESTATE->m_pCurSong->m_LyricSegments.size() ) return; @@ -51,7 +51,7 @@ void LyricDisplay::Update( float fDeltaTime ) const Song *pSong = GAMESTATE->m_pCurSong; const float fStartTime = (pSong->m_LyricSegments[m_iCurLyricNumber].m_fStartTime) - IN_LENGTH.GetValue(); - if( GAMESTATE->m_fMusicSeconds < fStartTime ) + if( GAMESTATE->m_Position.m_fMusicSeconds < fStartTime ) return; // Clamp this lyric to the beginning of the next or the end of the music. diff --git a/src/ScreenNameEntry.cpp b/src/ScreenNameEntry.cpp index fca92a59b1..b4eeeed4cc 100644 --- a/src/ScreenNameEntry.cpp +++ b/src/ScreenNameEntry.cpp @@ -61,7 +61,7 @@ void ScreenNameEntry::ScrollingText::Init( const RString &sName, const vectorm_fSongBeat; + const float fFakeBeat = GAMESTATE->m_Position.m_fSongBeat; const size_t iClosestIndex = lrintf( fFakeBeat ) % CHARS_CHOICES.size(); const float fClosestYOffset = GetClosestCharYOffset( fFakeBeat ); @@ -325,7 +325,7 @@ void ScreenNameEntry::Update( float fDelta ) SOUND->PlayOnceFromDir( ANNOUNCER->GetPathTo("name entry") ); m_fFakeBeat += fDelta * FAKE_BEATS_PER_SEC; - GAMESTATE->m_fSongBeat = m_fFakeBeat; + GAMESTATE->m_Position.m_fSongBeat = m_fFakeBeat; ScreenWithMenuElements::Update(fDelta); } diff --git a/src/ScreenSyncOverlay.cpp b/src/ScreenSyncOverlay.cpp index baf240d54d..5f5d8e37f4 100644 --- a/src/ScreenSyncOverlay.cpp +++ b/src/ScreenSyncOverlay.cpp @@ -221,7 +221,7 @@ bool ScreenSyncOverlay::OverlayInput( const InputEventPlus &input ) } if( GAMESTATE->m_pCurSong != NULL ) { - BPMSegment& seg = GAMESTATE->m_pCurSong->m_SongTiming.GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat ); + BPMSegment& seg = GAMESTATE->m_pCurSong->m_SongTiming.GetBPMSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ); seg.m_fBPS += fDelta; } } diff --git a/src/SoundEffectControl.cpp b/src/SoundEffectControl.cpp index 40d21fa6ba..2055e6bda1 100644 --- a/src/SoundEffectControl.cpp +++ b/src/SoundEffectControl.cpp @@ -44,7 +44,7 @@ void SoundEffectControl::Update( float fDeltaTime ) if( LOCK_TO_HOLD ) { - int iRow = BeatToNoteRow( GAMESTATE->m_fSongBeat ); + int iRow = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); int iHoldsHeld, iHoldsLetGo; HoldsBeingHeld( iRow, iHoldsHeld, iHoldsLetGo ); From fb8b387fb7b8dd3ce60e77e9415b1e9a357e534c Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 10 May 2011 14:53:59 -0400 Subject: [PATCH 031/197] [splittiming] Compiles and links. Not guaranteed to work. Adjustments to GameState and SongPosition may still be needed. --- src/BeginnerHelper.cpp | 16 ++++++++-------- src/GameSoundManager.cpp | 24 ++++++++++++------------ src/GameState.cpp | 12 ++++++------ src/GameplayAssist.cpp | 10 +++++----- src/ScreenGameplay.cpp | 24 ++++++++++++------------ src/ScreenHowToPlay.cpp | 10 +++++----- 6 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/BeginnerHelper.cpp b/src/BeginnerHelper.cpp index 3bf23107df..9bc73247ba 100644 --- a/src/BeginnerHelper.cpp +++ b/src/BeginnerHelper.cpp @@ -191,7 +191,7 @@ void BeginnerHelper::ShowStepCircle( PlayerNumber pn, int CSTEP ) m_sStepCircle[pn][isc].StopEffect(); m_sStepCircle[pn][isc].SetZoom( 2 ); m_sStepCircle[pn][isc].StopTweening(); - m_sStepCircle[pn][isc].BeginTweening( GAMESTATE->m_fCurBPS/3, TWEEN_LINEAR ); + m_sStepCircle[pn][isc].BeginTweening( GAMESTATE->m_Position.m_fCurBPS/3, TWEEN_LINEAR ); m_sStepCircle[pn][isc].SetZoom( 0 ); } @@ -318,19 +318,19 @@ void BeginnerHelper::Step( PlayerNumber pn, int CSTEP ) ShowStepCircle( pn, ST_DOWN ); m_pDancer[pn]->StopTweening(); m_pDancer[pn]->PlayAnimation( "Step-JUMPLR", 1.5f ); - m_pDancer[pn]->BeginTweening( GAMESTATE->m_fCurBPS/8, TWEEN_LINEAR ); + m_pDancer[pn]->BeginTweening( GAMESTATE->m_Position.m_fCurBPS/8, TWEEN_LINEAR ); m_pDancer[pn]->SetRotationY( 90 ); - m_pDancer[pn]->BeginTweening( 1/(GAMESTATE->m_fCurBPS * 2) ); //sleep between jump-frames - m_pDancer[pn]->BeginTweening( GAMESTATE->m_fCurBPS /6, TWEEN_LINEAR ); + m_pDancer[pn]->BeginTweening( 1/(GAMESTATE->m_Position.m_fCurBPS * 2) ); //sleep between jump-frames + m_pDancer[pn]->BeginTweening( GAMESTATE->m_Position.m_fCurBPS /6, TWEEN_LINEAR ); m_pDancer[pn]->SetRotationY( 0 ); break; } m_sFlash.StopEffect(); m_sFlash.StopTweening(); - m_sFlash.Sleep( GAMESTATE->m_fCurBPS/16 ); + m_sFlash.Sleep( GAMESTATE->m_Position.m_fCurBPS/16 ); m_sFlash.SetDiffuseAlpha( 1 ); - m_sFlash.BeginTweening( 1/GAMESTATE->m_fCurBPS * 0.5f ); + m_sFlash.BeginTweening( 1/GAMESTATE->m_Position.m_fCurBPS * 0.5f ); m_sFlash.SetDiffuseAlpha( 0 ); } @@ -340,7 +340,7 @@ void BeginnerHelper::Update( float fDeltaTime ) return; // the row we want to check on this update - int iCurRow = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat + 0.4f ); + int iCurRow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat + 0.4f ); FOREACH_EnabledPlayer( pn ) { for( int iRow=m_iLastRowChecked; iRowUpdate( fDeltaTime ); m_sFlash.Update( fDeltaTime ); - float beat = fDeltaTime*GAMESTATE->m_fCurBPS; + float beat = fDeltaTime*GAMESTATE->m_Position.m_fCurBPS; // If this is not a human player, the dancer is not shown FOREACH_HumanPlayer( pu ) { diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp index 6e517249fb..9560dfb4b3 100644 --- a/src/GameSoundManager.cpp +++ b/src/GameSoundManager.cpp @@ -201,7 +201,7 @@ static void StartMusic( MusicToPlay &ToPlay ) { /* This song has no real timing data. The offset is arbitrary. Change it so * the beat will line up to where we are now, so we don't have to delay. */ - float fDestBeat = fmodfp( GAMESTATE->m_fSongBeatNoOffset, 1 ); + float fDestBeat = fmodfp( GAMESTATE->m_Position.m_fSongBeatNoOffset, 1 ); float fTime = NewMusic->m_NewTiming.GetElapsedTimeFromBeatNoOffset( fDestBeat ); NewMusic->m_NewTiming.m_fBeat0OffsetInSeconds = fTime; @@ -223,7 +223,7 @@ static void StartMusic( MusicToPlay &ToPlay ) * common when starting a precached sound, but our sound isn't, so it'll * probably take a little longer. Nudge the latency up. */ const float fPresumedLatency = SOUNDMAN->GetPlayLatency() + 0.040f; - const float fCurSecond = GAMESTATE->m_fMusicSeconds + fPresumedLatency; + const float fCurSecond = GAMESTATE->m_Position.m_fMusicSeconds + fPresumedLatency; const float fCurBeat = g_Playing->m_Timing.GetBeatFromElapsedTimeNoOffset( fCurSecond ); /* The beat that the new sound will start on. */ @@ -236,9 +236,9 @@ static void StartMusic( MusicToPlay &ToPlay ) const float fSecondToStartOn = g_Playing->m_Timing.GetElapsedTimeFromBeatNoOffset( fCurBeatToStartOn ); const float fMaximumDistance = 2; - const float fDistance = min( fSecondToStartOn - GAMESTATE->m_fMusicSeconds, fMaximumDistance ); + const float fDistance = min( fSecondToStartOn - GAMESTATE->m_Position.m_fMusicSeconds, fMaximumDistance ); - when = GAMESTATE->m_LastBeatUpdate + fDistance; + when = GAMESTATE->m_Position.m_LastBeatUpdate + fDistance; } /* Important: don't hold the mutex while we load and seek the actual sound. */ @@ -552,8 +552,8 @@ void GameSoundManager::Update( float fDeltaTime ) if( !g_Playing->m_Music->IsPlaying() ) { /* There's no song playing. Fake it. */ - CHECKPOINT_M( ssprintf("%f, delta %f", GAMESTATE->m_fMusicSeconds, fDeltaTime) ); - GAMESTATE->UpdateSongPosition( GAMESTATE->m_fMusicSeconds + fDeltaTime, g_Playing->m_Timing ); + CHECKPOINT_M( ssprintf("%f, delta %f", GAMESTATE->m_Position.m_fMusicSeconds, fDeltaTime) ); + GAMESTATE->UpdateSongPosition( GAMESTATE->m_Position.m_fMusicSeconds + fDeltaTime, g_Playing->m_Timing ); return; } @@ -570,8 +570,8 @@ void GameSoundManager::Update( float fDeltaTime ) // if( PREFSMAN->m_bLogSkips && !g_Playing->m_bTimingDelayed ) { - const float fExpectedTimePassed = (tm - GAMESTATE->m_LastBeatUpdate) * g_Playing->m_Music->GetPlaybackRate(); - const float fSoundTimePassed = fSeconds - GAMESTATE->m_fMusicSeconds; + const float fExpectedTimePassed = (tm - GAMESTATE->m_Position.m_LastBeatUpdate) * g_Playing->m_Music->GetPlaybackRate(); + const float fSoundTimePassed = fSeconds - GAMESTATE->m_Position.m_fMusicSeconds; const float fDiff = fExpectedTimePassed - fSoundTimePassed; static RString sLastFile = ""; @@ -580,7 +580,7 @@ void GameSoundManager::Update( float fDeltaTime ) /* If fSoundTimePassed < 0, the sound has probably looped. */ if( sLastFile == ThisFile && fSoundTimePassed >= 0 && fabsf(fDiff) > 0.003f ) LOG->Trace("Song position skip in %s: expected %.3f, got %.3f (cur %f, prev %f) (%.3f difference)", - Basename(ThisFile).c_str(), fExpectedTimePassed, fSoundTimePassed, fSeconds, GAMESTATE->m_fMusicSeconds, fDiff ); + Basename(ThisFile).c_str(), fExpectedTimePassed, fSoundTimePassed, fSeconds, GAMESTATE->m_Position.m_fMusicSeconds, fDiff ); sLastFile = ThisFile; } @@ -599,7 +599,7 @@ void GameSoundManager::Update( float fDeltaTime ) { /* We're still waiting for the new sound to start playing, so keep using the * old timing data and fake the time. */ - GAMESTATE->UpdateSongPosition( GAMESTATE->m_fMusicSeconds + fDeltaTime, g_Playing->m_Timing ); + GAMESTATE->UpdateSongPosition( GAMESTATE->m_Position.m_fMusicSeconds + fDeltaTime, g_Playing->m_Timing ); } else { @@ -614,7 +614,7 @@ void GameSoundManager::Update( float fDeltaTime ) { static int iBeatLastCrossed = 0; - float fSongBeat = GAMESTATE->m_fSongBeat; + float fSongBeat = GAMESTATE->m_Position.m_fSongBeat; int iRowNow = BeatToNoteRowNotRounded( fSongBeat ); iRowNow = max( 0, iRowNow ); @@ -638,7 +638,7 @@ void GameSoundManager::Update( float fDeltaTime ) NoteData &lights = g_Playing->m_Lights; if( lights.GetNumTracks() > 0 ) // lights data was loaded { - const float fSongBeat = GAMESTATE->m_fLightSongBeat; + const float fSongBeat = GAMESTATE->m_Position.m_fLightSongBeat; const int iSongRow = BeatToNoteRowNotRounded( fSongBeat ); static int iRowLastCrossed = 0; diff --git a/src/GameState.cpp b/src/GameState.cpp index 4df8259744..54330d8dfd 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -958,7 +958,7 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti int iThrowAway; timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway, iThrowAway, fThrowAway2 ); - Actor::SetBGMTime( m_Position.m_fMusicSecondsVisible, m_Position.m_fSongBeatVisible, fPositionSeconds, m_Position.m_fSongBeatNoOffset ); + Actor::SetBGMTime( GAMESTATE->m_fMusicSecondsVisible, GAMESTATE->m_fSongBeatVisible, fPositionSeconds, GAMESTATE->m_Position.m_fSongBeatNoOffset ); // LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze ); } @@ -2252,11 +2252,11 @@ public: DEFINE_METHOD( GetHardestStepsDifficulty, GetHardestStepsDifficulty() ) DEFINE_METHOD( IsEventMode, IsEventMode() ) DEFINE_METHOD( GetNumPlayersEnabled, GetNumPlayersEnabled() ) - DEFINE_METHOD( GetSongBeat, m_fSongBeat ) + DEFINE_METHOD( GetSongBeat, m_Position.m_fSongBeat ) DEFINE_METHOD( GetSongBeatVisible, m_fSongBeatVisible ) - DEFINE_METHOD( GetSongBPS, m_fCurBPS ) - DEFINE_METHOD( GetSongFreeze, m_bFreeze ) - DEFINE_METHOD( GetSongDelay, m_bDelay ) + DEFINE_METHOD( GetSongBPS, m_Position.m_fCurBPS ) + DEFINE_METHOD( GetSongFreeze, m_Position.m_bFreeze ) + DEFINE_METHOD( GetSongDelay, m_Position.m_bDelay ) DEFINE_METHOD( GetGameplayLeadIn, m_bGameplayLeadIn ) DEFINE_METHOD( GetCoins, m_iCoins ) DEFINE_METHOD( IsSideJoined, m_bSideIsJoined[Enum::Check(L, 1)] ) @@ -2395,7 +2395,7 @@ public: static int JoinPlayer( T* p, lua_State *L ) { p->JoinPlayer(Enum::Check(L, 1)); return 0; } static int UnjoinPlayer( T* p, lua_State *L ) { p->UnjoinPlayer(Enum::Check(L, 1)); return 0; } static int GetSongPercent( T* p, lua_State *L ) { lua_pushnumber(L, p->GetSongPercent(FArg(1))); return 1; } - DEFINE_METHOD( GetCurMusicSeconds, m_fMusicSeconds ) + DEFINE_METHOD( GetCurMusicSeconds, m_Position.m_fMusicSeconds ) DEFINE_METHOD( GetWorkoutGoalComplete, m_bWorkoutGoalComplete ) static int GetCharacter( T* p, lua_State *L ) { p->m_pCurCharacters[Enum::Check(L, 1)]->PushSelf(L); return 1; } diff --git a/src/GameplayAssist.cpp b/src/GameplayAssist.cpp index 97a324416d..ac9ae328b3 100644 --- a/src/GameplayAssist.cpp +++ b/src/GameplayAssist.cpp @@ -25,7 +25,7 @@ void GameplayAssist::PlayTicks( const NoteData &nd ) * will start coming out the speaker. Compensate for this by boosting fPositionSeconds * ahead. This is just to make sure that we request the sound early enough for it to * come out on time; the actual precise timing is handled by SetStartTime. */ - float fPositionSeconds = GAMESTATE->m_fMusicSeconds; + float fPositionSeconds = GAMESTATE->m_Position.m_fMusicSeconds; fPositionSeconds += SOUNDMAN->GetPlayLatency() + (float)CommonMetrics::TICK_EARLY_SECONDS + 0.250f; const TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming; const float fSongBeat = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds ); @@ -47,11 +47,11 @@ void GameplayAssist::PlayTicks( const NoteData &nd ) { const float fTickBeat = NoteRowToBeat( iClapRow ); const float fTickSecond = timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); - float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; + float fSecondsUntil = fTickSecond - GAMESTATE->m_Position.m_fMusicSeconds; fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */ RageSoundParams p; - p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); + p.m_StartTime = GAMESTATE->m_Position.m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); m_soundAssistClap.Play( &p ); } } @@ -83,11 +83,11 @@ void GameplayAssist::PlayTicks( const NoteData &nd ) { const float fTickBeat = NoteRowToBeat( iMetronomeRow ); const float fTickSecond = timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); - float fSecondsUntil = fTickSecond - GAMESTATE->m_fMusicSeconds; + float fSecondsUntil = fTickSecond - GAMESTATE->m_Position.m_fMusicSeconds; fSecondsUntil /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; /* 2x music rate means the time until the tick is halved */ RageSoundParams p; - p.m_StartTime = GAMESTATE->m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); + p.m_StartTime = GAMESTATE->m_Position.m_LastBeatUpdate + (fSecondsUntil - (float)CommonMetrics::TICK_EARLY_SECONDS); if( bIsMeasure ) m_soundAssistMetronomeMeasure.Play( &p ); else diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index f2cba6c337..041613e914 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -1347,10 +1347,10 @@ void ScreenGameplay::StartPlayingSong( float fMinTimeToNotes, float fMinTimeToMu m_pSoundMusic->Pause( true ); /* Make sure GAMESTATE->m_fMusicSeconds is set up. */ - GAMESTATE->m_fMusicSeconds = -5000; + GAMESTATE->m_Position.m_fMusicSeconds = -5000; UpdateSongPosition(0); - ASSERT( GAMESTATE->m_fMusicSeconds > -4000 ); /* make sure the "fake timer" code doesn't trigger */ + ASSERT( GAMESTATE->m_Position.m_fMusicSeconds > -4000 ); /* make sure the "fake timer" code doesn't trigger */ } @@ -1405,7 +1405,7 @@ void ScreenGameplay::PlayAnnouncer( RString type, float fSeconds ) if( m_DancingState != STATE_DANCING ) return; if( GAMESTATE->m_pCurSong == NULL || // this will be true on ScreenDemonstration sometimes - GAMESTATE->m_fSongBeat < GAMESTATE->m_pCurSong->m_fFirstBeat ) + GAMESTATE->m_Position.m_fSongBeat < GAMESTATE->m_pCurSong->m_fFirstBeat ) return; if( m_fTimeSinceLastDancingComment < fSeconds ) @@ -1687,7 +1687,7 @@ void ScreenGameplay::Update( float fDeltaTime ) // update fGameplaySeconds STATSMAN->m_CurStageStats.m_fGameplaySeconds += fUnscaledDeltaTime; - if( GAMESTATE->m_fSongBeat >= GAMESTATE->m_pCurSong->m_fFirstBeat && GAMESTATE->m_fSongBeat < GAMESTATE->m_pCurSong->m_fLastBeat ) + if( GAMESTATE->m_Position.m_fSongBeat >= GAMESTATE->m_pCurSong->m_fFirstBeat && GAMESTATE->m_Position.m_fSongBeat < GAMESTATE->m_pCurSong->m_fLastBeat ) { STATSMAN->m_CurStageStats.m_fStepsSeconds += fUnscaledDeltaTime; @@ -1707,7 +1707,7 @@ void ScreenGameplay::Update( float fDeltaTime ) if( bAllReallyFailed ) fSecondsToStartTransitioningOut += BEGIN_FAILED_DELAY; - if( GAMESTATE->m_fMusicSeconds >= fSecondsToStartTransitioningOut && !m_NextSong.IsTransitioning() ) + if( GAMESTATE->m_Position.m_fMusicSeconds >= fSecondsToStartTransitioningOut && !m_NextSong.IsTransitioning() ) this->PostScreenMessage( SM_NotesEnded, 0 ); } @@ -1843,8 +1843,8 @@ void ScreenGameplay::Update( float fDeltaTime ) float ScreenGameplay::GetHasteRate() { - if( GAMESTATE->m_fMusicSeconds < GAMESTATE->m_fLastHasteUpdateMusicSeconds || // new song - GAMESTATE->m_fMusicSeconds > GAMESTATE->m_fLastHasteUpdateMusicSeconds + 4 ) + if( GAMESTATE->m_Position.m_fMusicSeconds < GAMESTATE->m_fLastHasteUpdateMusicSeconds || // new song + GAMESTATE->m_Position.m_fMusicSeconds > GAMESTATE->m_fLastHasteUpdateMusicSeconds + 4 ) { bool bAnyPlayerHitAllNotes = false; FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) @@ -1865,7 +1865,7 @@ float ScreenGameplay::GetHasteRate() GAMESTATE->m_fHasteRate += 0.1f; CLAMP( GAMESTATE->m_fHasteRate, -1.0f, +1.0f ); - GAMESTATE->m_fLastHasteUpdateMusicSeconds = GAMESTATE->m_fMusicSeconds; + GAMESTATE->m_fLastHasteUpdateMusicSeconds = GAMESTATE->m_Position.m_fMusicSeconds; } /* If the life meter is less than half full, push the haste rate down to let @@ -1914,7 +1914,7 @@ void ScreenGameplay::UpdateLights() ZERO( bBlinkGameButton ); bool bCrossedABeat = false; { - const float fSongBeat = GAMESTATE->m_fLightSongBeat; + const float fSongBeat = GAMESTATE->m_Position.m_fLightSongBeat; const int iSongRow = BeatToNoteRowNotRounded( fSongBeat ); static int iRowLastCrossed = 0; @@ -1968,7 +1968,7 @@ void ScreenGameplay::UpdateLights() } // Before the first beat of the song, all cabinet lights solid on (except for menu buttons). - bool bOverrideCabinetBlink = (GAMESTATE->m_fSongBeat < GAMESTATE->m_pCurSong->m_fFirstBeat); + bool bOverrideCabinetBlink = (GAMESTATE->m_Position.m_fSongBeat < GAMESTATE->m_pCurSong->m_fFirstBeat); FOREACH_CabinetLight( cl ) bBlinkCabinetLight[cl] |= bOverrideCabinetBlink; @@ -1994,7 +1994,7 @@ void ScreenGameplay::SendCrossedMessages() { static int iRowLastCrossed = 0; - float fPositionSeconds = GAMESTATE->m_fMusicSeconds; + float fPositionSeconds = GAMESTATE->m_Position.m_fMusicSeconds; float fSongBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds ); int iRowNow = BeatToNoteRowNotRounded( fSongBeat ); @@ -2032,7 +2032,7 @@ void ScreenGameplay::SendCrossedMessages() { float fNoteWillCrossInSeconds = MESSAGE_SPACING_SECONDS * i; - float fPositionSeconds = GAMESTATE->m_fMusicSeconds + fNoteWillCrossInSeconds; + float fPositionSeconds = GAMESTATE->m_Position.m_fMusicSeconds + fNoteWillCrossInSeconds; float fSongBeat = GAMESTATE->m_pCurSong->m_SongTiming.GetBeatFromElapsedTime( fPositionSeconds ); int iRowNow = BeatToNoteRowNotRounded( fSongBeat ); diff --git a/src/ScreenHowToPlay.cpp b/src/ScreenHowToPlay.cpp index 877fb693c4..21aeef437b 100644 --- a/src/ScreenHowToPlay.cpp +++ b/src/ScreenHowToPlay.cpp @@ -209,7 +209,7 @@ void ScreenHowToPlay::Step() #define ST_JUMPUD (ST_UP | ST_DOWN) int iStep = 0; - const int iNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat + 0.6f ); + const int iNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat + 0.6f ); // if we want to miss from here on out, don't process steps. if( m_iW2s < m_iNumW2s && m_NoteData.IsThereATapAtRow( iNoteRow ) ) { @@ -230,10 +230,10 @@ void ScreenHowToPlay::Step() m_pmCharacter->PlayAnimation( "Step-JUMPLR", 1.8f ); m_pmCharacter->StopTweening(); - m_pmCharacter->BeginTweening( GAMESTATE->m_fCurBPS /8, TWEEN_LINEAR ); + m_pmCharacter->BeginTweening( GAMESTATE->m_Position.m_fCurBPS /8, TWEEN_LINEAR ); m_pmCharacter->SetRotationY( 90 ); - m_pmCharacter->BeginTweening( (1/(GAMESTATE->m_fCurBPS * 2) ) ); //sleep between jump-frames - m_pmCharacter->BeginTweening( GAMESTATE->m_fCurBPS /6, TWEEN_LINEAR ); + m_pmCharacter->BeginTweening( (1/(GAMESTATE->m_Position.m_fCurBPS * 2) ) ); //sleep between jump-frames + m_pmCharacter->BeginTweening( GAMESTATE->m_Position.m_fCurBPS /6, TWEEN_LINEAR ); m_pmCharacter->SetRotationY( 0 ); break; } @@ -248,7 +248,7 @@ void ScreenHowToPlay::Update( float fDelta ) m_fFakeSecondsIntoSong += fDelta; static int iLastNoteRowCounted = 0; - int iCurNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat ); + int iCurNoteRow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat ); if( iCurNoteRow != iLastNoteRowCounted &&m_NoteData.IsThereATapAtRow(iCurNoteRow) ) { From 61839545904f0aee5f78f52fc4d18a107b304f93 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 10 May 2011 15:47:16 -0400 Subject: [PATCH 032/197] [splittiming] More work needed on this one. --- src/NotesLoaderKSF.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index 14e6b4bca7..42abc7032c 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -41,6 +41,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, LOG->UserLog( "Song file", sPath, "has an invalid tick count: %d.", iTickCount ); return false; } + out.m_Timing.AddTickcountSegment(TickcountSegment(0, iTickCount)); } else if( sValueName=="STEP" ) { @@ -133,6 +134,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, case StepsType_pump_single: notedata.SetNumTracks( 5 ); break; case StepsType_pump_couple: notedata.SetNumTracks( 10 ); break; case StepsType_pump_double: notedata.SetNumTracks( 10 ); break; + case StepsType_pump_routine: notedata.SetNumTracks( 10 ); break; // future files may have this? case StepsType_pump_halfdouble: notedata.SetNumTracks( 6 ); break; default: FAIL_M( ssprintf("%i", out.m_StepsType) ); } @@ -184,7 +186,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, }*/ if( BeginsWith(sRowString, "|B") || BeginsWith(sRowString, "|D") || BeginsWith(sRowString, "|E") ) { - // These don't have to be worried about here: the changes and stops were already added. + // TODO: Update for Split Timing. continue; } else if ( BeginsWith(sRowString, "|T") ) @@ -192,6 +194,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, RString temp = sRowString.substr(2,sRowString.size()-3); newTick = atoi(temp); bTickChangeNeeded = true; + out.m_Timing.AddTickcountSegment(TickcountSegment(fCurBeat, newTick)); continue; } else From 1bf99bd528a870cf2aedda0cc1498ebefd6e6a25 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Wed, 11 May 2011 20:53:40 +0700 Subject: [PATCH 033/197] [splittiming] make screenedit work with the steps' timing. --- src/ArrowEffects.cpp | 12 ++-- src/GameState.cpp | 17 ++--- src/GameState.h | 2 - src/ScreenEdit.cpp | 168 +++++++++++++++++++++---------------------- src/SongPosition.cpp | 11 +++ src/SongPosition.h | 2 + 6 files changed, 107 insertions(+), 105 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 69372078cd..f5ea953136 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -177,7 +177,7 @@ void ArrowEffects::Update() // Update Beat do { float fAccelTime = 0.2f, fTotalTime = 0.5f; - float fBeat = GAMESTATE->m_fSongBeatVisible + fAccelTime; + float fBeat = GAMESTATE->m_pPlayerState[pn]->m_Position.m_fSongBeatVisible + fAccelTime; const bool bEvenBeat = ( int(fBeat) % 2 ) != 0; @@ -223,7 +223,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float * entirely time spacing (respectively). Occasionally, we tween between them. */ if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f ) { - float fSongBeat = GAMESTATE->m_fSongBeatVisible; + float fSongBeat = pPlayerState->m_Position.m_fSongBeatVisible; float fBeatsUntilStep = fNoteBeat - fSongBeat; float fYOffsetBeatSpacing = fBeatsUntilStep; fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); @@ -231,7 +231,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f ) { - float fSongSeconds = GAMESTATE->m_fMusicSecondsVisible; + float fSongSeconds = pPlayerState->m_Position.m_fMusicSecondsVisible; float fNoteSeconds = GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing.GetElapsedTimeFromBeat(fNoteBeat); float fSecondsUntilStep = fNoteSeconds - fSongSeconds; float fBPM = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollBPM; @@ -515,7 +515,7 @@ float ArrowEffects::GetRotationZ( const PlayerState* pPlayerState, float fNoteBe // As usual, enable dizzy hold heads at your own risk. -Wolfman2000 if( fEffects[PlayerOptions::EFFECT_DIZZY] != 0 && ( DIZZY_HOLD_HEADS || !bIsHoldHead ) ) { - const float fSongBeat = GAMESTATE->m_fSongBeatVisible; + const float fSongBeat = pPlayerState->m_Position.m_fSongBeatVisible; float fDizzyRotation = fNoteBeat - fSongBeat; fDizzyRotation *= fEffects[PlayerOptions::EFFECT_DIZZY]; fDizzyRotation = fmodf( fDizzyRotation, 2*PI ); @@ -532,7 +532,7 @@ float ArrowEffects::ReceptorGetRotationZ( const PlayerState* pPlayerState ) if( fEffects[PlayerOptions::EFFECT_CONFUSION] != 0 ) { - float fConfRotation = GAMESTATE->m_fSongBeatVisible; + float fConfRotation = pPlayerState->m_Position.m_fSongBeatVisible; fConfRotation *= fEffects[PlayerOptions::EFFECT_CONFUSION]; fConfRotation = fmodf( fConfRotation, 2*PI ); fConfRotation *= -180/PI; @@ -684,7 +684,7 @@ float ArrowEffects::GetBrightness( const PlayerState* pPlayerState, float fNoteB if( GAMESTATE->IsEditing() ) return 1; - float fSongBeat = GAMESTATE->m_fSongBeatVisible; + float fSongBeat = pPlayerState->m_Position.m_fSongBeatVisible; float fBeatsUntilStep = fNoteBeat - fSongBeat; float fBrightness = SCALE( fBeatsUntilStep, 0, -1, 1.f, 0.f ); diff --git a/src/GameState.cpp b/src/GameState.cpp index 54330d8dfd..4dfbd0ebe6 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -895,8 +895,6 @@ void GameState::ResetMusicStatistics() { m_Position.Reset(); - m_fMusicSecondsVisible = 0; - m_fSongBeatVisible = 0; Actor::SetBGMTime( 0, 0, 0, 0 ); FOREACH_PlayerNumber( p ) @@ -942,23 +940,16 @@ void GameState::ResetStageStatistics() m_iStageSeed = rand(); } -static Preference g_fVisualDelaySeconds( "VisualDelaySeconds", 0.0f ); - void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp ) { m_Position.UpdateSongPosition( fPositionSeconds, timing, timestamp ); FOREACH_EnabledPlayer( pn ) - m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); - - m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get(); - float fThrowAway, fThrowAway2; - bool bThrowAway; - int iThrowAway; - timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway, iThrowAway, fThrowAway2 ); + if( m_pCurSteps[pn] ) + m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); - Actor::SetBGMTime( GAMESTATE->m_fMusicSecondsVisible, GAMESTATE->m_fSongBeatVisible, fPositionSeconds, GAMESTATE->m_Position.m_fSongBeatNoOffset ); + Actor::SetBGMTime( GAMESTATE->m_Position.m_fMusicSecondsVisible, GAMESTATE->m_Position.m_fSongBeatVisible, fPositionSeconds, GAMESTATE->m_Position.m_fSongBeatNoOffset ); // LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze ); } @@ -2253,7 +2244,7 @@ public: DEFINE_METHOD( IsEventMode, IsEventMode() ) DEFINE_METHOD( GetNumPlayersEnabled, GetNumPlayersEnabled() ) DEFINE_METHOD( GetSongBeat, m_Position.m_fSongBeat ) - DEFINE_METHOD( GetSongBeatVisible, m_fSongBeatVisible ) + DEFINE_METHOD( GetSongBeatVisible, m_Position.m_fSongBeatVisible ) DEFINE_METHOD( GetSongBPS, m_Position.m_fCurBPS ) DEFINE_METHOD( GetSongFreeze, m_Position.m_bFreeze ) DEFINE_METHOD( GetSongDelay, m_Position.m_bDelay ) diff --git a/src/GameState.h b/src/GameState.h index f0446c28b8..9b192156c3 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -196,8 +196,6 @@ public: // Music statistics: SongPosition m_Position; - float m_fMusicSecondsVisible; - float m_fSongBeatVisible; BroadcastOnChange m_bGameplayLeadIn; diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 929bc974cc..60d90a09d9 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -725,7 +725,7 @@ void ScreenEdit::Init() GAMESTATE->m_Position.m_fSongBeat = 0; FOREACH_PlayerNumber( p ) GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = 0; - m_fTrailingBeat = GAMESTATE->m_Position.m_fSongBeat; + m_fTrailingBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; m_iShiftAnchor = -1; m_iStartPlayingAt = -1; @@ -929,12 +929,12 @@ void ScreenEdit::Update( float fDeltaTime ) continue; float fStartPlayingAtBeat = NoteRowToBeat(m_iStartPlayingAt); - if( GAMESTATE->m_Position.m_fSongBeat <= fStartPlayingAtBeat ) + if( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat <= fStartPlayingAtBeat ) continue; float fStartedHoldingSeconds = m_pSoundMusic->GetPositionSeconds() - fSecsHeld; float fStartBeat = max( fStartPlayingAtBeat, m_pSteps->m_Timing.GetBeatFromElapsedTime(fStartedHoldingSeconds) ); - float fEndBeat = max( fStartBeat, GAMESTATE->m_Position.m_fSongBeat ); + float fEndBeat = max( fStartBeat, GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); fEndBeat = min( fEndBeat, NoteRowToBeat(m_iStopPlayingAt) ); // Round start and end to the nearest snap interval @@ -996,12 +996,12 @@ void ScreenEdit::Update( float fDeltaTime ) // Update trailing beat - float fDelta = GAMESTATE->m_Position.m_fSongBeat - m_fTrailingBeat; + float fDelta = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat - m_fTrailingBeat; if( fabsf(fDelta) < 10 ) - fapproach( m_fTrailingBeat, GAMESTATE->m_Position.m_fSongBeat, + fapproach( m_fTrailingBeat, GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fDeltaTime*40 / m_NoteFieldEdit.GetPlayerState()->m_PlayerOptions.GetCurrent().m_fScrollSpeed ); else - fapproach( m_fTrailingBeat, GAMESTATE->m_Position.m_fSongBeat, + fapproach( m_fTrailingBeat, GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fabsf(fDelta) * fDeltaTime*5 ); PlayTicks(); @@ -1072,8 +1072,8 @@ void ScreenEdit::UpdateTextInfo() RString sNoteType = ssprintf( NOTES.GetValue(), NoteTypeToLocalizedString(m_SnapDisplay.GetNoteType()).c_str() ); RString sText; - sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GAMESTATE->m_Position.m_fSongBeat ); - sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_Position.m_fSongBeat) ); + sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); + sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ); switch( EDIT_MODE.GetValue() ) { DEFAULT_FAIL( EDIT_MODE.GetValue() ); @@ -1143,24 +1143,24 @@ void ScreenEdit::UpdateTextInfo() void ScreenEdit::DrawPrimitives() { // HACK: Draw using the trailing beat - float fSongBeat = GAMESTATE->m_Position.m_fSongBeat; // save song beat - float fSongBeatNoOffset = GAMESTATE->m_Position.m_fSongBeatNoOffset; - float fSongBeatVisible = GAMESTATE->m_fSongBeatVisible; + float fSongBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; // save song beat + float fSongBeatNoOffset = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatNoOffset; + float fSongBeatVisible = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatVisible; if( !m_pSoundMusic->IsPlaying() ) { - GAMESTATE->m_Position.m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect - GAMESTATE->m_Position.m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect - GAMESTATE->m_fSongBeatVisible = m_fTrailingBeat; // put trailing beat in effect + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatVisible = m_fTrailingBeat; // put trailing beat in effect } ScreenWithMenuElements::DrawPrimitives(); if( !m_pSoundMusic->IsPlaying() ) { - GAMESTATE->m_Position.m_fSongBeat = fSongBeat; // restore real song beat - GAMESTATE->m_Position.m_fSongBeatNoOffset = fSongBeatNoOffset; - GAMESTATE->m_fSongBeatVisible = fSongBeatVisible; + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = fSongBeat; // restore real song beat + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatNoOffset = fSongBeatNoOffset; + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatVisible = fSongBeatVisible; } } @@ -1245,7 +1245,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) m_iShiftAnchor = -1; return; } - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ).m_iNumerator; + int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iNumerator; switch( EditB ) { @@ -1271,7 +1271,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) ShiftToRightSide( iCol, m_NoteDataEdit.GetNumTracks() ); - const float fSongBeat = GAMESTATE->m_Position.m_fSongBeat; + const float fSongBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; const int iSongIndex = BeatToNoteRow( fSongBeat ); if( iCol >= m_NoteDataEdit.GetNumTracks() ) // this button is not in the range of columns for this Style @@ -1409,7 +1409,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( m_PlayerStateEdit.m_PlayerOptions.GetSong().m_fScrolls[PlayerOptions::SCROLL_REVERSE] > 0.5 ) fBeatsToMove *= -1; - float fDestinationBeat = GAMESTATE->m_Position.m_fSongBeat + fBeatsToMove; + float fDestinationBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat + fBeatsToMove; fDestinationBeat = Quantize( fDestinationBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); ScrollTo( fDestinationBeat ); @@ -1417,28 +1417,28 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_SCROLL_NEXT_MEASURE: { - float fDestinationBeat = GAMESTATE->m_Position.m_fSongBeat + beatsPerMeasure; + float fDestinationBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat + beatsPerMeasure; fDestinationBeat = ftruncf( fDestinationBeat, (float)beatsPerMeasure ); ScrollTo( fDestinationBeat ); break; } case EDIT_BUTTON_SCROLL_PREV_MEASURE: { - float fDestinationBeat = QuantizeUp( GAMESTATE->m_Position.m_fSongBeat, (float)beatsPerMeasure ); + float fDestinationBeat = QuantizeUp( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, (float)beatsPerMeasure ); fDestinationBeat -= (float)beatsPerMeasure; ScrollTo( fDestinationBeat ); break; } case EDIT_BUTTON_SCROLL_NEXT: { - int iRow = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); + int iRow = BeatToNoteRow( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); NoteDataUtil::GetNextEditorPosition( m_NoteDataEdit, iRow ); ScrollTo( NoteRowToBeat(iRow) ); } break; case EDIT_BUTTON_SCROLL_PREV: { - int iRow = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); + int iRow = BeatToNoteRow( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); NoteDataUtil::GetPrevEditorPosition( m_NoteDataEdit, iRow ); ScrollTo( NoteRowToBeat(iRow) ); } @@ -1446,13 +1446,13 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_LABEL_NEXT: { ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming. - GetNextLabelSegmentBeatAtBeat( GAMESTATE->m_Position.m_fSongBeat ) ); + GetNextLabelSegmentBeatAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) ); } break; case EDIT_BUTTON_LABEL_PREV: { ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming. - GetPreviousLabelSegmentBeatAtBeat( GAMESTATE->m_Position.m_fSongBeat ) ); + GetPreviousLabelSegmentBeatAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) ); } break; case EDIT_BUTTON_SNAP_NEXT: @@ -1465,11 +1465,11 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_LAY_SELECT: { - const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); + const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); if( m_NoteFieldEdit.m_iBeginMarker==-1 && m_NoteFieldEdit.m_iEndMarker==-1 ) { // lay begin marker - m_NoteFieldEdit.m_iBeginMarker = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); + m_NoteFieldEdit.m_iBeginMarker = BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); } else if( m_NoteFieldEdit.m_iEndMarker==-1 ) // only begin marker is laid { @@ -1581,7 +1581,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_BPM_UP: case EDIT_BUTTON_BPM_DOWN: { - float fBPM = m_pSteps->m_Timing.GetBPMAtBeat( GAMESTATE->m_Position.m_fSongBeat ); + float fBPM = m_pSteps->m_Timing.GetBPMAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); float fDelta; switch( EditB ) { @@ -1602,7 +1602,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } float fNewBPM = fBPM + fDelta; - m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_Position.m_fSongBeat, fNewBPM ); + m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fNewBPM ); (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); } @@ -1631,7 +1631,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) unsigned i; for( i=0; im_Timing.m_StopSegments.size(); i++ ) { - if( m_pSteps->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) + if( m_pSteps->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ) break; } @@ -1639,7 +1639,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { // create a new StopSegment if( fDelta > 0 ) - m_pSteps->m_Timing.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), fDelta) ); + m_pSteps->m_Timing.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), fDelta) ); } else // StopSegment being modified is m_SongTiming.m_StopSegments[i] { @@ -1809,7 +1809,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) BackgroundChange bgChange; FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer), bgc ) { - if( bgc->m_fStartBeat == GAMESTATE->m_Position.m_fSongBeat ) + if( bgc->m_fStartBeat == GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) { bAlreadyBGChangeHere = true; bgChange = *bgc; @@ -1902,7 +1902,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( pCourse == NULL ) break; CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; - float fStartTime = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_Position.m_fSongBeat ); + float fStartTime = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); int iAttack = FindAttackAtTime( ce.attacks, fStartTime ); if( iAttack >= 0 ) @@ -2014,12 +2014,12 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { if( g_iDefaultRecordLength.Get() == -1 ) { - m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); + m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); m_iStopPlayingAt = max( m_iStartPlayingAt, m_NoteDataEdit.GetLastRow() + 1 ); } else { - m_iStartPlayingAt = BeatToNoteRow( ftruncf(GAMESTATE->m_Position.m_fSongBeat, g_iDefaultRecordLength.Get()) ); + m_iStartPlayingAt = BeatToNoteRow( ftruncf(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, g_iDefaultRecordLength.Get()) ); m_iStopPlayingAt = m_iStartPlayingAt + BeatToNoteRow( g_iDefaultRecordLength.Get() ); } @@ -2036,7 +2036,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } break; case EDIT_BUTTON_RECORD_FROM_CURSOR: - m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); + m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); m_iStopPlayingAt = max( m_iStartPlayingAt, m_NoteDataEdit.GetLastRow() ); TransitionEditState( STATE_RECORDING ); break; @@ -2105,7 +2105,7 @@ void ScreenEdit::InputRecord( const InputEventPlus &input, EditButton EditB ) } // Add a tap - float fBeat = GAMESTATE->m_Position.m_fSongBeat; + float fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; fBeat = Quantize( fBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); const int iRow = BeatToNoteRow( fBeat ); @@ -2241,7 +2241,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB ) { case EDIT_BUTTON_RETURN_TO_EDIT: /* When exiting play mode manually, leave the cursor where it is. */ - m_fBeatToReturnTo = GAMESTATE->m_Position.m_fSongBeat; + m_fBeatToReturnTo = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; TransitionEditState( STATE_EDITING ); break; case EDIT_BUTTON_OFFSET_UP: @@ -2312,7 +2312,7 @@ void ScreenEdit::TransitionEditState( EditState em ) { case STATE_EDITING: // If exiting EDIT mode, save the cursor position. - m_fBeatToReturnTo = GAMESTATE->m_Position.m_fSongBeat; + m_fBeatToReturnTo = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; break; case STATE_PLAYING: @@ -2365,14 +2365,14 @@ void ScreenEdit::TransitionEditState( EditState em ) m_Foreground.Unload(); // Restore the cursor position. - GAMESTATE->m_Position.m_fSongBeat = m_fBeatToReturnTo; + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_fBeatToReturnTo; // Make sure we're snapped. - GAMESTATE->m_Position.m_fSongBeat = Quantize( GAMESTATE->m_Position.m_fSongBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = Quantize( GAMESTATE->m_Position.m_fSongBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); /* Playing and recording have lead-ins, which may start before beat 0; * make sure we don't stay there if we escaped out early. */ - GAMESTATE->m_Position.m_fSongBeat = max( GAMESTATE->m_Position.m_fSongBeat, 0 ); + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = max( GAMESTATE->m_Position.m_fSongBeat, 0 ); break; @@ -2465,7 +2465,7 @@ void ScreenEdit::TransitionEditState( EditState em ) { case STATE_PLAYING: case STATE_RECORDING: - const float fStartSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_Position.m_fSongBeat); + const float fStartSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); LOG->Trace( "Starting playback at %f", fStartSeconds ); RageSoundParams p; @@ -2485,11 +2485,11 @@ void ScreenEdit::ScrollTo( float fDestinationBeat ) CLAMP( fDestinationBeat, 0, GetMaximumBeatForMoving() ); // Don't play the sound and do the hold note logic below if our position didn't change. - const float fOriginalBeat = GAMESTATE->m_Position.m_fSongBeat; + const float fOriginalBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; if( fOriginalBeat == fDestinationBeat ) return; - GAMESTATE->m_Position.m_fSongBeat = fDestinationBeat; + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = fDestinationBeat; // check to see if they're holding a button for( int n=0; n 0 ) - m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_Position.m_fSongBeat, fBPM ); + m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fBPM ); SetDirty( true ); } else if( SM == SM_BackFromStopChange ) { float fStop = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fStop >= 0 ) - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_Position.m_fSongBeat, fStop ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fStop ); SetDirty( true ); } else if( SM == SM_BackFromDelayChange ) { float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fDelay >= 0 ) - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_Position.m_fSongBeat, fDelay, true ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fDelay, true ); SetDirty( true ); } else if( SM == SM_BackFromTimeSignatureNumeratorChange ) @@ -2651,7 +2651,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iNum = atoi( ScreenTextEntry::s_sLastAnswer ); if( iNum > 0 ) { - m_pSteps->m_Timing.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_Position.m_fSongBeat, iNum ); + m_pSteps->m_Timing.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iNum ); } SetDirty( true ); } @@ -2660,7 +2660,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iDen = atoi( ScreenTextEntry::s_sLastAnswer ); if( iDen > 0) { - m_pSteps->m_Timing.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_Position.m_fSongBeat, iDen ); + m_pSteps->m_Timing.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iDen ); } SetDirty( true ); } @@ -2669,7 +2669,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iTick = atoi( ScreenTextEntry::s_sLastAnswer ); if ( iTick >= 0 && iTick <= ROWS_PER_BEAT ) { - m_pSteps->m_Timing.SetTickcountAtBeat( GAMESTATE->m_Position.m_fSongBeat, iTick ); + m_pSteps->m_Timing.SetTickcountAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iTick ); } SetDirty( true ); } @@ -2678,7 +2678,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iCombo = atoi( ScreenTextEntry::s_sLastAnswer ); if ( iCombo >= 0 ) { - m_pSteps->m_Timing.SetComboAtBeat( GAMESTATE->m_Position.m_fSongBeat, iCombo ); + m_pSteps->m_Timing.SetComboAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iCombo ); } SetDirty( true ); } @@ -2689,14 +2689,14 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { sLabel.Replace("=", "_"); sLabel.Replace(",", "_"); - m_pSteps->m_Timing.SetLabelAtBeat( GAMESTATE->m_Position.m_fSongBeat, sLabel ); + m_pSteps->m_Timing.SetLabelAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, sLabel ); SetDirty( true ); } } else if ( SM == SM_BackFromWarpChange ) { float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer ); - m_pSteps->m_Timing.SetWarpAtBeat( GAMESTATE->m_Position.m_fSongBeat, fWarp ); + m_pSteps->m_Timing.SetWarpAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fWarp ); SetDirty( true ); } else if( SM == SM_BackFromBGChange ) @@ -2924,12 +2924,12 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { /* When another screen comes up, RageSounds takes over the sound timer. When we come * back, put the timer back to where it was. */ - GAMESTATE->m_Position.m_fSongBeat = m_fTrailingBeat; + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_fTrailingBeat; } else if( SM == SM_LoseFocus ) { // Snap the trailing beat, in case we lose focus while tweening. - m_fTrailingBeat = GAMESTATE->m_Position.m_fSongBeat; + m_fTrailingBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; } ScreenWithMenuElements::HandleScreenMessage( SM ); @@ -2940,10 +2940,10 @@ void ScreenEdit::OnSnapModeChange() m_soundChangeSnap.Play(); NoteType nt = m_SnapDisplay.GetNoteType(); - int iStepIndex = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); + int iStepIndex = BeatToNoteRow( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); int iElementsPerNoteType = BeatToNoteRow( NoteTypeToBeat(nt) ); int iStepIndexHangover = iStepIndex % iElementsPerNoteType; - GAMESTATE->m_Position.m_fSongBeat -= NoteRowToBeat( iStepIndexHangover ); + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat -= NoteRowToBeat( iStepIndexHangover ); } @@ -3090,14 +3090,14 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns break; case play_current_beat_to_end: { - m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); + m_iStartPlayingAt = BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); m_iStopPlayingAt = max( m_iStartPlayingAt, m_NoteDataEdit.GetLastRow() ); TransitionEditState( STATE_PLAYING ); } break; case set_selection_start: { - const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); + const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); if( m_NoteFieldEdit.m_iEndMarker!=-1 && iCurrentRow >= m_NoteFieldEdit.m_iEndMarker ) { SCREENMAN->PlayInvalidSound(); @@ -3111,7 +3111,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns break; case set_selection_end: { - const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat); + const int iCurrentRow = BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); if( m_NoteFieldEdit.m_iBeginMarker!=-1 && iCurrentRow <= m_NoteFieldEdit.m_iBeginMarker ) { SCREENMAN->PlayInvalidSound(); @@ -3258,7 +3258,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns case edit_timing_data: { TimingData pTime = m_pSteps->m_Timing; - const float fBeat = GAMESTATE->m_Position.m_fSongBeat; + const float fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); @@ -3363,7 +3363,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns { DEFAULT_FAIL( c ); case paste_at_current_beat: - iDestFirstRow = BeatToNoteRow( GAMESTATE->m_Position.m_fSongBeat ); + iDestFirstRow = BeatToNoteRow( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); break; case paste_at_begin_marker: ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 ); @@ -3541,16 +3541,16 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns TransitionEditState( STATE_RECORDING ); break; case insert_and_shift: - NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), BeatToNoteRow(1) ); + NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), BeatToNoteRow(1) ); break; case delete_and_shift: - NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), BeatToNoteRow(1) ); + NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), BeatToNoteRow(1) ); break; case shift_pauses_forward: - m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), BeatToNoteRow(1) ); + m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), BeatToNoteRow(1) ); break; case shift_pauses_backward: - m_pSteps->m_Timing.DeleteRows( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat), BeatToNoteRow(1) ); + m_pSteps->m_Timing.DeleteRows( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), BeatToNoteRow(1) ); break; case convert_to_pause: { @@ -3578,14 +3578,14 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case convert_pause_to_beat: { // TODO: Convert both Delays and Stops at once. - float fStopSeconds = m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ); - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_Position.m_fSongBeat, 0 ); + float fStopSeconds = m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ); + m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, 0 ); - float fStopBeats = fStopSeconds * m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_Position.m_fSongBeat) / 60; + float fStopBeats = fStopSeconds * m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) / 60; // don't move the step from where it is, just move everything later - NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); - m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); + NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); + m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); } break; case undo: @@ -3751,7 +3751,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromBPMChange, ENTER_BPM_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_Position.m_fSongBeat) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ), 10 ); break; @@ -3759,7 +3759,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromStopChange, ENTER_STOP_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ) ), 10 ); break; @@ -3767,7 +3767,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromDelayChange, ENTER_DELAY_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ) ), 10 ); break; @@ -3775,7 +3775,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureNumeratorChange, ENTER_TIME_SIGNATURE_NUMERATOR_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ).m_iNumerator ), + ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iNumerator ), 3 ); break; @@ -3783,7 +3783,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureDenominatorChange, ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ).m_iDenominator ), + ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iDenominator ), 3 ); break; @@ -3791,7 +3791,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTickcountChange, ENTER_TICKCOUNT_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTickcountAtBeat( GAMESTATE->m_Position.m_fSongBeat ) ), + ssprintf( "%d", m_pSteps->m_Timing.GetTickcountAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) ), 2 ); break; @@ -3799,7 +3799,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromComboChange, ENTER_COMBO_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetComboAtBeat( GAMESTATE->m_Position.m_fSongBeat ) ), + ssprintf( "%d", m_pSteps->m_Timing.GetComboAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) ), 4 ); break; @@ -3807,7 +3807,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromLabelChange, ENTER_LABEL_VALUE, - ssprintf( "%s", m_pSteps->m_Timing.GetLabelAtBeat( GAMESTATE->m_Position.m_fSongBeat ).c_str() ), + ssprintf( "%s", m_pSteps->m_Timing.GetLabelAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).c_str() ), 64 ); break; @@ -3815,7 +3815,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromWarpChange, ENTER_WARP_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) ), + ssprintf( "%.4f", m_pSteps->m_Timing.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ) ), 10 ); break; @@ -4022,7 +4022,7 @@ void ScreenEdit::CheckNumberOfNotesAndUndo() if( EDIT_MODE.GetValue() != EditMode_Home ) return; - TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ); + TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); int rowsPerMeasure = curTime.m_iDenominator * curTime.m_iNumerator; for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure ) @@ -4074,7 +4074,7 @@ float ScreenEdit::GetMaximumBeatForNewNote() const /* Round up to the next measure end. Some songs end on weird beats * mid-measure, and it's odd to have movement capped to these weird * beats. */ - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ).m_iNumerator; + int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iNumerator; fEndBeat += beatsPerMeasure; fEndBeat = ftruncf( fEndBeat, (float)beatsPerMeasure ); diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp index 14a67c1806..048c93708c 100644 --- a/src/SongPosition.cpp +++ b/src/SongPosition.cpp @@ -1,5 +1,7 @@ #include "SongPosition.h" +static Preference g_fVisualDelaySeconds( "VisualDelaySeconds", 0.0f ); + void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp ) { @@ -43,12 +45,21 @@ void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData } } */ + + m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get(); + float fThrowAway, fThrowAway2; + bool bThrowAway; + int iThrowAway; + timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway, iThrowAway, fThrowAway2 ); } void SongPosition::Reset() { + m_fMusicSecondsVisible = 0; + m_fSongBeatVisible = 0; + m_fMusicSeconds = 0; // MUSIC_SECONDS_INVALID; // todo: move me to FOREACH_EnabledPlayer( p ) after [NUM_PLAYERS]ing m_fSongBeat = 0; diff --git a/src/SongPosition.h b/src/SongPosition.h index abe1dc2a8e..56cf0e38d5 100644 --- a/src/SongPosition.h +++ b/src/SongPosition.h @@ -31,6 +31,8 @@ class SongPosition /** @brief The beat to warp to afterwards. */ float m_fWarpDestination; RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update + float m_fMusicSecondsVisible; + float m_fSongBeatVisible; void Reset(); void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp = RageZeroTimer ); From 378b4383895dd62dc27628f1c4c9cc335f588dcd Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Wed, 11 May 2011 21:22:18 +0700 Subject: [PATCH 034/197] [splittiming] screenedit now behaves (just moving around, charting process not tested) some work need to be done on snapping and transitioning between editing and playing. --- src/ScreenEdit.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 60d90a09d9..76ae67a362 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1142,26 +1142,30 @@ void ScreenEdit::UpdateTextInfo() void ScreenEdit::DrawPrimitives() { - // HACK: Draw using the trailing beat - float fSongBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; // save song beat - float fSongBeatNoOffset = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatNoOffset; - float fSongBeatVisible = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatVisible; - if( !m_pSoundMusic->IsPlaying() ) + if( m_pSoundMusic->IsPlaying() ) { - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatVisible = m_fTrailingBeat; // put trailing beat in effect + ScreenWithMenuElements::DrawPrimitives(); + return; } + // HACK: Draw using the trailing beat + PlayerState *pPlayerState = const_cast (m_NoteFieldEdit.GetPlayerState()); + + float fSongBeat = pPlayerState->m_Position.m_fSongBeat; // save song beat + float fSongBeatNoOffset = pPlayerState->m_Position.m_fSongBeatNoOffset; + float fSongBeatVisible = pPlayerState->m_Position.m_fSongBeatVisible; + + pPlayerState->m_Position.m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect + pPlayerState->m_Position.m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect + pPlayerState->m_Position.m_fSongBeatVisible = m_fTrailingBeat; // put trailing beat in effect + ScreenWithMenuElements::DrawPrimitives(); - if( !m_pSoundMusic->IsPlaying() ) - { - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = fSongBeat; // restore real song beat - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatNoOffset = fSongBeatNoOffset; - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeatVisible = fSongBeatVisible; - } + pPlayerState->m_Position.m_fSongBeat = fSongBeat; // restore real song beat + pPlayerState->m_Position.m_fSongBeatNoOffset = fSongBeatNoOffset; + pPlayerState->m_Position.m_fSongBeatVisible = fSongBeatVisible; + } void ScreenEdit::Input( const InputEventPlus &input ) From 33172945ea0e1688b52e4a28785d4f5e2478f2d6 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 11 May 2011 11:03:12 -0400 Subject: [PATCH 035/197] [splittiming] Players, invalidate your caches! --- src/Song.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Song.cpp b/src/Song.cpp index c5986b0284..47c84ed8b3 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -41,7 +41,7 @@ * @brief The internal version of the cache for StepMania. * * Increment this value to invalidate the current cache. */ -const int FILE_CACHE_VERSION = 171; +const int FILE_CACHE_VERSION = 172; /** @brief How long does a song sample last by default? */ const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f; From a8f2d0094fcf627edd65e33f7cd5b424c5fcced2 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Wed, 11 May 2011 22:08:38 +0700 Subject: [PATCH 036/197] [splittiming] I accidently hardcoded PLAYER_1 in NoteField --- src/NoteField.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 72a9ceb90e..5f76e23d3e 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -742,7 +742,7 @@ void NoteField::DrawPrimitives() // Draw beat bars if( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) { - const vector &vTimeSignatureSegments = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing.m_vTimeSignatureSegments; + const vector &vTimeSignatureSegments = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing.m_vTimeSignatureSegments; int iMeasureIndex = 0; FOREACH_CONST( TimeSignatureSegment, vTimeSignatureSegments, iter ) { @@ -785,7 +785,7 @@ void NoteField::DrawPrimitives() { ASSERT(GAMESTATE->m_pCurSong); - const TimingData &timing = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing; + const TimingData &timing = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing; // BPM text FOREACH_CONST( BPMSegment, timing.m_BPMSegments, seg ) From a47830834555725e203c6c709c8824d2af34558f Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Wed, 11 May 2011 22:57:55 +0700 Subject: [PATCH 037/197] [splittiming] Fix crash. I don't know what caused it and how it was caused, but this fixed it. --- src/PlayerOptions.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PlayerOptions.h b/src/PlayerOptions.h index 8a66d1d758..c6ea986160 100644 --- a/src/PlayerOptions.h +++ b/src/PlayerOptions.h @@ -35,8 +35,9 @@ public: m_fPassmark(0), m_SpeedfPassmark(1.0f), m_fRandomSpeed(0), m_SpeedfRandomSpeed(1.0f), m_bMuteOnError(false), m_FailType(FAIL_IMMEDIATE), - m_ScoreDisplay(SCORING_ADD), m_sNoteSkin("") + m_ScoreDisplay(SCORING_ADD) { + m_sNoteSkin = ""; ZERO( m_fAccels ); ONE( m_SpeedfAccels ); ZERO( m_fEffects ); ONE( m_SpeedfEffects ); ZERO( m_fAppearances ); ONE( m_SpeedfAppearances ); From 04d45bca1c50b44bee8a802187b1bdcbaa11b9ca Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 11 May 2011 17:13:22 -0400 Subject: [PATCH 038/197] [splittiming] Right, we store ints. --- src/NotesLoaderKSF.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index af36be25d2..ca066c3361 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -194,7 +194,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, RString temp = sRowString.substr(2,sRowString.size()-3); newTick = StringToInt(temp); bTickChangeNeeded = true; - out.m_Timing.AddTickcountSegment(TickcountSegment(fCurBeat, newTick)); + out.m_Timing.AddTickcountSegment(TickcountSegment(BeatToNoteRow(fCurBeat), newTick)); continue; } else From 68b391481d9a38a176ad28716224c977c025b113 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 11 May 2011 18:19:39 -0400 Subject: [PATCH 039/197] [splittiming] Rewritten to be more modular. Guess I'll have some fun with this tonight. --- src/NotesLoaderKSF.cpp | 255 ++++++++++++++++++++++++++++------------- 1 file changed, 177 insertions(+), 78 deletions(-) diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index ca066c3361..862c4bd485 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -9,6 +9,51 @@ #include "Song.h" #include "Steps.h" +static void HandleBunki( TimingData &timing, const float fEarlyBPM, + const float fCurBPM, const float fGap, + const float fPos ) +{ + const float BeatsPerSecond = fEarlyBPM / 60.0f; + const float beat = (fPos + fGap) * BeatsPerSecond; + LOG->Trace( "BPM %f, BPS %f, BPMPos %f, beat %f", + fEarlyBPM, BeatsPerSecond, fPos, beat ); + timing.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), fCurBPM) ); +} + +static bool HandlePipeChars( TimingData &timing, const RString sNoteRow, + const float fCurBeat, int &iTickCount ) +{ + RString temp = sNoteRow.substr(2,sNoteRow.size()-3); + float numTemp = StringToFloat(temp); + if (BeginsWith(sNoteRow, "|T")) + { + iTickCount = static_cast(numTemp); + timing.SetTickcountAtBeat( fCurBeat, clamp(iTickCount, 0, ROWS_PER_BEAT) ); + return true; + } + else if (BeginsWith(sNoteRow, "|B")) + { + timing.SetBPMAtBeat( fCurBeat, numTemp ); + return true; + } + else if (BeginsWith(sNoteRow, "|E")) + { + // Finally! the |E| tag is working as it should. I can die happy now -DaisuMaster + float fCurDelay = 60 / timing.GetBPMAtBeat(fCurBeat) * numTemp / iTickCount; + fCurDelay += timing.GetDelayAtRow(BeatToNoteRow(fCurBeat) ); + timing.SetStopAtBeat( fCurBeat, fCurDelay, true ); + return true; + } + else if (BeginsWith(sNoteRow, "|D")) + { + float fCurDelay = timing.GetStopAtRow(BeatToNoteRow(fCurBeat) ); + fCurDelay += numTemp / 1000; + timing.SetStopAtBeat( fCurBeat, fCurDelay, true ); + return true; + } + return false; +} + static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, bool bKIUCompliant ) { LOG->Trace( "Steps::LoadFromKSFFile( '%s' )", sPath.c_str() ); @@ -25,6 +70,9 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, // According to Aldo_MX, there is a default BPM and it's 60. -aj bool bDoublesChart = false; + + TimingData stepsTiming; + float SMGap1 = 0, SMGap2 = 0, BPM1 = -1, BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1; for( unsigned i=0; iUserLog( "Song file", sPath, "doesn't have a TICKCOUNT. Defaulting to %i.", iTickCount ); } + + // Prepare BPM stuff already if the file uses KSF syntax. + if( bKIUCompliant ) + { + if( BPM2 > 0 && BPMPos2 > 0 ) + { + HandleBunki( stepsTiming, BPM1, BPM2, SMGap1, BPMPos2 ); + } + + if( BPM3 > 0 && BPMPos3 > 0 ) + { + HandleBunki( stepsTiming, BPM2, BPM3, SMGap2, BPMPos3 ); + } + } NoteData notedata; // read it into here @@ -148,6 +291,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, int newTick = -1; float fCurBeat = 0.0f; float prevBeat = 0.0f; // Used for hold tails. + for( unsigned r=0; rUserLog( "Song file", sPath, "has illegal syntax \"%s\" which can't be in KIU complient files.", - sRowString.c_str() ); - return false; - //In other words: you can't mix ksf's with DM05 tags and ksf's without any DM05 tags - //Either one set or another will be read... - }*/ - if( BeginsWith(sRowString, "|B") || BeginsWith(sRowString, "|D") || BeginsWith(sRowString, "|E") ) - { - // TODO: Update for Split Timing. - continue; - } - else if ( BeginsWith(sRowString, "|T") ) - { - RString temp = sRowString.substr(2,sRowString.size()-3); - newTick = StringToInt(temp); - bTickChangeNeeded = true; - out.m_Timing.AddTickcountSegment(TickcountSegment(BeatToNoteRow(fCurBeat), newTick)); + if (bKIUCompliant) + { + // Log an error, ignore the line. + continue; + } + if ( !HandlePipeChars( stepsTiming, sRowString, fCurBeat, iTickCount ) ) + { + // LOG it first. + } continue; + } + else { // Is this why improper ksf or some kiucompilant ksf mixed with dm05 ksf are ignored?? -DaisuMaster @@ -273,6 +408,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, } out.SetNoteData( notedata ); + out.m_Timing = stepsTiming; out.TidyUpData(); @@ -468,21 +604,12 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant { if( BPM2 > 0 && BPMPos2 > 0 ) { - const float BeatsPerSecond = BPM1 / 60.0f; - const float beat = (BPMPos2 + SMGap1) * BeatsPerSecond; - LOG->Trace( "BPM %f, BPS %f, BPMPos2 %f, beat %f", - BPM1, BeatsPerSecond, BPMPos2, beat ); - out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM2) ); + HandleBunki( out.m_SongTiming, BPM1, BPM2, SMGap1, BPMPos2 ); } if( BPM3 > 0 && BPMPos3 > 0 ) { - const float BeatsPerSecond = BPM2 / 60.0f; - //The line below isn't perfect, but works better than previous versions. - const float beat = (BPMPos3 + SMGap2) * BeatsPerSecond; - LOG->Trace( "BPM %f, BPS %f, BPMPos3 %f, beat %f", - BPM2, BeatsPerSecond, BPMPos3, beat ); - out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), BPM3) ); + HandleBunki( out.m_SongTiming, BPM2, BPM3, SMGap2, BPMPos3 ); } } else @@ -510,40 +637,11 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant BeginsWith(NoteRowString, "|D") || BeginsWith(NoteRowString, "|E") ) { bDMRequired = true; - RString temp = NoteRowString.substr(2,NoteRowString.size()-3); - float numTemp = StringToFloat(temp); - if (BeginsWith(NoteRowString, "|T")) + if ( !HandlePipeChars( out.m_SongTiming, NoteRowString, fCurBeat, iTickCount ) ) { - iTickCount = (int)numTemp; - TickcountSegment tcs; - tcs.m_iStartRow = BeatToNoteRow(fCurBeat); - tcs.m_iTicks = iTickCount > ROWS_PER_BEAT ? ROWS_PER_BEAT : iTickCount; - out.m_SongTiming.AddTickcountSegment( tcs ); - - continue; - } - else if (BeginsWith(NoteRowString, "|B")) - { - float fCurBpm = (float)numTemp; - //out.m_Timing.AddBPMSegment( BPMSegment( BeatToNoteRow(fCurBeat), (float)numTemp ) ); - out.m_SongTiming.SetBPMAtBeat( fCurBeat, fCurBpm ); - continue; - } - else if (BeginsWith(NoteRowString, "|E")) - { - // Finally! the |E| tag is working as it should. I can die happy now -DaisuMaster - float fCurDelay = 60 / out.m_SongTiming.GetBPMAtBeat(fCurBeat) * (float)numTemp / iTickCount; - fCurDelay += out.m_SongTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) ); - out.m_SongTiming.SetStopAtBeat( fCurBeat, fCurDelay, true ); - continue; - } - else if (BeginsWith(NoteRowString, "|D")) - { - float fCurDelay = out.m_SongTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) ); - fCurDelay += (float)numTemp / 1000; - out.m_SongTiming.SetStopAtBeat( fCurBeat, fCurDelay, true ); - continue; + // LOG it first. } + continue; } else { @@ -583,16 +681,17 @@ bool KSFLoader::LoadFromDir( const RString &sDir, Song &out ) ASSERT( arrayKSFFileNames.size() ); bool bKIUCompliant = false; - /* If only the first file is read, it will cause problems for other simfiles with - * different BPM changes and tickcounts. This command will probably have to be - * changed in the future. */ + /* With Split Timing, there has to be a backup Song Timing in case + * anything goes wrong. Use the first file found to determine said + * timing, while also establishing whether this file respects the + * Kick It Up syntax. */ if( !LoadGlobalData(out.GetSongDir() + arrayKSFFileNames[0], out, bKIUCompliant) ) return false; // load the Steps from the rest of the KSF files for( unsigned i=0; i Date: Thu, 12 May 2011 16:44:24 +0700 Subject: [PATCH 040/197] [splittiming] - load split timing from BMS files - fix a crash because autogen'd steps don't inherit the timing from parent - be more verbose in UpdateSongPosition --- src/AutoKeysounds.cpp | 2 +- src/GameState.cpp | 9 +- src/GameState.h | 2 +- src/NotesLoaderBMS.cpp | 408 +++++++++++++++++++++++------------------ src/ScreenEdit.cpp | 4 +- src/ScreenGameplay.cpp | 2 +- src/Steps.cpp | 2 + 7 files changed, 243 insertions(+), 186 deletions(-) diff --git a/src/AutoKeysounds.cpp b/src/AutoKeysounds.cpp index aba066200d..79ec773973 100644 --- a/src/AutoKeysounds.cpp +++ b/src/AutoKeysounds.cpp @@ -99,7 +99,7 @@ void AutoKeysounds::LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain ) if( tn[pn].iKeysoundIndex >= 0 ) { RString sKeysoundFilePath = sSongDir + pSong->m_vsKeysoundFile[tn[pn].iKeysoundIndex]; - float fSeconds = pSong->m_SongTiming.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency(); + float fSeconds = GAMESTATE->m_pCurSteps[pn]->m_Timing.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency(); float fPan = 0; if( !bSoundIsGlobal ) diff --git a/src/GameState.cpp b/src/GameState.cpp index 4dfbd0ebe6..fd8f2c487b 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -940,14 +940,15 @@ void GameState::ResetStageStatistics() m_iStageSeed = rand(); } -void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp ) +void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp, bool bUpdatePlayers ) { m_Position.UpdateSongPosition( fPositionSeconds, timing, timestamp ); - FOREACH_EnabledPlayer( pn ) - if( m_pCurSteps[pn] ) - m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); + if( bUpdatePlayers ) + FOREACH_EnabledPlayer( pn ) + if( m_pCurSteps[pn] ) + m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); Actor::SetBGMTime( GAMESTATE->m_Position.m_fMusicSecondsVisible, GAMESTATE->m_Position.m_fSongBeatVisible, fPositionSeconds, GAMESTATE->m_Position.m_fSongBeatNoOffset ); // LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze ); diff --git a/src/GameState.h b/src/GameState.h index 9b192156c3..000219a343 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -205,7 +205,7 @@ public: static const float MUSIC_SECONDS_INVALID; void ResetMusicStatistics(); // Call this when it's time to play a new song. Clears the values above. - void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp = RageZeroTimer ); + void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp = RageZeroTimer, bool bUpdatePlayers = false ); float GetSongPercent( float beat ) const; bool AllAreInDangerOrWorse() const; diff --git a/src/NotesLoaderBMS.cpp b/src/NotesLoaderBMS.cpp index 9eb58168ed..b05f9d8807 100644 --- a/src/NotesLoaderBMS.cpp +++ b/src/NotesLoaderBMS.cpp @@ -435,9 +435,121 @@ static void ReadTimeSigs( const NameToData_t &mapNameToData, MeasureToTimeSig_t static const int BEATS_PER_MEASURE = 4; static const int ROWS_PER_MEASURE = ROWS_PER_BEAT * BEATS_PER_MEASURE; -static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameToData, Steps &out, - const MeasureToTimeSig_t &sigAdjustments, const map &idToKeySoundIndex ) +static bool SearchForKeysound( const RString &sPath, RString nDataOriginal, map &mapFilenameToKeysoundIndex, Song &out, int &outKeysoundIndex ) { + + // Search for memoized file names: + { + RString nDataToSearchFor = nDataOriginal; + nDataToSearchFor.MakeLower(); + map::iterator it = mapFilenameToKeysoundIndex.find(nDataToSearchFor); + if (it != mapFilenameToKeysoundIndex.end()) { + outKeysoundIndex = it->second; + return true; + } + } + + // FIXME: garbled song names seem to crash the app. + // this might not be the best place to put this code. + if( !utf8_is_valid(nDataOriginal) ) + return false; + + /* Due to bugs in some programs, many BMS files have a "WAV" extension + * on files in the BMS for files that actually have some other extension. + * Do a search. Don't do a wildcard search; if sData is "song.wav", + * we might also have "song.png", which we shouldn't match. */ + RString nData = nDataOriginal; + if( !IsAFile(out.GetSongDir()+nData) ) + { + const char *exts[] = { "oga", "ogg", "wav", "mp3", NULL }; // XXX: stop duplicating these everywhere + for( unsigned i = 0; exts[i] != NULL; ++i ) + { + RString fn = SetExtension( nData, exts[i] ); + if( IsAFile(out.GetSongDir()+fn) ) + { + nData = fn; + break; + } + } + } + + if( !IsAFile(out.GetSongDir()+nData) ) + { + LOG->UserLog( "Song file", out.GetSongDir(), "references key \"%s\" that can't be found", nData.c_str() ); + return false; + } + + // Let's again search for memoized file names (we got the normalized one!): + { + RString nDataToSearchFor = nData; + nDataToSearchFor.MakeLower(); + map::iterator it = mapFilenameToKeysoundIndex.find(nDataToSearchFor); + if (it != mapFilenameToKeysoundIndex.end()) { + outKeysoundIndex = it->second; + + { + RString nDataToAdd = nDataOriginal; + nDataToAdd.MakeLower(); + mapFilenameToKeysoundIndex[nDataToAdd] = outKeysoundIndex; + } + + return true; + } + } + + // Now this is a new sample. + out.m_vsKeysoundFile.push_back( nData ); + outKeysoundIndex = out.m_vsKeysoundFile.size() - 1; + + { + RString nDataToAdd = nDataOriginal; + nDataToAdd.MakeLower(); + mapFilenameToKeysoundIndex[nDataToAdd] = outKeysoundIndex; + } + + { + RString nDataToAdd = nData; + nDataToAdd.MakeLower(); + mapFilenameToKeysoundIndex[nDataToAdd] = outKeysoundIndex; + } + + return true; + +} + +static bool SearchForKeysound( const RString &sPath, RString sNoteId, const NameToData_t &mapNameToData, map &mapIdToKeysoundIndex, map &mapFilenameToKeysoundIndex, Song &out, int &outKeysoundIndex ) +{ + + sNoteId.MakeLower(); + { + map::iterator it = mapIdToKeysoundIndex.find(sNoteId); + if (it != mapIdToKeysoundIndex.end()) + { + outKeysoundIndex = it->second; + return outKeysoundIndex >= 0; + } + } + + RString sTagToLookFor = ssprintf( "#wav%s", sNoteId.c_str() ); + RString nDataOriginal; + if( !GetTagFromMap( mapNameToData, sTagToLookFor, nDataOriginal ) ) + { + LOG->UserLog( "Song file", sPath.c_str(), "has tag \"%s\" which cannot be found.", sTagToLookFor.c_str() ); + return false; + } + + bool retval = SearchForKeysound(sPath, nDataOriginal, mapFilenameToKeysoundIndex, out, outKeysoundIndex); + mapIdToKeysoundIndex[sNoteId] = outKeysoundIndex; + return retval; + +} + +static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameToData, Steps &out, Song &outSong, map &mapFilenameToKeysoundIndex ) +{ + + map mapIdToKeysoundIndex; + MeasureToTimeSig_t sigAdjustments; + LOG->Trace( "Steps::LoadFromBMSFile( '%s' )", sPath.c_str() ); out.m_StepsType = StepsType_Invalid; @@ -453,11 +565,121 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo NoteData ndNotes; ndNotes.SetNumTracks( NUM_BMS_TRACKS ); + // Read BPM + if( GetTagFromMap(mapNameToData, "#bpm", sData) ) + { + const float fBPM = StringToFloat( sData ); + + if( fBPM > 0.0f ) + { + BPMSegment newSeg( 0, fBPM ); + out.m_Timing.AddBPMSegment( newSeg ); + LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM ); + } + else + { + LOG->UserLog( "Song file", sPath.c_str(), "has an invalid BPM change at beat %f, BPM %f.", + NoteRowToBeat(0), fBPM ); + } + } + + /* Read time signatures. Note that these can differ across files in the same * song. */ MeasureToTimeSig_t mapMeasureToTimeSig; ReadTimeSigs( mapNameToData, mapMeasureToTimeSig ); + for( NameToData_t::const_iterator it = mapNameToData.lower_bound("#00000"); it != mapNameToData.end(); ++it ) + { + const RString &sName = it->first; + if( sName.size() != 6 || sName[0] != '#' || !IsAnInt( sName.substr(1,5) ) ) + continue; + // this is step or offset data. Looks like "#00705" + int iMeasureNo = atoi( sName.substr(1, 3).c_str() ); + int iBMSTrackNo = atoi( sName.substr(4, 2).c_str() ); + int iStepIndex = GetMeasureStartRow( mapMeasureToTimeSig, iMeasureNo, sigAdjustments ); + float fBeatsPerMeasure = GetBeatsPerMeasure( mapMeasureToTimeSig, iMeasureNo, sigAdjustments ); + int iRowsPerMeasure = BeatToNoteRow( fBeatsPerMeasure ); + + RString nData = it->second; + int totalPairs = nData.size() / 2; + for( int i = 0; i < totalPairs; ++i ) + { + RString sPair = nData.substr( i*2, 2 ); + + int iRow = iStepIndex + (i * iRowsPerMeasure) / totalPairs; + float fBeat = NoteRowToBeat( iRow ); + int iVal = 0; + sscanf( sPair, "%x", &iVal ); + + if (sPair == "00") + { + continue; + } + + switch( iBMSTrackNo ) + { + case BMS_TRACK_BPM: + if( iVal > 0 ) + { + out.m_Timing.SetBPMAtBeat( fBeat, (float) iVal ); + LOG->Trace( "Inserting new BPM change at beat %f, BPM %i", fBeat, iVal ); + } + else + { + LOG->UserLog( "Song file", sPath.c_str(), "has an invalid BPM change at beat %f, BPM %d.", + fBeat, iVal ); + } + break; + + case BMS_TRACK_BPM_REF: + { + RString sTagToLookFor = ssprintf( "#bpm%s", sPair.c_str() ); + RString sBPM; + if( GetTagFromMap( mapNameToData, sTagToLookFor, sBPM ) ) + { + float fBPM = StringToFloat( sBPM ); + out.m_Timing.SetBPMAtBeat( fBeat, fBPM ); + } + else + { + LOG->UserLog( "Song file", sPath.c_str(), "has tag \"%s\" which cannot be found.", sTagToLookFor.c_str() ); + } + break; + } + case BMS_TRACK_STOP: + { + if( iVal == 0 ) + { + break; + } + RString sTagToLookFor = ssprintf( "#stop%02x", iVal ); + RString sBeats; + if( GetTagFromMap( mapNameToData, sTagToLookFor, sBeats ) ) + { + // find the BPM at the time of this freeze + float fBPS = out.m_Timing.GetBPMAtBeat(fBeat) / 60.0f; + float fBeats = StringToFloat( sBeats ) / 48.0f; + float fFreezeSecs = fBeats / fBPS; + + StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs ); + out.m_Timing.AddStopSegment( newSeg ); + LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.m_fStopSeconds ); + } + else + { + LOG->UserLog( "Song file", sPath.c_str(), "has tag \"%s\" which cannot be found.", sTagToLookFor.c_str() ); + } + break; + } + } + } + + } + + // Now that we're done reading BPMs, factor out weird time signatures. + SetTimeSigAdjustments( mapMeasureToTimeSig, outSong, sigAdjustments ); + int iHoldStarts[NUM_BMS_TRACKS]; TapNote iHoldHeads[NUM_BMS_TRACKS]; @@ -487,10 +709,9 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo RString sNoteId = sNoteData.substr( i, 2 ); if( sNoteId != "00" ) { - vTapNotes.push_back( TAP_ORIGINAL_TAP ); - map::const_iterator rInt = idToKeySoundIndex.find( sNoteId ); - if( rInt != idToKeySoundIndex.end() ) - vTapNotes.back().iKeysoundIndex = rInt->second; + TapNote tn = TAP_ORIGINAL_TAP; + SearchForKeysound( sPath, sNoteId, mapNameToData, mapIdToKeysoundIndex, mapFilenameToKeysoundIndex, outSong, tn.iKeysoundIndex ); + vTapNotes.push_back( tn ); } else { @@ -781,7 +1002,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo return true; } -static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, MeasureToTimeSig_t &sigAdjustmentsOut, map &idToKeySoundIndexOut ) +static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out ) { RString sData; if( GetTagFromMap(mapNameToData, "#title", sData) ) @@ -792,172 +1013,6 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur GetTagFromMap( mapNameToData, "#backbmp", out.m_sBackgroundFile ); GetTagFromMap( mapNameToData, "#wav", out.m_sMusicFile ); - if( GetTagFromMap(mapNameToData, "#bpm", sData) ) - { - const float fBPM = StringToFloat( sData ); - - if( PREFSMAN->m_bQuirksMode ) - { - BPMSegment newSeg( 0, fBPM ); - out.m_SongTiming.AddBPMSegment( newSeg ); - if( fBPM > 0.0f ) - LOG->Trace( "Inserting new positive BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM ); - else - LOG->Trace( "Inserting new negative BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM ); - } - else - { - if( fBPM > 0.0f ) - { - BPMSegment newSeg( 0, fBPM ); - out.m_SongTiming.AddBPMSegment( newSeg ); - LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM ); - } - else - { - LOG->UserLog( "Song file", out.GetSongDir(), "has an invalid BPM change at beat %f, BPM %f.", - NoteRowToBeat(0), fBPM ); - } - } - } - - NameToData_t::const_iterator it; - for( it = mapNameToData.lower_bound("#wav"); it != mapNameToData.end(); ++it ) - { - const RString &sName = it->first; - - if( sName.size() != 6 || sName.Left(4) != "#wav" ) - continue; - - // this is keysound file name. Looks like "#WAV1A" - RString nData = it->second; - RString sWavID = sName.Right(2); - - // FIXME: garbled song names seem to crash the app. - // this might not be the best place to put this code. - if( !utf8_is_valid(nData) ) - continue; - - /* Due to bugs in some programs, many BMS files have a "WAV" extension - * on files in the BMS for files that actually have some other extension. - * Do a search. Don't do a wildcard search; if sData is "song.wav", - * we might also have "song.png", which we shouldn't match. */ - if( !IsAFile(out.GetSongDir()+nData) ) - { - const char *exts[] = { "oga", "ogg", "wav", "mp3", NULL }; // XXX: stop duplicating these everywhere - for( unsigned i = 0; exts[i] != NULL; ++i ) - { - RString fn = SetExtension( nData, exts[i] ); - if( IsAFile(out.GetSongDir()+fn) ) - { - nData = fn; - break; - } - } - } - if( !IsAFile(out.GetSongDir()+nData) ) - LOG->UserLog( "Song file", out.GetSongDir(), "references key \"%s\" that can't be found", nData.c_str() ); - - sWavID.MakeUpper(); // HACK: undo the MakeLower() - out.m_vsKeysoundFile.push_back( nData ); - idToKeySoundIndexOut[ sWavID ] = out.m_vsKeysoundFile.size()-1; - LOG->Trace( "Inserting keysound index %u '%s'", unsigned(out.m_vsKeysoundFile.size()-1), sWavID.c_str() ); - } - - // Time signature tags affect all other global timing tags, so read them first. - MeasureToTimeSig_t mapMeasureToTimeSig; - ReadTimeSigs( mapNameToData, mapMeasureToTimeSig ); - - for( it = mapNameToData.lower_bound("#00000"); it != mapNameToData.end(); ++it ) - { - const RString &sName = it->first; - if( sName.size() != 6 || sName[0] != '#' || !IsAnInt( sName.substr(1,5) ) ) - continue; - // this is step or offset data. Looks like "#00705" - int iMeasureNo = atoi( sName.substr(1, 3).c_str() ); - int iBMSTrackNo = atoi( sName.substr(4, 2).c_str() ); - int iStepIndex = GetMeasureStartRow( mapMeasureToTimeSig, iMeasureNo, sigAdjustmentsOut ); - float fBeatsPerMeasure = GetBeatsPerMeasure( mapMeasureToTimeSig, iMeasureNo, sigAdjustmentsOut ); - int iRowsPerMeasure = BeatToNoteRow( fBeatsPerMeasure ); - - RString nData = it->second; - int totalPairs = nData.size() / 2; - for( int i = 0; i < totalPairs; ++i ) - { - RString sPair = nData.substr( i*2, 2 ); - - int iRow = iStepIndex + (i * iRowsPerMeasure) / totalPairs; - float fBeat = NoteRowToBeat( iRow ); - int iVal = 0; - sscanf( sPair, "%x", &iVal ); - - if (sPair == "00") - { - continue; - } - - switch( iBMSTrackNo ) - { - case BMS_TRACK_BPM: - if( iVal > 0 ) - { - out.m_SongTiming.SetBPMAtBeat( fBeat, (float) iVal ); - LOG->Trace( "Inserting new BPM change at beat %f, BPM %i", fBeat, iVal ); - } - else - { - LOG->UserLog( "Song file", out.GetSongDir(), "has an invalid BPM change at beat %f, BPM %d.", - fBeat, iVal ); - } - break; - - case BMS_TRACK_BPM_REF: - { - RString sTagToLookFor = ssprintf( "#bpm%s", sPair.c_str() ); - RString sBPM; - if( GetTagFromMap( mapNameToData, sTagToLookFor, sBPM ) ) - { - float fBPM = StringToFloat( sBPM ); - out.m_SongTiming.SetBPMAtBeat( fBeat, fBPM ); - } - else - { - LOG->UserLog( "Song file", out.GetSongDir(), "has tag \"%s\" which cannot be found.", sTagToLookFor.c_str() ); - } - break; - } - case BMS_TRACK_STOP: - { - if( iVal == 0 ) - { - break; - } - RString sTagToLookFor = ssprintf( "#stop%02x", iVal ); - RString sBeats; - if( GetTagFromMap( mapNameToData, sTagToLookFor, sBeats ) ) - { - // find the BPM at the time of this freeze - float fBPS = out.m_SongTiming.GetBPMAtBeat(fBeat) / 60.0f; - float fBeats = StringToFloat( sBeats ) / 48.0f; - float fFreezeSecs = fBeats / fBPS; - - StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs ); - out.m_SongTiming.AddStopSegment( newSeg ); - LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.m_fStopSeconds ); - } - else - { - LOG->UserLog( "Song file", out.GetSongDir(), "has tag \"%s\" which cannot be found.", sTagToLookFor.c_str() ); - } - break; - } - } - } - - } - - // Now that we're done reading BPMs, factor out weird time signatures. - SetTimeSigAdjustments( mapMeasureToTimeSig, out, sigAdjustmentsOut ); } static void SlideDuplicateDifficulties( Song &p ) @@ -1100,9 +1155,7 @@ bool BMSLoader::LoadFromDir( const RString &sDir, Song &out ) if( apSteps[i]->GetDifficulty() == Difficulty_Medium ) iMainDataIndex = i; - MeasureToTimeSig_t sigAdjustments; - map idToKeysoundIndex; - ReadGlobalTags( aBMSData[iMainDataIndex], out, sigAdjustments, idToKeysoundIndex ); + ReadGlobalTags( aBMSData[iMainDataIndex], out ); // The brackets before the difficulty are in common substring, so remove them if it's found. if( commonSubstring.size() > 2 && commonSubstring[commonSubstring.size() - 2] == ' ' ) @@ -1124,10 +1177,11 @@ bool BMSLoader::LoadFromDir( const RString &sDir, Song &out ) // Now that we've parsed the keysound data, load the Steps from the rest // of the .bms files. + map mapFilenameToKeysoundIndex; for( unsigned i=0; iGetPositionSeconds( NULL, &tm ); - GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_SongTiming, tm ); + GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_SongTiming, tm, true ); } if( m_EditState == STATE_RECORDING ) @@ -2388,7 +2388,7 @@ void ScreenEdit::TransitionEditState( EditState em ) /* Give a 1 second lead-in. If we're loading Player, this must be done first. */ float fSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1; - GAMESTATE->UpdateSongPosition( fSeconds, m_pSteps->m_Timing ); + GAMESTATE->UpdateSongPosition( fSeconds, m_pSteps->m_Timing, RageZeroTimer, true ); GAMESTATE->m_bGameplayLeadIn.Set( false ); diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index 041613e914..ffea34a274 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -1423,7 +1423,7 @@ void ScreenGameplay::UpdateSongPosition( float fDeltaTime ) RageTimer tm; const float fSeconds = m_pSoundMusic->GetPositionSeconds( NULL, &tm ); const float fAdjust = SOUND->GetFrameTimingAdjustment( fDeltaTime ); - GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, GAMESTATE->m_pCurSong->m_SongTiming, tm+fAdjust ); + GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, GAMESTATE->m_pCurSong->m_SongTiming, tm+fAdjust, true ); } void ScreenGameplay::BeginScreen() diff --git a/src/Steps.cpp b/src/Steps.cpp index 3c0cf7cb57..5c2c91f063 100644 --- a/src/Steps.cpp +++ b/src/Steps.cpp @@ -339,6 +339,7 @@ void Steps::AutogenFrom( const Steps *parent_, StepsType ntTo ) { parent = parent_; m_StepsType = ntTo; + m_Timing = parent->m_Timing; } void Steps::CopyFrom( Steps* pSource, StepsType ntTo, float fMusicLengthSeconds ) // pSource does not have to be of the same StepsType @@ -348,6 +349,7 @@ void Steps::CopyFrom( Steps* pSource, StepsType ntTo, float fMusicLengthSeconds pSource->GetNoteData( noteData ); noteData.SetNumTracks( GAMEMAN->GetStepsTypeInfo(ntTo).iNumTracks ); parent = NULL; + m_Timing = pSource->m_Timing; this->SetNoteData( noteData ); this->SetDescription( pSource->GetDescription() ); this->SetDifficulty( pSource->GetDifficulty() ); From 6847ef9087dcfe5e10d35030251d4072dc2d67b4 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Thu, 12 May 2011 17:11:54 +0700 Subject: [PATCH 041/197] [splittiming] Now that we have split timing, Compress/Expand in ScreenEdit no longer need to affect any other notes anymore. --- src/ScreenEdit.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 5d1eb1d933..217e515554 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3507,6 +3507,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns m_pSteps->m_Timing.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); // scale all other steps. + /* const vector sIter = m_pSong->GetAllSteps(); RString sTempStyle, sTempDiff; for( unsigned i = 0; i < sIter.size(); i++ ) @@ -3525,7 +3526,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns NoteDataUtil::ScaleRegion( ndTemp, fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); sIter[i]->SetNoteData( ndTemp ); } - + */ m_NoteFieldEdit.m_iEndMarker = iNewEndIndex; } From a09e3d51c2e2ad5502ce4df917e54d0832973556 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Thu, 12 May 2011 19:07:41 +0700 Subject: [PATCH 042/197] [splittiming] - calculate m_fFirstBeat and m_fLastBeat correctly - fix a crash caused by calculating by tidying the timing first. - make editor go back to right place after playing (the editor should be fairly working now!) --- src/ScreenEdit.cpp | 4 ++-- src/Song.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 217e515554..8b9e03cb0d 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2372,11 +2372,11 @@ void ScreenEdit::TransitionEditState( EditState em ) GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_fBeatToReturnTo; // Make sure we're snapped. - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = Quantize( GAMESTATE->m_Position.m_fSongBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = Quantize( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); /* Playing and recording have lead-ins, which may start before beat 0; * make sure we don't stay there if we escaped out early. */ - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = max( GAMESTATE->m_Position.m_fSongBeat, 0 ); + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = max( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, 0 ); break; diff --git a/src/Song.cpp b/src/Song.cpp index dcb39b1eec..8bf3c72fd0 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -472,6 +472,13 @@ void Song::TidyUpData() m_fMusicLengthSeconds = 0; } + m_SongTiming.TidyUpData(); + + FOREACH( Steps *, m_vpSteps, s ) + { + (*s)->m_Timing.TidyUpData(); + } + /* Generate these before we autogen notes, so the new notes can inherit * their source's values. */ ReCalculateRadarValuesAndLastBeat(); @@ -488,13 +495,6 @@ void Song::TidyUpData() m_sArtist = "Unknown artist"; TranslateTitles(); - m_SongTiming.TidyUpData(); - - FOREACH( Steps *, m_vpSteps, s ) - { - (*s)->m_Timing.TidyUpData(); - } - if( m_fMusicSampleStartSeconds == -1 || m_fMusicSampleStartSeconds == 0 || m_fMusicSampleStartSeconds+m_fMusicSampleLengthSeconds > this->m_fMusicLengthSeconds ) @@ -833,8 +833,8 @@ void Song::ReCalculateRadarValuesAndLastBeat() if( tempNoteData.GetLastRow() == 0 ) continue; - fFirstBeat = min( fFirstBeat, tempNoteData.GetFirstBeat() ); - fLastBeat = max( fLastBeat, tempNoteData.GetLastBeat() ); + fFirstBeat = min( fFirstBeat, m_SongTiming.GetBeatFromElapsedTime(pSteps->m_Timing.GetElapsedTimeFromBeat(tempNoteData.GetFirstBeat())) ); + fLastBeat = max( fLastBeat, m_SongTiming.GetBeatFromElapsedTime(pSteps->m_Timing.GetElapsedTimeFromBeat(tempNoteData.GetLastBeat())) ); } m_fFirstBeat = fFirstBeat; From 83c5b676476dc97409dc2b03498653aa92337472 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Thu, 12 May 2011 23:34:57 +0700 Subject: [PATCH 043/197] [splittiming] - #include "global.h" in SongPosition.cpp to make it build in MSVC. - Add SongPosition.cpp to VC2008 project. --- src/SongPosition.cpp | 1 + src/StepMania-net2008.vcproj | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp index 048c93708c..79e925658f 100644 --- a/src/SongPosition.cpp +++ b/src/SongPosition.cpp @@ -1,3 +1,4 @@ +#include "global.h" #include "SongPosition.h" static Preference g_fVisualDelaySeconds( "VisualDelaySeconds", 0.0f ); diff --git a/src/StepMania-net2008.vcproj b/src/StepMania-net2008.vcproj index fdd1456e75..a038f0dc1d 100644 --- a/src/StepMania-net2008.vcproj +++ b/src/StepMania-net2008.vcproj @@ -1444,6 +1444,14 @@ RelativePath="SongOptions.h" > + + + + From f9da743e59104adf14a8aed452758d90ed208811 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 20:50:38 -0400 Subject: [PATCH 044/197] [splittiming] Fix editor bug on create & no save. Hmm...is this bug also in default? --- src/NoteField.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 5f76e23d3e..06f73b18d1 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -739,10 +739,12 @@ void NoteField::DrawPrimitives() cur->m_ReceptorArrowRow.Draw(); } + Steps *stepChecking = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]; + // Draw beat bars - if( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) + if( ( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) && stepChecking != NULL ) { - const vector &vTimeSignatureSegments = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing.m_vTimeSignatureSegments; + const vector &vTimeSignatureSegments = stepChecking->m_Timing.m_vTimeSignatureSegments; int iMeasureIndex = 0; FOREACH_CONST( TimeSignatureSegment, vTimeSignatureSegments, iter ) { @@ -781,11 +783,11 @@ void NoteField::DrawPrimitives() } } - if( GAMESTATE->IsEditing() ) + if( GAMESTATE->IsEditing() && stepChecking != NULL ) { ASSERT(GAMESTATE->m_pCurSong); - const TimingData &timing = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing; + const TimingData &timing = stepChecking->m_Timing; // BPM text FOREACH_CONST( BPMSegment, timing.m_BPMSegments, seg ) From 1ee92c65e98f11b0fa31bf5b769e670deadf2e2e Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 20:55:45 -0400 Subject: [PATCH 045/197] [splittiming] Allow F1^H4 dedicated Timing Menu. --- src/ScreenEdit.cpp | 39 ++++++++++++++++++++++++++------------- src/ScreenEdit.h | 4 ++++ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 8b9e03cb0d..9427fb8ee6 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -194,6 +194,9 @@ void ScreenEdit::InitEditMappings() return; case EditMode_Full: + // F4 = Show timing menu + m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_TIMING_MENU][0] = DeviceInput(DEVICE_KEYBOARD, KEY_F4); + /* Don't allow F5/F6 in home mode. It breaks the "delay creation until first save" logic. */ m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_PREV_STEPS][0] = DeviceInput(DEVICE_KEYBOARD, KEY_F5); m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_NEXT_STEPS][0] = DeviceInput(DEVICE_KEYBOARD, KEY_F6); @@ -1522,6 +1525,11 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_OPEN_INPUT_HELP: DoHelp(); break; + case EDIT_BUTTON_OPEN_TIMING_MENU: + { + DisplayTimingMenu(); + break; + } case EDIT_BUTTON_OPEN_NEXT_STEPS: case EDIT_BUTTON_OPEN_PREV_STEPS: { @@ -3056,6 +3064,23 @@ static void ChangeMaxBPM( const RString &sNew ) GAMESTATE->m_pCurSong->m_fSpecifiedBPMMax = StringToFloat( sNew ); } +void ScreenEdit::DisplayTimingMenu() +{ + TimingData pTime = m_pSteps->m_Timing; + const float fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; + g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[time_signature_numerator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[time_signature_denominator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[label].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); + g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); + + EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); +} + // End helper functions static LocalizedString REVERT_LAST_SAVE ( "ScreenEdit", "Do you want to revert to your last save?" ); @@ -3259,19 +3284,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns break; case edit_timing_data: { - TimingData pTime = m_pSteps->m_Timing; - const float fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; - g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; - g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[time_signature_numerator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[time_signature_denominator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[label].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); - g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); - - EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); + DisplayTimingMenu(); } break; diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index ea10ca22a2..58656f419a 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -86,6 +86,7 @@ enum EditButton EDIT_BUTTON_SNAP_PREV, EDIT_BUTTON_OPEN_EDIT_MENU, + EDIT_BUTTON_OPEN_TIMING_MENU, EDIT_BUTTON_OPEN_AREA_MENU, EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU, EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU, @@ -231,6 +232,9 @@ protected: float GetMaximumBeatForMoving() const; // don't allow Down key to go past this beat. void DoHelp(); + + /** @brief Display the TimingData menu for editing song and step timing. */ + void DisplayTimingMenu(); EditState m_EditState; From 5bcc094504fa21d61a9337bb17128ad65f25afb5 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 21:23:48 -0400 Subject: [PATCH 046/197] [splittiming] Let Steps have their own offset. There are pros and cons...call this one instinct. --- src/ScreenEdit.cpp | 21 +++++++++++---------- src/ScreenEdit.h | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 9427fb8ee6..2186924579 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -551,7 +551,6 @@ static MenuDef g_SongInformation( MenuRowDef( ScreenEdit::main_title_transliteration, "Main title transliteration", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::sub_title_transliteration, "Sub title transliteration", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::artist_transliteration, "Artist transliteration", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::beat_0_offset, "Beat 0 Offset", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::last_beat_hint, "Last beat hint", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::preview_start, "Preview Start", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::preview_length, "Preview Length", true, EditMode_Full, true, true, 0, NULL ), @@ -562,7 +561,8 @@ static MenuDef g_SongInformation( static MenuDef g_TimingDataInformation( "ScreenMiniMenuTimingDataInformation", - MenuRowDef( ScreenEdit::bpm, "Edit BPM change", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::beat_0_offset, "Beat 0 Offset", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::bpm, "Edit BPM change", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::stop, "Edit stop", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::delay, "Edit delay", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::time_signature_numerator, "Edit time signature (top)", true, EditMode_Full, true, true, 0, NULL ), @@ -3068,6 +3068,7 @@ void ScreenEdit::DisplayTimingMenu() { TimingData pTime = m_pSteps->m_Timing; const float fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pTime.m_fBeat0OffsetInSeconds) ); g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); @@ -3271,7 +3272,6 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns g_SongInformation.rows[main_title_transliteration].SetOneUnthemedChoice( pSong->m_sMainTitleTranslit ); g_SongInformation.rows[sub_title_transliteration].SetOneUnthemedChoice( pSong->m_sSubTitleTranslit ); g_SongInformation.rows[artist_transliteration].SetOneUnthemedChoice( pSong->m_sArtistTranslit ); - g_SongInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_SongTiming.m_fBeat0OffsetInSeconds) ); g_SongInformation.rows[last_beat_hint].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fSpecifiedLastBeat) ); g_SongInformation.rows[preview_start].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fMusicSampleStartSeconds) ); g_SongInformation.rows[preview_length].SetOneUnthemedChoice( ssprintf("%.5f", pSong->m_fMusicSampleLengthSeconds) ); @@ -3679,7 +3679,6 @@ static LocalizedString ENTER_CREDIT ("ScreenEdit","Enter a new credit."); static LocalizedString ENTER_MAIN_TITLE_TRANSLIT ("ScreenEdit","Enter a new main title transliteration."); static LocalizedString ENTER_SUB_TITLE_TRANSLIT ("ScreenEdit","Enter a new sub title transliteration."); static LocalizedString ENTER_ARTIST_TRANSLIT ("ScreenEdit","Enter a new artist transliteration."); -static LocalizedString ENTER_BEAT_0_OFFSET ("ScreenEdit","Enter the offset for the song."); static LocalizedString ENTER_LAST_BEAT_HINT ("ScreenEdit","Enter a new last beat hint."); static LocalizedString ENTER_PREVIEW_START ("ScreenEdit","Enter a new preview start."); static LocalizedString ENTER_PREVIEW_LENGTH ("ScreenEdit","Enter a new preview length."); @@ -3716,11 +3715,6 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec case artist_transliteration: ScreenTextEntry::TextEntry( SM_None, ENTER_ARTIST_TRANSLIT, pSong->m_sArtistTranslit, 100, NULL, ChangeArtistTranslit, NULL ); break; - case beat_0_offset: - ScreenTextEntry::TextEntry( SM_None, ENTER_BEAT_0_OFFSET, - ssprintf("%.5f", m_pSteps->m_Timing.m_fBeat0OffsetInSeconds), 20, - ScreenTextEntry::FloatValidate, ChangeBeat0Offset, NULL ); - break; case last_beat_hint: ScreenTextEntry::TextEntry( SM_None, ENTER_LAST_BEAT_HINT, ssprintf("%.5f", pSong->m_fSpecifiedLastBeat), 20, @@ -3749,6 +3743,8 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec }; } + +static LocalizedString ENTER_BEAT_0_OFFSET ("ScreenEdit","Enter the offset for the song."); static LocalizedString ENTER_BPM_VALUE ( "ScreenEdit", "Enter a new BPM value." ); static LocalizedString ENTER_STOP_VALUE ( "ScreenEdit", "Enter a new Stop value." ); static LocalizedString ENTER_DELAY_VALUE ( "ScreenEdit", "Enter a new Delay value." ); @@ -3763,7 +3759,12 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice switch( c ) { DEFAULT_FAIL( c ); - case bpm: + case beat_0_offset: + ScreenTextEntry::TextEntry( SM_None, ENTER_BEAT_0_OFFSET, + ssprintf("%.5f", m_pSteps->m_Timing.m_fBeat0OffsetInSeconds), 20, + ScreenTextEntry::FloatValidate, ChangeBeat0Offset, NULL ); + break; + case bpm: ScreenTextEntry::TextEntry( SM_BackFromBPMChange, ENTER_BPM_VALUE, diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 58656f419a..a24053645f 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -463,7 +463,6 @@ public: main_title_transliteration, sub_title_transliteration, artist_transliteration, - beat_0_offset, last_beat_hint, preview_start, preview_length, @@ -476,6 +475,7 @@ public: enum TimingDataInformationChoice { + beat_0_offset, bpm, stop, delay, From 7c638451cd271862f70626692b8dd67bad594f7a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 21:31:33 -0400 Subject: [PATCH 047/197] [splittiming] Write out the Steps' #OFFSET. --- src/NotesWriterSSC.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index d24f7f5e9f..445aa9ee5b 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -132,7 +132,6 @@ static void GetTimingTags( vector &lines, TimingData timing ) FOREACH_CONST( LabelSegment, timing.m_LabelSegments, ls ) w.Write( ls->m_iStartRow, ls->m_sLabel.c_str() ); w.Finish(); - } static void WriteTimingTags( RageFile &f, const TimingData &timing ) @@ -147,7 +146,7 @@ static void WriteTimingTags( RageFile &f, const TimingData &timing ) } /** - * @brief Write out the common tags for .SM files. + * @brief Write out the common tags for .SSC files. * @param f the file in question. * @param out the Song in question. */ static void WriteGlobalTags( RageFile &f, const Song &out ) @@ -299,6 +298,9 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa GetTimingTags( lines, in.m_Timing ); + lines.push_back( "#ATTACKS:;" ); // not sure of how to handle this yet. + lines.push_back( ssprintf( "#OFFSET:%.6f;", in.m_Timing.m_fBeat0OffsetInSeconds ) ); + RString sNoteData; in.GetSMNoteData( sNoteData ); From 4edf884b1ae1fb7d7035ddfd205d6fc259232b5f Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 21:41:20 -0400 Subject: [PATCH 048/197] [splittiming] Cleanup and comment. --- src/ScreenEdit.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 2186924579..221d527996 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3036,6 +3036,9 @@ static void ChangeArtistTranslit( const RString &sNew ) static void ChangeBeat0Offset( const RString &sNew ) { + /* TODO: Use a switch/boolean to determine which to write to. + * If it's a new chart (have to find a way to determine that), + * write to both. */ GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); } @@ -3744,7 +3747,7 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec } -static LocalizedString ENTER_BEAT_0_OFFSET ("ScreenEdit","Enter the offset for the song."); +static LocalizedString ENTER_BEAT_0_OFFSET ( "ScreenEdit", "Enter the offset for the song."); static LocalizedString ENTER_BPM_VALUE ( "ScreenEdit", "Enter a new BPM value." ); static LocalizedString ENTER_STOP_VALUE ( "ScreenEdit", "Enter a new Stop value." ); static LocalizedString ENTER_DELAY_VALUE ( "ScreenEdit", "Enter a new Delay value." ); From 32afac99918b2a4c2e925f2d4fe1739487079016 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 22:07:00 -0400 Subject: [PATCH 049/197] [splittiming] Fit more text/directions in. Someone more skilled in metrics can try to make the text stand out. --- Themes/_fallback/Languages/en.ini | 2 +- Themes/_fallback/metrics.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index d0492d5a94..b4f91ef808 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1246,7 +1246,7 @@ Enter a new min BPM.=Enter the minimum displayed BPM. Enter a new max BPM.=Enter the maximum displayed BPM. More than %d notes per measure is not allowed. This change has been reverted.=More than %d notes per measure is not allowed. This change has been reverted. No backgrounds available=No backgrounds available -EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nEnter:\n Area Menu\nEscape:\n Main Menu\nF1:\n Show help\n +EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nN and M keys:\n swap tap notes\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nEnter:\n Area Menu\nEscape:\n Main Menu\nF4:\n Timing Menu\nF1:\n Show help\n PlayRecordHelpText=Press START to end Save successful.=Save successful. Saved as SM and DWI.=Saved as SM and DWI. diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 668d96827b..ecac994d7e 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -3598,7 +3598,7 @@ TimerSeconds=-1 EditModifiers="no reverse" EditHelpX=SCREEN_LEFT+4 EditHelpY=SCREEN_TOP+16 -EditHelpOnCommand=halign,0;valign,0;zoom,0.675;shadowlength,1 +EditHelpOnCommand=halign,0;valign,0;zoom,0.5;shadowlength,1 InfoX=SCREEN_RIGHT-128 InfoY=SCREEN_TOP+16 InfoOnCommand=halign,0;valign,0;zoom,0.5;shadowlength,1 From 29e0bd3d2f668eece62a856d5e8ba3f7f2eb588b Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 22:24:25 -0400 Subject: [PATCH 050/197] [splittiming] Prepare timing bool switch. This is needed in GAMESTATE due to it also going to be called in NoteField. --- src/GameState.cpp | 3 ++- src/GameState.h | 41 +++++++++++++++++++++++++++++++++++------ src/ScreenEdit.cpp | 5 +++++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index 242ccaee70..4a521e1ebb 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -127,7 +127,8 @@ GameState::GameState() : m_pEditSourceSteps( Message_EditSourceStepsChanged ), m_stEditSource( Message_EditSourceStepsTypeChanged ), m_iEditCourseEntryIndex( Message_EditCourseEntryIndexChanged ), - m_sEditLocalProfileID( Message_EditLocalProfileIDChanged ) + m_sEditLocalProfileID( Message_EditLocalProfileIDChanged ), + m_bIsEditorStepTiming( false ) { g_pImpl = new GameStateImpl; diff --git a/src/GameState.h b/src/GameState.h index 000219a343..592b613dfe 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -44,7 +44,8 @@ public: void ResetPlayer( PlayerNumber pn ); void ApplyCmdline(); // called by Reset void ApplyGameCommand( const RString &sCommand, PlayerNumber pn=PLAYER_INVALID ); - void BeginGame(); // called when first player joins + /** @brief Start the game when the first player joins in. */ + void BeginGame(); void JoinPlayer( PlayerNumber pn ); void UnjoinPlayer( PlayerNumber pn ); bool JoinInput( PlayerNumber pn ); @@ -56,13 +57,25 @@ public: bool HaveProfileToSave(); void SaveLocalData(); void LoadCurrentSettingsFromProfile( PlayerNumber pn ); - void SaveCurrentSettingsToProfile( PlayerNumber pn ); // called at the beginning of each stage + /** + * @brief Save the specified player's settings to his/her profile. + * + * This is called at the beginning of each stage. + * @param pn the PlayerNumber to save the stats to. */ + void SaveCurrentSettingsToProfile( PlayerNumber pn ); Song* GetDefaultSong() const; void Update( float fDelta ); // Main state info - void SetCurGame( const Game *pGame ); // Call this instead of m_pCurGame.Set to make sure PREFSMAN->m_sCurrentGame stays in sync + + /** + * @brief State what the current game is. + * + * Call this instead of m_pCurGame.Set to make sure that + * PREFSMAN->m_sCurrentGame stays in sync. + * @param pGame the game to start using. */ + void SetCurGame( const Game *pGame ); BroadcastOnChangePtr m_pCurGame; BroadcastOnChangePtr m_pCurStyle; /** @brief Determine which side is joined. @@ -130,6 +143,9 @@ public: bool IsCourseMode() const; bool IsBattleMode() const; // not Rave + /** + * @brief Do we show the W1 timing judgment? + * @return true if we do, or false otherwise. */ bool ShowW1() const; BroadcastOnChange m_sPreferredSongGroup; // GROUP_ALL denotes no preferred group @@ -142,7 +158,11 @@ public: SortOrder m_PreferredSortOrder; // used by MusicWheel EditMode m_EditMode; bool IsEditing() const { return m_EditMode != EditMode_Invalid; } - bool m_bDemonstrationOrJukebox; // ScreenGameplay does special stuff when this is true + /** + * @brief Are we in the demonstration or jukebox mode? + * + * ScreenGameplay often does special things when this is set to true. */ + bool m_bDemonstrationOrJukebox; bool m_bJukeboxUsesModifiers; int m_iNumStagesOfThisSong; /** @@ -240,8 +260,11 @@ public: // Options stuff ModsGroup m_SongOptions; - // True if the current mode has changed the default NoteSkin, such as Edit/Sync Songs does. - // Note: any mode that wants to use it must set it + /** + * @brief Did the current game mode change the default Noteskin? + * + * This is true if it has: see Edit/Sync Songs for a common example. + * Note: any mode that wants to use this must set it explicitly. */ bool m_bDidModeChangeNoteSkin; void GetDefaultPlayerOptions( PlayerOptions &po ); @@ -308,6 +331,12 @@ public: Premium GetPremium() const; // Edit stuff + + /** + * @brief Is the editor making changes to Song timing or Steps timing? + * + * Different options are available depending on this setting. */ + bool m_bIsEditorStepTiming; BroadcastOnChange m_stEdit; BroadcastOnChange m_cdEdit; BroadcastOnChangePtr m_pEditSourceSteps; diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 221d527996..43f8b94d46 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -692,6 +692,8 @@ REGISTER_SCREEN_CLASS( ScreenEdit ); void ScreenEdit::Init() { m_pSoundMusic = NULL; + + GAMESTATE->m_bIsEditorStepTiming = true; SubscribeToMessage( "Judgment" ); @@ -849,6 +851,9 @@ ScreenEdit::~ScreenEdit() LOG->Trace( "ScreenEdit::~ScreenEdit()" ); m_pSoundMusic->StopPlaying(); + + // Reset the GameState variable in case it's needed elsewhere. + GAMESTATE->m_bIsEditorStepTiming = false; } void ScreenEdit::BeginScreen() From 3a348123ca52c4b682fcfc5f48330624c99af624 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 22:34:16 -0400 Subject: [PATCH 051/197] [splittiming] Draw certain text based on switch. Note: the diff for this hates the indentation. --- src/NoteField.cpp | 145 ++++++++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 68 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 06f73b18d1..66cdf2a34b 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -833,25 +833,31 @@ void NoteField::DrawPrimitives() } } - // Tickcount text - FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, seg ) + if( GAMESTATE->m_bIsEditorStepTiming ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + // Tickcount text + FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, seg ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); - if( IS_ON_SCREEN(fBeat) ) - DrawTickcountText( fBeat, seg->m_iTicks ); + if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + { + float fBeat = NoteRowToBeat(seg->m_iStartRow); + if( IS_ON_SCREEN(fBeat) ) + DrawTickcountText( fBeat, seg->m_iTicks ); + } } } - // Combo text - FOREACH_CONST( ComboSegment, timing.m_ComboSegments, seg ) + if( GAMESTATE->m_bIsEditorStepTiming ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + // Combo text + FOREACH_CONST( ComboSegment, timing.m_ComboSegments, seg ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); - if( IS_ON_SCREEN(fBeat) ) - DrawComboText( fBeat, seg->m_iCombo ); + if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + { + float fBeat = NoteRowToBeat(seg->m_iStartRow); + if( IS_ON_SCREEN(fBeat) ) + DrawComboText( fBeat, seg->m_iCombo ); + } } } @@ -886,71 +892,74 @@ void NoteField::DrawPrimitives() } } } - - // BGChange text - switch( GAMESTATE->m_EditMode ) + + if( !GAMESTATE->m_bIsEditorStepTiming ) { - case EditMode_Home: - case EditMode_CourseMods: - case EditMode_Practice: - break; - case EditMode_Full: - { - vector::iterator iter[NUM_BackgroundLayer]; - FOREACH_BackgroundLayer( i ) - iter[i] = GAMESTATE->m_pCurSong->GetBackgroundChanges(i).begin(); - - while( 1 ) + // BGChange text + switch( GAMESTATE->m_EditMode ) + { + case EditMode_Home: + case EditMode_CourseMods: + case EditMode_Practice: + break; + case EditMode_Full: { - float fLowestBeat = FLT_MAX; - vector viLowestIndex; - + vector::iterator iter[NUM_BackgroundLayer]; FOREACH_BackgroundLayer( i ) + iter[i] = GAMESTATE->m_pCurSong->GetBackgroundChanges(i).begin(); + + while( 1 ) { - if( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() ) - continue; - - float fBeat = iter[i]->m_fStartBeat; - if( fBeat < fLowestBeat ) - { - fLowestBeat = fBeat; - viLowestIndex.clear(); - viLowestIndex.push_back( i ); - } - else if( fBeat == fLowestBeat ) - { - viLowestIndex.push_back( i ); - } - } - - if( viLowestIndex.empty() ) - { + float fLowestBeat = FLT_MAX; + vector viLowestIndex; + FOREACH_BackgroundLayer( i ) - ASSERT( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() ); - break; - } - - if( IS_ON_SCREEN(fLowestBeat) ) - { - vector vsBGChanges; - FOREACH_CONST( BackgroundLayer, viLowestIndex, i ) { - ASSERT( iter[*i] != GAMESTATE->m_pCurSong->GetBackgroundChanges(*i).end() ); - const BackgroundChange& change = *iter[*i]; - RString s = change.GetTextDescription(); - if( *i!=0 ) - s = ssprintf("%d: ",*i) + s; - vsBGChanges.push_back( s ); + if( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() ) + continue; + + float fBeat = iter[i]->m_fStartBeat; + if( fBeat < fLowestBeat ) + { + fLowestBeat = fBeat; + viLowestIndex.clear(); + viLowestIndex.push_back( i ); + } + else if( fBeat == fLowestBeat ) + { + viLowestIndex.push_back( i ); + } } - DrawBGChangeText( fLowestBeat, join("\n",vsBGChanges) ); + + if( viLowestIndex.empty() ) + { + FOREACH_BackgroundLayer( i ) + ASSERT( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() ); + break; + } + + if( IS_ON_SCREEN(fLowestBeat) ) + { + vector vsBGChanges; + FOREACH_CONST( BackgroundLayer, viLowestIndex, i ) + { + ASSERT( iter[*i] != GAMESTATE->m_pCurSong->GetBackgroundChanges(*i).end() ); + const BackgroundChange& change = *iter[*i]; + RString s = change.GetTextDescription(); + if( *i!=0 ) + s = ssprintf("%d: ",*i) + s; + vsBGChanges.push_back( s ); + } + DrawBGChangeText( fLowestBeat, join("\n",vsBGChanges) ); + } + FOREACH_CONST( BackgroundLayer, viLowestIndex, i ) + iter[*i]++; } - FOREACH_CONST( BackgroundLayer, viLowestIndex, i ) - iter[*i]++; } - } - break; - default: - ASSERT(0); + break; + default: + ASSERT(0); + } } // Draw marker bars From 59fe8c02c069564fb7e92b46ba0d9edbfec4e391 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 22:39:10 -0400 Subject: [PATCH 052/197] [splittiming] Organize Beat 0 Offset. --- src/ScreenEdit.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 43f8b94d46..fcd2910e30 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1139,7 +1139,11 @@ void ScreenEdit::UpdateTextInfo() case EditMode_Home: break; case EditMode_Full: - sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), m_pSteps->m_Timing.m_fBeat0OffsetInSeconds ); + sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), + BEAT_0_OFFSET.GetValue().c_str(), + ( GAMESTATE->m_bIsEditorStepTiming ? + m_pSteps->m_Timing.m_fBeat0OffsetInSeconds : + m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds ) ); sText += ssprintf( PREVIEW_START_FORMAT.GetValue(), PREVIEW_START.GetValue().c_str(), m_pSong->m_fMusicSampleStartSeconds ); sText += ssprintf( PREVIEW_LENGTH_FORMAT.GetValue(), PREVIEW_LENGTH.GetValue().c_str(), m_pSong->m_fMusicSampleLengthSeconds ); break; @@ -3041,10 +3045,12 @@ static void ChangeArtistTranslit( const RString &sNew ) static void ChangeBeat0Offset( const RString &sNew ) { - /* TODO: Use a switch/boolean to determine which to write to. - * If it's a new chart (have to find a way to determine that), - * write to both. */ - GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); + TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming; + if( GAMESTATE->m_bIsEditorStepTiming ) + { + timing = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing; + } + timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); } static void ChangeLastBeatHint( const RString &sNew ) From d74294d4b7811da65e7f163b2b219607efa0a052 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 22:50:39 -0400 Subject: [PATCH 053/197] [splittiming] DisplayTimingMenu() The bottom part may be reverted if this backfires horribly. --- src/ScreenEdit.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index fcd2910e30..abf1260948 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3080,16 +3080,29 @@ static void ChangeMaxBPM( const RString &sNew ) void ScreenEdit::DisplayTimingMenu() { - TimingData pTime = m_pSteps->m_Timing; - const float fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + float fBeat; + TimingData &pTime = m_pSteps->m_Timing; + if( !GAMESTATE->m_bIsEditorStepTiming ) + { + pTime = m_pSong->m_SongTiming; + fBeat = GAMESTATE->m_Position.m_fSongBeat; + } + else + { + fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + } + g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pTime.m_fBeat0OffsetInSeconds) ); g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[time_signature_numerator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[time_signature_denominator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); + if( GAMESTATE->m_bIsEditorStepTiming ) + { + g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); + } g_TimingDataInformation.rows[label].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); From 7361e3fe04ed0989908ff7e39fd7ae3af243c27e Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 23:01:19 -0400 Subject: [PATCH 054/197] [splittiming] GetAppropriateTiming() function. I admit it: I got tired of typing the same if statement. --- src/ScreenEdit.cpp | 34 ++++++++++++++++++++-------------- src/ScreenEdit.h | 5 +++++ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index abf1260948..0113f41682 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1141,9 +1141,7 @@ void ScreenEdit::UpdateTextInfo() case EditMode_Full: sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), - ( GAMESTATE->m_bIsEditorStepTiming ? - m_pSteps->m_Timing.m_fBeat0OffsetInSeconds : - m_pSong->m_SongTiming.m_fBeat0OffsetInSeconds ) ); + GetAppropriateTiming().m_fBeat0OffsetInSeconds ); sText += ssprintf( PREVIEW_START_FORMAT.GetValue(), PREVIEW_START.GetValue().c_str(), m_pSong->m_fMusicSampleStartSeconds ); sText += ssprintf( PREVIEW_LENGTH_FORMAT.GetValue(), PREVIEW_LENGTH.GetValue().c_str(), m_pSong->m_fMusicSampleLengthSeconds ); break; @@ -2648,21 +2646,21 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { float fBPM = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fBPM > 0 ) - m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fBPM ); + GetAppropriateTiming().SetBPMAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fBPM ); SetDirty( true ); } else if( SM == SM_BackFromStopChange ) { float fStop = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fStop >= 0 ) - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fStop ); + GetAppropriateTiming().SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fStop ); SetDirty( true ); } else if( SM == SM_BackFromDelayChange ) { float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fDelay >= 0 ) - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fDelay, true ); + GetAppropriateTiming().SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fDelay, true ); SetDirty( true ); } else if( SM == SM_BackFromTimeSignatureNumeratorChange ) @@ -2670,7 +2668,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iNum = StringToInt( ScreenTextEntry::s_sLastAnswer ); if( iNum > 0 ) { - m_pSteps->m_Timing.SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iNum ); + GetAppropriateTiming().SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iNum ); } SetDirty( true ); } @@ -2679,7 +2677,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iDen = StringToInt( ScreenTextEntry::s_sLastAnswer ); if( iDen > 0) { - m_pSteps->m_Timing.SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iDen ); + GetAppropriateTiming().SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iDen ); } SetDirty( true ); } @@ -2688,7 +2686,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iTick = StringToInt( ScreenTextEntry::s_sLastAnswer ); if ( iTick >= 0 && iTick <= ROWS_PER_BEAT ) { - m_pSteps->m_Timing.SetTickcountAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iTick ); + GetAppropriateTiming().SetTickcountAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iTick ); } SetDirty( true ); } @@ -2697,7 +2695,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iCombo = StringToInt( ScreenTextEntry::s_sLastAnswer ); if ( iCombo >= 0 ) { - m_pSteps->m_Timing.SetComboAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iCombo ); + GetAppropriateTiming().SetComboAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iCombo ); } SetDirty( true ); } @@ -2708,14 +2706,14 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { sLabel.Replace("=", "_"); sLabel.Replace(",", "_"); - m_pSteps->m_Timing.SetLabelAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, sLabel ); + GetAppropriateTiming().SetLabelAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, sLabel ); SetDirty( true ); } } else if ( SM == SM_BackFromWarpChange ) { float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer ); - m_pSteps->m_Timing.SetWarpAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fWarp ); + GetAppropriateTiming().SetWarpAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fWarp ); SetDirty( true ); } else if( SM == SM_BackFromBGChange ) @@ -3078,13 +3076,21 @@ static void ChangeMaxBPM( const RString &sNew ) GAMESTATE->m_pCurSong->m_fSpecifiedBPMMax = StringToFloat( sNew ); } +TimingData & ScreenEdit::GetAppropriateTiming() const +{ + if( GAMESTATE->m_bIsEditorStepTiming ) + { + return m_pSteps->m_Timing; + } + return m_pSong->m_SongTiming; +} + void ScreenEdit::DisplayTimingMenu() { float fBeat; - TimingData &pTime = m_pSteps->m_Timing; + TimingData &pTime = GetAppropriateTiming(); if( !GAMESTATE->m_bIsEditorStepTiming ) { - pTime = m_pSong->m_SongTiming; fBeat = GAMESTATE->m_Position.m_fSongBeat; } else diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index a24053645f..f471a6a9f1 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -548,6 +548,11 @@ public: void MakeFilteredMenuDef( const MenuDef* pDef, MenuDef &menu ); void EditMiniMenu( const MenuDef* pDef, ScreenMessage SM_SendOnOK = SM_None, ScreenMessage SM_SendOnCancel = SM_None ); +private: + /** + * @brief Retrieve the appropriate TimingData based on GAMESTATE. + * @return the proper TimingData. */ + TimingData & GetAppropriateTiming() const; }; #endif From 14fc0839d528dd39105bd51c405d83009799442b Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 23:11:42 -0400 Subject: [PATCH 055/197] [splittiming] Prepare right side of editor. Now, what key on the keyboard can be used for switching... --- Themes/_fallback/Languages/en.ini | 3 +++ Themes/_fallback/metrics.ini | 1 + src/ScreenEdit.cpp | 9 +++++++++ 3 files changed, 13 insertions(+) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index b4f91ef808..98a6d9c2e7 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1276,6 +1276,9 @@ Mines=Mines Rolls=Rolls Lifts=Lifts Fakes=Fakes +Timing Mode=Timing Mode +Step Timing=Step Timing +Song Timing=Song Timing Beat 0 offset=Beat 0 offset Preview Start=Preview Start Preview Length=Preview Length diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index ecac994d7e..9423e563fb 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -3627,6 +3627,7 @@ NumHandsFormat="%s: %d\n" NumRollsFormat="%s: %d\n" NumLiftsFormat="%s: %d\n" NumFakesFormat="%s: %d\n" +TimingModeFormat="%:\n %s\n" Beat0OffsetFormat="%s:\n %.5f secs\n" PreviewStartFormat="%s:\n %.5f secs\n" PreviewLengthFormat="%s:\n %.5f secs\n" diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 0113f41682..d05063d0ad 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1035,6 +1035,9 @@ static LocalizedString MINES("ScreenEdit", "Mines"); static LocalizedString ROLLS("ScreenEdit", "Rolls"); static LocalizedString LIFTS("ScreenEdit", "Lifts"); static LocalizedString FAKES("ScreenEdit", "Fakes"); +static LocalizedString TIMING_MODE("ScreenEdit", "Timing Mode"); +static LocalizedString STEP_TIMING("ScreenEdit", "Step Timing"); +static LocalizedString SONG_TIMING("ScreenEdit", "Song Timing"); static LocalizedString BEAT_0_OFFSET("ScreenEdit", "Beat 0 offset"); static LocalizedString PREVIEW_START("ScreenEdit", "Preview Start"); static LocalizedString PREVIEW_LENGTH("ScreenEdit", "Preview Length"); @@ -1060,6 +1063,7 @@ static ThemeMetric NUM_HANDS_FORMAT("ScreenEdit", "NumHandsFormat"); static ThemeMetric NUM_ROLLS_FORMAT("ScreenEdit", "NumRollsFormat"); static ThemeMetric NUM_LIFTS_FORMAT("ScreenEdit", "NumLiftsFormat"); static ThemeMetric NUM_FAKES_FORMAT("ScreenEdit", "NumFakesFormat"); +static ThemeMetric TIMING_MODE_FORMAT("ScreenEdit", "TimingModeFormat"); static ThemeMetric BEAT_0_OFFSET_FORMAT("ScreenEdit", "Beat0OffsetFormat"); static ThemeMetric PREVIEW_START_FORMAT("ScreenEdit", "PreviewStartFormat"); static ThemeMetric PREVIEW_LENGTH_FORMAT("ScreenEdit", "PreviewLengthFormat"); @@ -1139,6 +1143,11 @@ void ScreenEdit::UpdateTextInfo() case EditMode_Home: break; case EditMode_Full: + sText += ssprintf( TIMING_MODE_FORMAT.GetValue(), + TIMING_MODE.GetValue().c_str(), + ( GAMESTATE->m_bIsEditorStepTiming ? + STEP_TIMING.GetValue().c_str() : + SONG_TIMING.GetValue().c_str() ) ); sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), BEAT_0_OFFSET.GetValue().c_str(), GetAppropriateTiming().m_fBeat0OffsetInSeconds ); From 64a6abc12ba87f2174d31f99ce0c2de69e66c34d Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 23:18:57 -0400 Subject: [PATCH 056/197] [splittiming] Add the [T]iming Switch. One or two more things to do before running this... --- Themes/_fallback/Languages/en.ini | 1 + src/ScreenEdit.cpp | 9 +++++++++ src/ScreenEdit.h | 2 ++ 3 files changed, 12 insertions(+) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 98a6d9c2e7..e6c4a64c23 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1956,6 +1956,7 @@ Cycle between tap notes=Cycle between tap notes Lay mine=Lay mine Lay lift=Lay lift Add to/remove from right half=Add to/remove from right half +Switch Timing=Switch Timing Switch player (Routine only)=Switch player (Routine only) [Grade] diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index d05063d0ad..a12f22580f 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -310,6 +310,9 @@ void ScreenEdit::InitEditMappings() // Switch players, if it makes sense to do so. m_EditMappingsDeviceInput.button[EDIT_BUTTON_SWITCH_PLAYERS][0] = DeviceInput(DEVICE_KEYBOARD, KEY_SLASH); + + // Allow song and step timing to be swapped. + m_EditMappingsDeviceInput.button[EDIT_BUTTON_SWITCH_TIMINGS][0] = DeviceInput(DEVICE_KEYBOARD, KEY_Ct); m_PlayMappingsDeviceInput.button[EDIT_BUTTON_RETURN_TO_EDIT][0] = DeviceInput(DEVICE_KEYBOARD, KEY_ESC); m_PlayMappingsMenuButton.button[EDIT_BUTTON_RETURN_TO_EDIT][1] = GAME_BUTTON_BACK; @@ -2105,6 +2108,10 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) m_InputPlayerNumber = PLAYER_1; } break; + + case EDIT_BUTTON_SWITCH_TIMINGS: + GAMESTATE->m_bIsEditorStepTiming = !GAMESTATE->m_bIsEditorStepTiming; + break; } } @@ -4190,6 +4197,7 @@ struct EditHelpLine #undef PUSH_IF_VALID } }; +// TODO: Identify which of these can be removed and sent to a readme. static const EditHelpLine g_EditHelpLines[] = { EditHelpLine( "Move cursor", EDIT_BUTTON_SCROLL_UP_LINE, EDIT_BUTTON_SCROLL_DOWN_LINE ), @@ -4218,6 +4226,7 @@ static const EditHelpLine g_EditHelpLines[] = EditHelpLine( "Shift BPM changes and stops up one beat", EDIT_BUTTON_DELETE_SHIFT_PAUSES ), EditHelpLine( "Cycle between tap notes", EDIT_BUTTON_CYCLE_TAP_LEFT, EDIT_BUTTON_CYCLE_TAP_RIGHT ), EditHelpLine( "Add to/remove from right half", EDIT_BUTTON_RIGHT_SIDE ), + EditHelpLine( "Switch Timing", EDIT_BUTTON_SWITCH_TIMINGS ), EditHelpLine( "Switch player (Routine only)", EDIT_BUTTON_SWITCH_PLAYERS ), }; diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index f471a6a9f1..eb36e539e2 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -138,6 +138,8 @@ enum EditButton EDIT_BUTTON_ADD_COURSE_MODS, EDIT_BUTTON_SWITCH_PLAYERS, /**< Allow entering notes for a different Player. */ + + EDIT_BUTTON_SWITCH_TIMINGS, /**< Allow switching between Song and Step TimingData. */ NUM_EditButton, // leave this at the end EditButton_Invalid From 72690b8c70314a31723de3088ee021b4811f866e Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 12 May 2011 23:25:50 -0400 Subject: [PATCH 057/197] [splittiming] BG stuff in Song Timing only. Alright...let's see how badly I broke this. --- Themes/_fallback/Languages/en.ini | 2 +- src/ScreenEdit.cpp | 179 +++++++++++++++--------------- 2 files changed, 92 insertions(+), 89 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index e6c4a64c23..a2014d3f75 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1947,7 +1947,7 @@ Decrease/increase music offset=Decrease/increase music offset Decrease/increase sample music start=Decrease/increase sample music start Decrease/increase sample music length=Decrease/increase sample music length Play sample music=Play sample music -Add/Edit Background Change=Add/Edit Background Change +Add/Edit Background Change=Add/Edit Background Change (Song Timing Only) Insert beat and shift down=Insert beat and shift down Shift BPM changes and stops down one beat=Shift BPM changes and stops down one beat Delete beat and shift up=Delete beat and shift up diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index a12f22580f..7c738bac1e 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1798,101 +1798,104 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU: case EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU: - switch( EditB ) + if( !GAMESTATE->m_bIsEditorStepTiming ) { - DEFAULT_FAIL( EditB ); - case EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU: g_CurrentBGChangeLayer = BACKGROUND_LAYER_1; break; - case EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU: g_CurrentBGChangeLayer = BACKGROUND_LAYER_2; break; - } - - { - // Fill in option names - vector vThrowAway; - - MenuDef &menu = g_BackgroundChange; - - menu.rows[layer].choices[0] = ssprintf("%d",g_CurrentBGChangeLayer); - BackgroundUtil::GetBackgroundTransitions( "", vThrowAway, menu.rows[transition].choices ); - g_BackgroundChange.rows[transition].choices.insert( g_BackgroundChange.rows[transition].choices.begin(), "None" ); // add "no transition" - BackgroundUtil::GetBackgroundEffects( "", vThrowAway, menu.rows[effect].choices ); - menu.rows[effect].choices.insert( menu.rows[effect].choices.begin(), "Default" ); // add "default effect" - - BackgroundUtil::GetSongBGAnimations( m_pSong, "", vThrowAway, menu.rows[file1_song_bganimation].choices ); - BackgroundUtil::GetSongMovies( m_pSong, "", vThrowAway, menu.rows[file1_song_movie].choices ); - BackgroundUtil::GetSongBitmaps( m_pSong, "", vThrowAway, menu.rows[file1_song_still].choices ); - BackgroundUtil::GetGlobalBGAnimations( m_pSong, "", vThrowAway, menu.rows[file1_global_bganimation].choices ); // NULL to get all background files - BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie].choices, false, false ); // all backgrounds - BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie_song_group].choices, false, true ); // song group's backgrounds - BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie_song_group_and_genre].choices, true, true ); // song group and genre's backgrounds - - menu.rows[file2_type].choices = menu.rows[file1_type].choices; - menu.rows[file2_song_bganimation].choices = menu.rows[file1_song_bganimation].choices; - menu.rows[file2_song_movie].choices = menu.rows[file1_song_movie].choices; - menu.rows[file2_song_still].choices = menu.rows[file1_song_still].choices; - menu.rows[file2_global_bganimation].choices = menu.rows[file1_global_bganimation].choices; - menu.rows[file2_global_movie].choices = menu.rows[file1_global_movie].choices; - menu.rows[file2_global_movie_song_group].choices = menu.rows[file1_global_movie_song_group].choices; - menu.rows[file2_global_movie_song_group_and_genre].choices = menu.rows[file1_global_movie_song_group_and_genre].choices; - - - // Fill in lines enabled/disabled - bool bAlreadyBGChangeHere = false; - BackgroundChange bgChange; - FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer), bgc ) + switch( EditB ) { - if( bgc->m_fStartBeat == GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) - { - bAlreadyBGChangeHere = true; - bgChange = *bgc; - } + DEFAULT_FAIL( EditB ); + case EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU: g_CurrentBGChangeLayer = BACKGROUND_LAYER_1; break; + case EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU: g_CurrentBGChangeLayer = BACKGROUND_LAYER_2; break; } + { + // Fill in option names + vector vThrowAway; + + MenuDef &menu = g_BackgroundChange; + + menu.rows[layer].choices[0] = ssprintf("%d",g_CurrentBGChangeLayer); + BackgroundUtil::GetBackgroundTransitions( "", vThrowAway, menu.rows[transition].choices ); + g_BackgroundChange.rows[transition].choices.insert( g_BackgroundChange.rows[transition].choices.begin(), "None" ); // add "no transition" + BackgroundUtil::GetBackgroundEffects( "", vThrowAway, menu.rows[effect].choices ); + menu.rows[effect].choices.insert( menu.rows[effect].choices.begin(), "Default" ); // add "default effect" + + BackgroundUtil::GetSongBGAnimations( m_pSong, "", vThrowAway, menu.rows[file1_song_bganimation].choices ); + BackgroundUtil::GetSongMovies( m_pSong, "", vThrowAway, menu.rows[file1_song_movie].choices ); + BackgroundUtil::GetSongBitmaps( m_pSong, "", vThrowAway, menu.rows[file1_song_still].choices ); + BackgroundUtil::GetGlobalBGAnimations( m_pSong, "", vThrowAway, menu.rows[file1_global_bganimation].choices ); // NULL to get all background files + BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie].choices, false, false ); // all backgrounds + BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie_song_group].choices, false, true ); // song group's backgrounds + BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie_song_group_and_genre].choices, true, true ); // song group and genre's backgrounds + + menu.rows[file2_type].choices = menu.rows[file1_type].choices; + menu.rows[file2_song_bganimation].choices = menu.rows[file1_song_bganimation].choices; + menu.rows[file2_song_movie].choices = menu.rows[file1_song_movie].choices; + menu.rows[file2_song_still].choices = menu.rows[file1_song_still].choices; + menu.rows[file2_global_bganimation].choices = menu.rows[file1_global_bganimation].choices; + menu.rows[file2_global_movie].choices = menu.rows[file1_global_movie].choices; + menu.rows[file2_global_movie_song_group].choices = menu.rows[file1_global_movie_song_group].choices; + menu.rows[file2_global_movie_song_group_and_genre].choices = menu.rows[file1_global_movie_song_group_and_genre].choices; + + + // Fill in lines enabled/disabled + bool bAlreadyBGChangeHere = false; + BackgroundChange bgChange; + FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer), bgc ) + { + if( bgc->m_fStartBeat == GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) + { + bAlreadyBGChangeHere = true; + bgChange = *bgc; + } + } + #define FILL_ENABLED( x ) menu.rows[x].bEnabled = menu.rows[x].choices.size() > 0; - FILL_ENABLED( transition ); - FILL_ENABLED( effect ); - FILL_ENABLED( file1_song_bganimation ); - FILL_ENABLED( file1_song_movie ); - FILL_ENABLED( file1_song_still ); - FILL_ENABLED( file1_global_bganimation ); - FILL_ENABLED( file1_global_movie ); - FILL_ENABLED( file1_global_movie_song_group ); - FILL_ENABLED( file1_global_movie_song_group_and_genre ); - FILL_ENABLED( file2_song_bganimation ); - FILL_ENABLED( file2_song_movie ); - FILL_ENABLED( file2_song_still ); - FILL_ENABLED( file2_global_bganimation ); - FILL_ENABLED( file2_global_movie ); - FILL_ENABLED( file2_global_movie_song_group ); - FILL_ENABLED( file2_global_movie_song_group_and_genre ); + FILL_ENABLED( transition ); + FILL_ENABLED( effect ); + FILL_ENABLED( file1_song_bganimation ); + FILL_ENABLED( file1_song_movie ); + FILL_ENABLED( file1_song_still ); + FILL_ENABLED( file1_global_bganimation ); + FILL_ENABLED( file1_global_movie ); + FILL_ENABLED( file1_global_movie_song_group ); + FILL_ENABLED( file1_global_movie_song_group_and_genre ); + FILL_ENABLED( file2_song_bganimation ); + FILL_ENABLED( file2_song_movie ); + FILL_ENABLED( file2_song_still ); + FILL_ENABLED( file2_global_bganimation ); + FILL_ENABLED( file2_global_movie ); + FILL_ENABLED( file2_global_movie_song_group ); + FILL_ENABLED( file2_global_movie_song_group_and_genre ); #undef FILL_ENABLED - menu.rows[delete_change].bEnabled = bAlreadyBGChangeHere; + menu.rows[delete_change].bEnabled = bAlreadyBGChangeHere; - // set default choices - menu.rows[rate]. SetDefaultChoiceIfPresent( ssprintf("%2.0f%%",bgChange.m_fRate*100) ); - menu.rows[transition]. SetDefaultChoiceIfPresent( bgChange.m_sTransition ); - menu.rows[effect]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sEffect ); - menu.rows[file1_type].iDefaultChoice = none; - if( bgChange.m_def.m_sFile1 == RANDOM_BACKGROUND_FILE ) menu.rows[file1_type].iDefaultChoice = dynamic_random; - if( menu.rows[file1_song_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = song_bganimation; - if( menu.rows[file1_song_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = song_movie; - if( menu.rows[file1_song_still]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = song_bitmap; - if( menu.rows[file1_global_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = global_bganimation; - if( menu.rows[file1_global_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = global_movie; - if( menu.rows[file1_global_movie_song_group]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = global_movie_song_group; - if( menu.rows[file1_global_movie_song_group_and_genre]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = global_movie_song_group_and_genre; - menu.rows[file2_type].iDefaultChoice = none; - if( bgChange.m_def.m_sFile2 == RANDOM_BACKGROUND_FILE ) menu.rows[file2_type].iDefaultChoice = dynamic_random; - if( menu.rows[file2_song_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = song_bganimation; - if( menu.rows[file2_song_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = song_movie; - if( menu.rows[file2_song_still]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = song_bitmap; - if( menu.rows[file2_global_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = global_bganimation; - if( menu.rows[file2_global_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = global_movie; - if( menu.rows[file2_global_movie_song_group]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = global_movie_song_group; - if( menu.rows[file2_global_movie_song_group_and_genre]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = global_movie_song_group_and_genre; - menu.rows[color1]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sColor1 ); - menu.rows[color2]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sColor2 ); + // set default choices + menu.rows[rate]. SetDefaultChoiceIfPresent( ssprintf("%2.0f%%",bgChange.m_fRate*100) ); + menu.rows[transition]. SetDefaultChoiceIfPresent( bgChange.m_sTransition ); + menu.rows[effect]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sEffect ); + menu.rows[file1_type].iDefaultChoice = none; + if( bgChange.m_def.m_sFile1 == RANDOM_BACKGROUND_FILE ) menu.rows[file1_type].iDefaultChoice = dynamic_random; + if( menu.rows[file1_song_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = song_bganimation; + if( menu.rows[file1_song_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = song_movie; + if( menu.rows[file1_song_still]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = song_bitmap; + if( menu.rows[file1_global_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = global_bganimation; + if( menu.rows[file1_global_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = global_movie; + if( menu.rows[file1_global_movie_song_group]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = global_movie_song_group; + if( menu.rows[file1_global_movie_song_group_and_genre]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile1 ) ) menu.rows[file1_type].iDefaultChoice = global_movie_song_group_and_genre; + menu.rows[file2_type].iDefaultChoice = none; + if( bgChange.m_def.m_sFile2 == RANDOM_BACKGROUND_FILE ) menu.rows[file2_type].iDefaultChoice = dynamic_random; + if( menu.rows[file2_song_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = song_bganimation; + if( menu.rows[file2_song_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = song_movie; + if( menu.rows[file2_song_still]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = song_bitmap; + if( menu.rows[file2_global_bganimation]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = global_bganimation; + if( menu.rows[file2_global_movie]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = global_movie; + if( menu.rows[file2_global_movie_song_group]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = global_movie_song_group; + if( menu.rows[file2_global_movie_song_group_and_genre]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sFile2 ) ) menu.rows[file2_type].iDefaultChoice = global_movie_song_group_and_genre; + menu.rows[color1]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sColor1 ); + menu.rows[color2]. SetDefaultChoiceIfPresent( bgChange.m_def.m_sColor2 ); - EditMiniMenu( &g_BackgroundChange, SM_BackFromBGChange ); + EditMiniMenu( &g_BackgroundChange, SM_BackFromBGChange ); + } } break; @@ -2718,7 +2721,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) else if ( SM == SM_BackFromLabelChange ) { RString sLabel = ScreenTextEntry::s_sLastAnswer; - if ( !m_pSteps->m_Timing.DoesLabelExist(sLabel) ) + if ( !GetAppropriateTiming().DoesLabelExist(sLabel) ) { sLabel.Replace("=", "_"); sLabel.Replace(",", "_"); From 123f3a64ed80800b9a90599407cef6873be6e6f7 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 00:03:41 -0400 Subject: [PATCH 058/197] [splittiming] Minor typo. --- Themes/_fallback/metrics.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 9423e563fb..0ab21a76f5 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -3627,7 +3627,7 @@ NumHandsFormat="%s: %d\n" NumRollsFormat="%s: %d\n" NumLiftsFormat="%s: %d\n" NumFakesFormat="%s: %d\n" -TimingModeFormat="%:\n %s\n" +TimingModeFormat="%s:\n %s\n" Beat0OffsetFormat="%s:\n %.5f secs\n" PreviewStartFormat="%s:\n %.5f secs\n" PreviewLengthFormat="%s:\n %.5f secs\n" From 4c063eaefd75436fa558d4e0797a954a2209f2a2 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 00:05:31 -0400 Subject: [PATCH 059/197] [splittiming] Only display needed values. NOTE: Hackish code in here. Improvements would be appreciated. --- src/ScreenEdit.cpp | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 7c738bac1e..5e32eae172 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -562,10 +562,10 @@ static MenuDef g_SongInformation( MenuRowDef( ScreenEdit::max_bpm, "Max BPM", true, EditMode_Full, true, true, 0, NULL ) ); -static MenuDef g_TimingDataInformation( - "ScreenMiniMenuTimingDataInformation", - MenuRowDef( ScreenEdit::beat_0_offset, "Beat 0 Offset", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::bpm, "Edit BPM change", true, EditMode_Full, true, true, 0, NULL ), +static const MenuRowDef g_TimingDataLines[] = +{ + MenuRowDef( ScreenEdit::beat_0_offset, "Beat 0 Offset", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::bpm, "Edit BPM change", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::stop, "Edit stop", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::delay, "Edit delay", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::time_signature_numerator, "Edit time signature (top)", true, EditMode_Full, true, true, 0, NULL ), @@ -573,7 +573,12 @@ static MenuDef g_TimingDataInformation( MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::combo, "Edit combo", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::label, "Edit label", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ) + MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ), +}; + +static MenuDef g_TimingDataInformation( + "ScreenMiniMenuTimingDataInformation" + // fill this in dynamically too. ); enum { song_bganimation, song_movie, song_bitmap, global_bganimation, global_movie, global_movie_song_group, global_movie_song_group_and_genre, dynamic_random, baked_random, none }; @@ -3106,6 +3111,21 @@ TimingData & ScreenEdit::GetAppropriateTiming() const void ScreenEdit::DisplayTimingMenu() { + g_TimingDataInformation.rows.clear(); + + for( unsigned i=0; im_bIsEditorStepTiming ) + { + continue; + } + + g_TimingDataInformation.rows.push_back(hl); + } + float fBeat; TimingData &pTime = GetAppropriateTiming(); if( !GAMESTATE->m_bIsEditorStepTiming ) @@ -3116,6 +3136,10 @@ void ScreenEdit::DisplayTimingMenu() { fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; } + + // TODO: Better way of guaranteeing that we don't go out of bounds between timings. + int posLabel = ScreenEdit::tickcount; + int posWarp = ScreenEdit::combo; g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pTime.m_fBeat0OffsetInSeconds) ); g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); @@ -3123,13 +3147,16 @@ void ScreenEdit::DisplayTimingMenu() 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_denominator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) ); + if( GAMESTATE->m_bIsEditorStepTiming ) { g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); + posLabel = ScreenEdit::label; + posWarp = ScreenEdit::warp; } - g_TimingDataInformation.rows[label].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); - g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[posLabel].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); + g_TimingDataInformation.rows[posWarp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); } From ba65be23352011737402c7ecbb3ab019c117ca92 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 00:40:10 -0400 Subject: [PATCH 060/197] [splittiming] Don't show routine key on non. Hmm...does mercurial offer a cherry pick command? --- src/ScreenEdit.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 5e32eae172..0a6e8a2a4a 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -4328,6 +4328,13 @@ void ScreenEdit::DoHelp() RString sButtons = GetDeviceButtonsLocalized( hl.veb, m_EditMappingsDeviceInput ); RString sDescription = THEME->GetString( "EditHelpDescription", hl.szEnglishDescription ); + + // TODO: Better way of hiding routine only key on non-routine. + if( sDescription.Left(13) == "Switch player" && m_InputPlayerNumber == PLAYER_INVALID ) + { + continue; + } + g_EditHelp.rows.push_back( MenuRowDef( -1, sDescription, false, EditMode_Practice, false, false, 0, sButtons ) ); } From 172c80204f331037bcf9f3120706f7078e5908eb Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 00:49:59 -0400 Subject: [PATCH 061/197] [splittiming] doxygen test with transplanting. --- src/ScreenEdit.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index eb36e539e2..f76c56a020 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -71,8 +71,8 @@ enum EditButton EDIT_BUTTON_SCROLL_NEXT, EDIT_BUTTON_SCROLL_PREV, - EDIT_BUTTON_LABEL_NEXT, - EDIT_BUTTON_LABEL_PREV, + EDIT_BUTTON_LABEL_NEXT, /**< Jump to the start of the next label downward. */ + EDIT_BUTTON_LABEL_PREV, /**< Jump to the start of the previous label upward. */ // These are modifiers to EDIT_BUTTON_SCROLL_*. EDIT_BUTTON_SCROLL_SELECT, From 2116525e24aa42ec2b2c0bb58459828d3d4e93f7 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Fri, 13 May 2011 14:14:57 +0700 Subject: [PATCH 062/197] [splittiming] display song timing in song timing editing mode (buggy) --- src/NoteField.cpp | 53 ++++++++++++++++++++++++------- src/NoteField.h | 4 ++- src/ScreenEdit.cpp | 78 +++++++++++++++++++++++++++------------------- src/ScreenEdit.h | 3 ++ 4 files changed, 93 insertions(+), 45 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 66cdf2a34b..314da4376c 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -32,6 +32,33 @@ static ThemeMetric FADE_FAIL_TIME( "NoteField", "FadeFailTime" ); static RString RoutineNoteSkinName( size_t i ) { return ssprintf("RoutineNoteSkinP%i",int(i+1)); } static ThemeMetric1D ROUTINE_NOTESKIN( "NoteField", RoutineNoteSkinName, NUM_PLAYERS ); + +inline const TimingData *GetRealTiming(const PlayerState *pPlayerState) +{ + if( GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber] != NULL ) + return &GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing; + return NULL; +} + +inline const TimingData *GetDisplayedTiming(const PlayerState *pPlayerState) +{ + if( !GAMESTATE->m_bIsEditorStepTiming ) + return &GAMESTATE->m_pCurSong->m_SongTiming; + return GetRealTiming(pPlayerState); +} + +inline const SongPosition *GetRealPosition(const PlayerState *pPlayerState) +{ + return &pPlayerState->m_Position; +} + +inline const SongPosition *GetDisplayedPosition(const PlayerState *pPlayerState) +{ + if( !GAMESTATE->m_bIsEditorStepTiming ) + return &GAMESTATE->m_Position; + return GetRealPosition(pPlayerState); +} + NoteField::NoteField() { m_pNoteData = NULL; @@ -240,7 +267,7 @@ void NoteField::Update( float fDeltaTime ) ActorFrame::Update( fDeltaTime ); // update m_fBoardOffsetPixels, m_fCurrentBeatLastUpdate, m_fYPosCurrentBeatLastUpdate - const float fCurrentBeat = m_pPlayerState->m_Position.m_fSongBeat; + const float fCurrentBeat = GetDisplayedPosition(m_pPlayerState)->m_fSongBeat; bool bTweeningOn = m_sprBoard->GetCurrentDiffuseAlpha() >= 0.98 && m_sprBoard->GetCurrentDiffuseAlpha() < 1.00; // HACK if( !bTweeningOn && m_fCurrentBeatLastUpdate != -1 ) { @@ -444,6 +471,7 @@ static ThemeMetric TICKCOUNT_OFFSETX ( "NoteField", "TickcountOffsetX" ); static ThemeMetric COMBO_OFFSETX ( "NoteField", "ComboOffsetX" ); static ThemeMetric LABEL_OFFSETX ( "NoteField", "LabelOffsetX" ); + void NoteField::DrawBPMText( const float fBeat, const float fBPM ) { const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat ); @@ -606,7 +634,7 @@ void NoteField::DrawBGChangeText( const float fBeat, const RString sNewBGName ) // change this probing to binary search float FindFirstDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceAfterTargetsPixels ) { - float fFirstBeatToDraw = pPlayerState->m_Position.m_fSongBeat-4; // Adjust to balance off performance and showing enough notes. + float fFirstBeatToDraw = GetDisplayedPosition(pPlayerState)->m_fSongBeat-4; // Adjust to balance off performance and showing enough notes. /* In Boomerang, we'll usually have two sections of notes: before and after * the peak. We always start drawing before the peak, and end after it, or @@ -618,7 +646,7 @@ float FindFirstDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistance bBoomerang = (fAccels[PlayerOptions::ACCEL_BOOMERANG] != 0); } - while( fFirstBeatToDraw < pPlayerState->m_Position.m_fSongBeat ) + while( fFirstBeatToDraw < GetDisplayedPosition(pPlayerState)->m_fSongBeat ) { bool bIsPastPeakYOffset; float fPeakYOffset; @@ -640,7 +668,7 @@ float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceB // Probe for last note to draw. Worst case is 0.25x + boost. // Adjust search distance so that notes don't pop onto the screen. float fSearchDistance = 10; - float fLastBeatToDraw = pPlayerState->m_Position.m_fSongBeat+fSearchDistance; + float fLastBeatToDraw = GetDisplayedPosition(pPlayerState)->m_fSongBeat+fSearchDistance; const int NUM_ITERATIONS = 20; @@ -739,12 +767,13 @@ void NoteField::DrawPrimitives() cur->m_ReceptorArrowRow.Draw(); } - Steps *stepChecking = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]; + const TimingData *pTiming = GetDisplayedTiming(m_pPlayerState); // Draw beat bars - if( ( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) && stepChecking != NULL ) + if( ( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) && pTiming != NULL ) { - const vector &vTimeSignatureSegments = stepChecking->m_Timing.m_vTimeSignatureSegments; + const TimingData &timing = *pTiming; + const vector &vTimeSignatureSegments = timing.m_vTimeSignatureSegments; int iMeasureIndex = 0; FOREACH_CONST( TimeSignatureSegment, vTimeSignatureSegments, iter ) { @@ -783,11 +812,11 @@ void NoteField::DrawPrimitives() } } - if( GAMESTATE->IsEditing() && stepChecking != NULL ) + if( GAMESTATE->IsEditing() && pTiming != NULL ) { ASSERT(GAMESTATE->m_pCurSong); - const TimingData &timing = stepChecking->m_Timing; + const TimingData &timing = *pTiming; // BPM text FOREACH_CONST( BPMSegment, timing.m_BPMSegments, seg ) @@ -1056,7 +1085,7 @@ void NoteField::DrawPrimitives() displayCols->display[c].DrawHold( tn, c, iStartRow, bIsHoldingNote, Result, bUseAdditionColoring, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, m_fYReverseOffsetPixels, (float) iDrawDistanceAfterTargetsPixels, (float) iDrawDistanceBeforeTargetsPixels, iDrawDistanceBeforeTargetsPixels, FADE_BEFORE_TARGETS_PERCENT ); - bool bNoteIsUpcoming = NoteRowToBeat(iStartRow) > m_pPlayerState->m_Position.m_fSongBeat; + bool bNoteIsUpcoming = NoteRowToBeat(iStartRow) > GetDisplayedPosition(m_pPlayerState)->m_fSongBeat; bAnyUpcomingInThisCol |= bNoteIsUpcoming; } } @@ -1098,7 +1127,7 @@ void NoteField::DrawPrimitives() continue; // skip ASSERT_M( NoteRowToBeat(q) > -2000, ssprintf("%i %i %i, %f %f", q, iLastRowToDraw, - iFirstRowToDraw, m_pPlayerState->m_Position.m_fSongBeat, m_pPlayerState->m_Position.m_fMusicSeconds) ); + iFirstRowToDraw, GetDisplayedPosition(m_pPlayerState)->m_fSongBeat, GetDisplayedPosition(m_pPlayerState)->m_fMusicSeconds) ); // See if there is a hold step that begins on this index. // Only do this if the noteskin cares. @@ -1128,7 +1157,7 @@ void NoteField::DrawPrimitives() m_fYReverseOffsetPixels, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels, FADE_BEFORE_TARGETS_PERCENT ); - bool bNoteIsUpcoming = NoteRowToBeat(q) > m_pPlayerState->m_Position.m_fSongBeat; + bool bNoteIsUpcoming = NoteRowToBeat(q) > GetDisplayedPosition(m_pPlayerState)->m_fSongBeat; bAnyUpcomingInThisCol |= bNoteIsUpcoming; } diff --git a/src/NoteField.h b/src/NoteField.h index 560f3cb563..c389676cfb 100644 --- a/src/NoteField.h +++ b/src/NoteField.h @@ -1,6 +1,8 @@ #ifndef NOTE_FIELD_H #define NOTE_FIELD_H +#include "TimingData.h" +#include "SongPosition.h" #include "Sprite.h" #include "ActorFrame.h" #include "BitmapText.h" @@ -65,7 +67,7 @@ protected: void DrawAttackText( const float fBeat, const Attack &attack ); void DrawBGChangeText( const float fBeat, const RString sNewBGName ); float GetWidth() const; - + const NoteData *m_pNoteData; float m_fPercentFadeToFail; // -1 if not fading to fail diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 0a6e8a2a4a..8a69a67040 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -735,10 +735,8 @@ void ScreenEdit::Init() GAMESTATE->m_bGameplayLeadIn.Set( true ); GAMESTATE->m_EditMode = EDIT_MODE.GetValue(); - GAMESTATE->m_Position.m_fSongBeat = 0; - FOREACH_PlayerNumber( p ) - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = 0; - m_fTrailingBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + SetBeat(0); + m_fTrailingBeat = 0; m_iShiftAnchor = -1; m_iStartPlayingAt = -1; @@ -1179,9 +1177,13 @@ void ScreenEdit::DrawPrimitives() // HACK: Draw using the trailing beat PlayerState *pPlayerState = const_cast (m_NoteFieldEdit.GetPlayerState()); - float fSongBeat = pPlayerState->m_Position.m_fSongBeat; // save song beat - float fSongBeatNoOffset = pPlayerState->m_Position.m_fSongBeatNoOffset; - float fSongBeatVisible = pPlayerState->m_Position.m_fSongBeatVisible; + float fPlayerSongBeat = pPlayerState->m_Position.m_fSongBeat; // save song beat + float fPlayerSongBeatNoOffset = pPlayerState->m_Position.m_fSongBeatNoOffset; + float fPlayerSongBeatVisible = pPlayerState->m_Position.m_fSongBeatVisible; + + float fGameSongBeat = GAMESTATE->m_Position.m_fSongBeat; // save song beat + float fGameSongBeatNoOffset = GAMESTATE->m_Position.m_fSongBeatNoOffset; + float fGameSongBeatVisible = GAMESTATE->m_Position.m_fSongBeatVisible; pPlayerState->m_Position.m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect pPlayerState->m_Position.m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect @@ -1189,9 +1191,13 @@ void ScreenEdit::DrawPrimitives() ScreenWithMenuElements::DrawPrimitives(); - pPlayerState->m_Position.m_fSongBeat = fSongBeat; // restore real song beat - pPlayerState->m_Position.m_fSongBeatNoOffset = fSongBeatNoOffset; - pPlayerState->m_Position.m_fSongBeatVisible = fSongBeatVisible; + pPlayerState->m_Position.m_fSongBeat = fPlayerSongBeat; // restore real song beat + pPlayerState->m_Position.m_fSongBeatNoOffset = fPlayerSongBeatNoOffset; + pPlayerState->m_Position.m_fSongBeatVisible = fPlayerSongBeatVisible; + + GAMESTATE->m_Position.m_fSongBeat = fGameSongBeat; // restore real song beat + GAMESTATE->m_Position.m_fSongBeatNoOffset = fGameSongBeatNoOffset; + GAMESTATE->m_Position.m_fSongBeatVisible = fGameSongBeatVisible; } @@ -2407,15 +2413,8 @@ void ScreenEdit::TransitionEditState( EditState em ) m_Background.Unload(); m_Foreground.Unload(); - // Restore the cursor position. - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_fBeatToReturnTo; - - // Make sure we're snapped. - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = Quantize( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); - - /* Playing and recording have lead-ins, which may start before beat 0; - * make sure we don't stay there if we escaped out early. */ - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = max( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, 0 ); + // Restore the cursor position + Quantize + Clamp + SetBeat( max( 0, Quantize( m_fBeatToReturnTo, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ) ) ); break; @@ -2532,7 +2531,7 @@ void ScreenEdit::ScrollTo( float fDestinationBeat ) if( fOriginalBeat == fDestinationBeat ) return; - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = fDestinationBeat; + SetBeat(fDestinationBeat); // check to see if they're holding a button for( int n=0; nm_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_fTrailingBeat; + SetBeat(m_fTrailingBeat); } else if( SM == SM_LoseFocus ) { @@ -2981,10 +2980,10 @@ void ScreenEdit::OnSnapModeChange() m_soundChangeSnap.Play(); NoteType nt = m_SnapDisplay.GetNoteType(); - int iStepIndex = BeatToNoteRow( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); + int iStepIndex = BeatToNoteRow( GetBeat() ); int iElementsPerNoteType = BeatToNoteRow( NoteTypeToBeat(nt) ); int iStepIndexHangover = iStepIndex % iElementsPerNoteType; - GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat -= NoteRowToBeat( iStepIndexHangover ); + SetBeat( GetBeat() - NoteRowToBeat( iStepIndexHangover ) ); } @@ -3109,6 +3108,29 @@ TimingData & ScreenEdit::GetAppropriateTiming() const return m_pSong->m_SongTiming; } +inline void ScreenEdit::SetBeat(float fBeat) +{ + if( !GAMESTATE->m_bIsEditorStepTiming ) + { + GAMESTATE->m_Position.m_fSongBeat = fBeat; + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_pSteps->m_Timing.GetBeatFromElapsedTime(m_pSong->m_SongTiming.GetElapsedTimeFromBeat(fBeat)); + } + else + { + GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = fBeat; + GAMESTATE->m_Position.m_fSongBeat = m_pSong->m_SongTiming.GetBeatFromElapsedTime(m_pSteps->m_Timing.GetElapsedTimeFromBeat(fBeat)); + } +} + +inline float ScreenEdit::GetBeat() +{ + if( !GAMESTATE->m_bIsEditorStepTiming ) + { + return GAMESTATE->m_Position.m_fSongBeat; + } + return GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; +} + void ScreenEdit::DisplayTimingMenu() { g_TimingDataInformation.rows.clear(); @@ -3126,16 +3148,8 @@ void ScreenEdit::DisplayTimingMenu() g_TimingDataInformation.rows.push_back(hl); } - float fBeat; + float fBeat = GetBeat(); TimingData &pTime = GetAppropriateTiming(); - if( !GAMESTATE->m_bIsEditorStepTiming ) - { - fBeat = GAMESTATE->m_Position.m_fSongBeat; - } - else - { - fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; - } // TODO: Better way of guaranteeing that we don't go out of bounds between timings. int posLabel = ScreenEdit::tickcount; diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index f76c56a020..da134f6aa2 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -555,6 +555,9 @@ private: * @brief Retrieve the appropriate TimingData based on GAMESTATE. * @return the proper TimingData. */ TimingData & GetAppropriateTiming() const; + void SetBeat(float fBeat); + float GetBeat(); + }; #endif From 1c4b21b18113524687642958478a8783cd9329d0 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Fri, 13 May 2011 15:19:42 +0700 Subject: [PATCH 063/197] [splittiming] ok, now it displays properly. --- src/ArrowEffects.cpp | 10 ++++++---- src/NoteField.cpp | 19 ++++++++++++++++--- src/ScreenEdit.cpp | 18 +++++++++++------- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index f5ea953136..a0566826d1 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -85,13 +85,14 @@ void ArrowEffects::Update() FOREACH_PlayerNumber( pn ) { const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn]; + const SongPosition &position = GAMESTATE->m_bIsEditorStepTiming ? GAMESTATE->m_pPlayerState[pn]->m_Position : GAMESTATE->m_Position; PerPlayerData &data = g_EffectData[pn]; { static float fLastTime = 0; float fTime = RageTimer::GetTimeSinceStartFast(); - if( !GAMESTATE->m_pPlayerState[pn]->m_Position.m_bFreeze || !GAMESTATE->m_pPlayerState[pn]->m_Position.m_bDelay ) + if( !position.m_bFreeze || !position.m_bDelay ) { data.m_fExpandSeconds += fTime - fLastTime; data.m_fExpandSeconds = fmodf( data.m_fExpandSeconds, PI*2 ); @@ -177,7 +178,7 @@ void ArrowEffects::Update() // Update Beat do { float fAccelTime = 0.2f, fTotalTime = 0.5f; - float fBeat = GAMESTATE->m_pPlayerState[pn]->m_Position.m_fSongBeatVisible + fAccelTime; + float fBeat = position.m_fSongBeatVisible + fAccelTime; const bool bEvenBeat = ( int(fBeat) % 2 ) != 0; @@ -218,12 +219,13 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float bIsPastPeakOut = true; float fYOffset = 0; + const SongPosition &position = GAMESTATE->m_bIsEditorStepTiming ? pPlayerState->m_Position : GAMESTATE->m_Position; /* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or * entirely time spacing (respectively). Occasionally, we tween between them. */ if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f ) { - float fSongBeat = pPlayerState->m_Position.m_fSongBeatVisible; + float fSongBeat = position.m_fSongBeatVisible; float fBeatsUntilStep = fNoteBeat - fSongBeat; float fYOffsetBeatSpacing = fBeatsUntilStep; fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); @@ -231,7 +233,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f ) { - float fSongSeconds = pPlayerState->m_Position.m_fMusicSecondsVisible; + float fSongSeconds = position.m_fMusicSecondsVisible; float fNoteSeconds = GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing.GetElapsedTimeFromBeat(fNoteBeat); float fSecondsUntilStep = fNoteSeconds - fSongSeconds; float fBPM = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollBPM; diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 314da4376c..6982277071 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -697,6 +697,19 @@ float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceB return fLastBeatToDraw; } +inline float NoteRowToVisibleBeat( const PlayerState *pPlayerState, int iRow ) +{ + /* + if( GAMESTATE->m_bIsEditorStepTiming ) + { + */ + return NoteRowToBeat(iRow); + /* + } + return GetDisplayedTiming(pPlayerState)->GetBeatFromElapsedTime(GetRealTiming(pPlayerState)->GetElapsedTimeFromBeat(NoteRowToBeat(iRow))); + */ +} + bool NoteField::IsOnScreen( float fBeat, int iCol, int iDrawDistanceAfterTargetsPixels, int iDrawDistanceBeforeTargetsPixels ) const { // TRICKY: If boomerang is on, then ones in the range @@ -1054,8 +1067,8 @@ void NoteField::DrawPrimitives() float fThrowAway; bool bStartIsPastPeak = false; bool bEndIsPastPeak = false; - float fStartYOffset = ArrowEffects::GetYOffset( m_pPlayerState, c, NoteRowToBeat(iStartRow), fThrowAway, bStartIsPastPeak ); - float fEndYOffset = ArrowEffects::GetYOffset( m_pPlayerState, c, NoteRowToBeat(iEndRow), fThrowAway, bEndIsPastPeak ); + float fStartYOffset = ArrowEffects::GetYOffset( m_pPlayerState, c, NoteRowToVisibleBeat(m_pPlayerState, iStartRow), fThrowAway, bStartIsPastPeak ); + float fEndYOffset = ArrowEffects::GetYOffset( m_pPlayerState, c, NoteRowToVisibleBeat(m_pPlayerState, iEndRow), fThrowAway, bEndIsPastPeak ); bool bTailIsOnVisible = iDrawDistanceAfterTargetsPixels <= fEndYOffset && fEndYOffset <= iDrawDistanceBeforeTargetsPixels; bool bHeadIsVisible = iDrawDistanceAfterTargetsPixels <= fStartYOffset && fStartYOffset <= iDrawDistanceBeforeTargetsPixels; @@ -1152,7 +1165,7 @@ void NoteField::DrawPrimitives() bool bIsHopoPossible = (tn.bHopoPossible); bool bUseAdditionColoring = bIsAddition || bIsHopoPossible; NoteDisplayCols *displayCols = tn.pn == PLAYER_INVALID ? m_pCurDisplay : m_pDisplays[tn.pn]; - displayCols->display[c].DrawTap( tn, c, NoteRowToBeat(q), bHoldNoteBeginsOnThisBeat, + displayCols->display[c].DrawTap( tn, c, NoteRowToVisibleBeat(m_pPlayerState, q), bHoldNoteBeginsOnThisBeat, bUseAdditionColoring, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, m_fYReverseOffsetPixels, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels, FADE_BEFORE_TARGETS_PERCENT ); diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 8a69a67040..94a2bb44f1 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1010,12 +1010,12 @@ void ScreenEdit::Update( float fDeltaTime ) // Update trailing beat - float fDelta = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat - m_fTrailingBeat; + float fDelta = GetBeat() - m_fTrailingBeat; if( fabsf(fDelta) < 10 ) - fapproach( m_fTrailingBeat, GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, + fapproach( m_fTrailingBeat, GetBeat(), fDeltaTime*40 / m_NoteFieldEdit.GetPlayerState()->m_PlayerOptions.GetCurrent().m_fScrollSpeed ); else - fapproach( m_fTrailingBeat, GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, + fapproach( m_fTrailingBeat, GetBeat(), fabsf(fDelta) * fDeltaTime*5 ); PlayTicks(); @@ -1090,8 +1090,8 @@ void ScreenEdit::UpdateTextInfo() RString sNoteType = ssprintf( NOTES.GetValue(), NoteTypeToLocalizedString(m_SnapDisplay.GetNoteType()).c_str() ); RString sText; - sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); - sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ); + sText += ssprintf( CURRENT_BEAT_FORMAT.GetValue(), CURRENT_BEAT.GetValue().c_str(), GetBeat() ); + sText += ssprintf( CURRENT_SECOND_FORMAT.GetValue(), CURRENT_SECOND.GetValue().c_str(), GetAppropriateTiming().GetElapsedTimeFromBeat(GetBeat()) ); switch( EDIT_MODE.GetValue() ) { DEFAULT_FAIL( EDIT_MODE.GetValue() ); @@ -1188,6 +1188,10 @@ void ScreenEdit::DrawPrimitives() pPlayerState->m_Position.m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect pPlayerState->m_Position.m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect pPlayerState->m_Position.m_fSongBeatVisible = m_fTrailingBeat; // put trailing beat in effect + + GAMESTATE->m_Position.m_fSongBeat = m_fTrailingBeat; // put trailing beat in effect + GAMESTATE->m_Position.m_fSongBeatNoOffset = m_fTrailingBeat; // put trailing beat in effect + GAMESTATE->m_Position.m_fSongBeatVisible = m_fTrailingBeat; // put trailing beat in effect ScreenWithMenuElements::DrawPrimitives(); @@ -1446,7 +1450,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( m_PlayerStateEdit.m_PlayerOptions.GetSong().m_fScrolls[PlayerOptions::SCROLL_REVERSE] > 0.5 ) fBeatsToMove *= -1; - float fDestinationBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat + fBeatsToMove; + float fDestinationBeat = GetBeat() + fBeatsToMove; fDestinationBeat = Quantize( fDestinationBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); ScrollTo( fDestinationBeat ); @@ -2969,7 +2973,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) else if( SM == SM_LoseFocus ) { // Snap the trailing beat, in case we lose focus while tweening. - m_fTrailingBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + m_fTrailingBeat = GetBeat(); //GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; } ScreenWithMenuElements::HandleScreenMessage( SM ); From f694fe5955556b09d6eb7677548a34ea3128f844 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 08:50:59 -0400 Subject: [PATCH 064/197] [splittiming] Add sounds to recent actions. --- Themes/_fallback/Sounds/ScreenEdit switch player.redir | 1 + Themes/_fallback/Sounds/ScreenEdit switch timing.redir | 1 + src/ScreenEdit.cpp | 4 ++++ src/ScreenEdit.h | 8 ++++++++ 4 files changed, 14 insertions(+) create mode 100644 Themes/_fallback/Sounds/ScreenEdit switch player.redir create mode 100644 Themes/_fallback/Sounds/ScreenEdit switch timing.redir diff --git a/Themes/_fallback/Sounds/ScreenEdit switch player.redir b/Themes/_fallback/Sounds/ScreenEdit switch player.redir new file mode 100644 index 0000000000..cd59d419fb --- /dev/null +++ b/Themes/_fallback/Sounds/ScreenEdit switch player.redir @@ -0,0 +1 @@ +MusicWheel sort diff --git a/Themes/_fallback/Sounds/ScreenEdit switch timing.redir b/Themes/_fallback/Sounds/ScreenEdit switch timing.redir new file mode 100644 index 0000000000..cd59d419fb --- /dev/null +++ b/Themes/_fallback/Sounds/ScreenEdit switch timing.redir @@ -0,0 +1 @@ +MusicWheel sort diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 94a2bb44f1..35760b7872 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -837,6 +837,8 @@ void ScreenEdit::Init() m_soundMarker.Load( THEME->GetPathS("ScreenEdit","marker"), true ); m_soundValueIncrease.Load( THEME->GetPathS("ScreenEdit","value increase"), true ); m_soundValueDecrease.Load( THEME->GetPathS("ScreenEdit","value decrease"), true ); + m_soundSwitchPlayer.Load( THEME->GetPathS("ScreenEdit","switch player"), true ); + m_soundSwitchTiming.Load( THEME->GetPathS("ScreenEdit","switch timing"), true ); m_soundSwitchSteps.Load( THEME->GetPathS("ScreenEdit","switch steps") ); m_soundSave.Load( THEME->GetPathS("ScreenEdit","save") ); m_GameplayAssist.Init(); @@ -2124,11 +2126,13 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) enum_add( m_InputPlayerNumber, 1 ); if( m_InputPlayerNumber == NUM_PLAYERS ) m_InputPlayerNumber = PLAYER_1; + m_soundSwitchPlayer.Play(); } break; case EDIT_BUTTON_SWITCH_TIMINGS: GAMESTATE->m_bIsEditorStepTiming = !GAMESTATE->m_bIsEditorStepTiming; + m_soundSwitchTiming.Play(); break; } } diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index da134f6aa2..d6a472e5c3 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -281,14 +281,22 @@ protected: /** @brief Has the NoteData been changed such that a user should be prompted to save? */ bool m_bDirty; + /** @brief The sound that is played when a note is added. */ RageSound m_soundAddNote; + /** @brief The sound that is played when a note is removed. */ RageSound m_soundRemoveNote; RageSound m_soundChangeLine; RageSound m_soundChangeSnap; RageSound m_soundMarker; RageSound m_soundValueIncrease; RageSound m_soundValueDecrease; + /** @brief The sound that is played when switching players for Routine. */ + RageSound m_soundSwitchPlayer; + /** @brief The sound that is played when switching song/step timing. */ + RageSound m_soundSwitchTiming; + /** @brief The sound that is played when switching to a different chart. */ RageSound m_soundSwitchSteps; + /** @brief The sound that is played when the chart is saved. */ RageSound m_soundSave; // used for reverting From b43dabc0948d8f6b558fc0f14dac95e7d6a61d73 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 09:05:32 -0400 Subject: [PATCH 065/197] [splittiming] Tap insertions are Step Time only. --- src/ScreenEdit.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 35760b7872..0b8f28af26 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1306,6 +1306,13 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( input.type != IET_FIRST_PRESS ) break; // We only care about first presses + + if( !GAMESTATE->m_bIsEditorStepTiming ) + { + // TODO: broadcast a message...? + break; // Only allow steps to be hit in Step Timing. + } + int iCol = EditB - EDIT_BUTTON_COLUMN_0; From a7b58e07a203c286dd1863bc2ef79bbd77037e0b Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 09:20:42 -0400 Subject: [PATCH 066/197] [splittiming] Broadcast message on failure. --- Themes/_fallback/Languages/en.ini | 1 + src/ScreenEdit.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index a2014d3f75..03cef7dd16 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1257,6 +1257,7 @@ This change creates more than %d notes in a measure.=This change creates more th This change creates notes past the end of the music and is not allowed.=This change creates notes past the end of the music and is not allowed. This will destroy all unsaved changes.=This will destroy all unsaved changes. Undo=Undo +You must be in Step Timing Mode to edit the notes.=You must be in Step Timing Mode to edit the notes. Current beat=Current beat Current second=Current second diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 0b8f28af26..025decb52b 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1276,9 +1276,10 @@ static int FindAttackAtTime( const AttackArray& attacks, float fStartTime ) return -1; } +static LocalizedString TAP_NOTE_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to edit the notes." ); static LocalizedString SWITCHED_TO ( "ScreenEdit", "Switched to" ); static LocalizedString NO_BACKGROUNDS_AVAILABLE ( "ScreenEdit", "No backgrounds available" ); -static ThemeMetric INVERT_SCROLL_BUTTONS ( "ScreenEdit", "InvertScrollSpeedButtons" ); +static ThemeMetric INVERT_SCROLL_BUTTONS ( "ScreenEdit", "InvertScrollSpeedButtons" ); void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { @@ -1309,8 +1310,9 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( !GAMESTATE->m_bIsEditorStepTiming ) { - // TODO: broadcast a message...? - break; // Only allow steps to be hit in Step Timing. + // Only allow steps to be hit in Step Timing. + SCREENMAN->SystemMessage( TAP_NOTE_SONG_TIMING ); + break; } int iCol = EditB - EDIT_BUTTON_COLUMN_0; From 6f6c18e0508f3d9f392c79353160590adfe58951 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 09:44:54 -0400 Subject: [PATCH 067/197] [splittiming] More SST fixes. --- src/ScreenEdit.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 025decb52b..bfc51637a7 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2153,6 +2153,9 @@ void ScreenEdit::InputRecord( const InputEventPlus &input, EditButton EditB ) TransitionEditState( STATE_EDITING ); return; } + + if ( !GAMESTATE->m_bIsEditorStepTiming ) + return; // can't allow changes if in song timing. if( input.pn != PLAYER_1 ) return; // ignore @@ -3667,16 +3670,16 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns TransitionEditState( STATE_RECORDING ); break; case insert_and_shift: - NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), BeatToNoteRow(1) ); + NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow( GetBeat() ), BeatToNoteRow(1) ); break; case delete_and_shift: - NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), BeatToNoteRow(1) ); + NoteDataUtil::DeleteRows( m_NoteDataEdit, BeatToNoteRow( GetBeat() ), BeatToNoteRow(1) ); break; case shift_pauses_forward: - m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), BeatToNoteRow(1) ); + GetAppropriateTiming().InsertRows( BeatToNoteRow( GetBeat() ), BeatToNoteRow(1) ); break; case shift_pauses_backward: - m_pSteps->m_Timing.DeleteRows( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), BeatToNoteRow(1) ); + GetAppropriateTiming().DeleteRows( BeatToNoteRow( GetBeat() ), BeatToNoteRow(1) ); break; case convert_to_pause: { From cba8011765ab72008ea59dda8f7832badb57e065 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 09:49:00 -0400 Subject: [PATCH 068/197] [splittiming] Preemptive SST fixing. --- src/ScreenEdit.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index bfc51637a7..775a1f29b5 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3684,8 +3684,8 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case convert_to_pause: { ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - float fMarkerStart = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); - float fMarkerEnd = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); + float fMarkerStart = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); + float fMarkerEnd = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); // The length of the stop segment we're going to create. This includes time spent in any // stops in the selection, which will be deleted and subsumed into the new stop. @@ -3697,9 +3697,9 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns m_NoteFieldEdit.m_iBeginMarker + 1, m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); - m_pSteps->m_Timing.DeleteRows( m_NoteFieldEdit.m_iBeginMarker, + GetAppropriateTiming().DeleteRows( m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); - m_pSteps->m_Timing.SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); + GetAppropriateTiming().SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); m_NoteFieldEdit.m_iBeginMarker = -1; m_NoteFieldEdit.m_iEndMarker = -1; break; @@ -3707,14 +3707,14 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case convert_pause_to_beat: { // TODO: Convert both Delays and Stops at once. - float fStopSeconds = m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ); - m_pSteps->m_Timing.SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, 0 ); + float fStopSeconds = GetAppropriateTiming().GetStopAtRow( BeatToNoteRow( GetBeat() ) ); + GetAppropriateTiming().SetStopAtBeat( GetBeat() , 0 ); - float fStopBeats = fStopSeconds * m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) / 60; + float fStopBeats = fStopSeconds * GetAppropriateTiming().GetBPMAtBeat( GetBeat() ) / 60; // don't move the step from where it is, just move everything later - NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); - m_pSteps->m_Timing.InsertRows( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) + 1, BeatToNoteRow(fStopBeats) ); + NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow( GetBeat() ) + 1, BeatToNoteRow(fStopBeats) ); + GetAppropriateTiming().InsertRows( BeatToNoteRow( GetBeat() ) + 1, BeatToNoteRow(fStopBeats) ); } break; case undo: From 844f5828a55a8a1f90906c5d5b706e2f0b3a1a47 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 09:53:06 -0400 Subject: [PATCH 069/197] [splittiming] Use SST, Simplify. --- src/ScreenEdit.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 775a1f29b5..6799d93409 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3874,14 +3874,14 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice DEFAULT_FAIL( c ); case beat_0_offset: ScreenTextEntry::TextEntry( SM_None, ENTER_BEAT_0_OFFSET, - ssprintf("%.5f", m_pSteps->m_Timing.m_fBeat0OffsetInSeconds), 20, + ssprintf("%.5f", GetAppropriateTiming().m_fBeat0OffsetInSeconds), 20, ScreenTextEntry::FloatValidate, ChangeBeat0Offset, NULL ); break; case bpm: ScreenTextEntry::TextEntry( SM_BackFromBPMChange, ENTER_BPM_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetBPMAtBeat(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ), + ssprintf( "%.4f", GetAppropriateTiming().GetBPMAtBeat( GetBeat() ) ), 10 ); break; @@ -3889,7 +3889,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromStopChange, ENTER_STOP_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetStopAtRow( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ) ), + ssprintf( "%.4f", GetAppropriateTiming().GetStopAtBeat( GetBeat() ) ), 10 ); break; @@ -3897,7 +3897,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromDelayChange, ENTER_DELAY_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetDelayAtRow( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ) ), + ssprintf( "%.4f", GetAppropriateTiming().GetDelayAtBeat( GetBeat() ) ), 10 ); break; @@ -3905,7 +3905,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureNumeratorChange, ENTER_TIME_SIGNATURE_NUMERATOR_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iNumerator ), + ssprintf( "%d", GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iNumerator ), 3 ); break; @@ -3913,7 +3913,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureDenominatorChange, ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iDenominator ), + ssprintf( "%d", GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iDenominator ), 3 ); break; @@ -3921,7 +3921,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromTickcountChange, ENTER_TICKCOUNT_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetTickcountAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) ), + ssprintf( "%d", GetAppropriateTiming().GetTickcountAtBeat( GetBeat() ) ), 2 ); break; @@ -3929,7 +3929,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromComboChange, ENTER_COMBO_VALUE, - ssprintf( "%d", m_pSteps->m_Timing.GetComboAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) ), + ssprintf( "%d", GetAppropriateTiming().GetComboAtBeat( GetBeat() ) ), 4 ); break; @@ -3937,7 +3937,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromLabelChange, ENTER_LABEL_VALUE, - ssprintf( "%s", m_pSteps->m_Timing.GetLabelAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).c_str() ), + ssprintf( "%s", GetAppropriateTiming().GetLabelAtBeat( GetBeat() ).c_str() ), 64 ); break; @@ -3945,7 +3945,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromWarpChange, ENTER_WARP_VALUE, - ssprintf( "%.4f", m_pSteps->m_Timing.GetWarpAtRow( BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ) ), + ssprintf( "%.4f", GetAppropriateTiming().GetWarpAtBeat( GetBeat() ) ), 10 ); break; From af3fb53d182a3a5c93a1cda444685914d742d033 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 09:55:25 -0400 Subject: [PATCH 070/197] [splittiming] doxygen note on SST. --- src/ScreenEdit.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index d6a472e5c3..f783cf5368 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -529,6 +529,12 @@ public: NUM_BGCHANGE_CHOICES }; + /** + * @brief Take care of any background changes that the user wants. + * + * It is important that this is only called in Song Timing mode. + * @param c the Background Change style requested. + * @param iAnswers the other settings involving the change. */ void HandleBGChangeChoice( BGChangeChoice c, const vector &iAnswers ); enum CourseAttackChoice From d85b9552b4153c771b4d0ac1025d7bcb5822305b Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 10:07:41 -0400 Subject: [PATCH 071/197] [splittiming] Use more SST functions. --- src/ScreenEdit.cpp | 60 ++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 6799d93409..10adb8c403 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -936,6 +936,8 @@ void ScreenEdit::Update( float fDeltaTime ) if( m_EditState == STATE_RECORDING ) { + // TODO: Find a way to prevent STATE_RECORDING when in Song Timing. + for( int t=0; tGetCurrentStyle()->m_iColsPerPlayer; t++ ) // for each track { GameInput GameI = GAMESTATE->GetCurrentStyle()->StyleInputToGameInput( t, PLAYER_1 ); @@ -950,7 +952,7 @@ void ScreenEdit::Update( float fDeltaTime ) float fStartedHoldingSeconds = m_pSoundMusic->GetPositionSeconds() - fSecsHeld; float fStartBeat = max( fStartPlayingAtBeat, m_pSteps->m_Timing.GetBeatFromElapsedTime(fStartedHoldingSeconds) ); - float fEndBeat = max( fStartBeat, GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); + float fEndBeat = max( fStartBeat, GetBeat() ); fEndBeat = min( fEndBeat, NoteRowToBeat(m_iStopPlayingAt) ); // Round start and end to the nearest snap interval @@ -992,12 +994,13 @@ void ScreenEdit::Update( float fDeltaTime ) } float fLastBeat = NoteRowToBeat(m_iStopPlayingAt); - if( bButtonIsBeingPressed && m_EditState == STATE_RECORDING ) + if( bButtonIsBeingPressed && m_EditState == STATE_RECORDING && GAMESTATE->m_bIsEditorStepTiming ) { float fSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( fLastBeat ); fLastBeat = m_pSteps->m_Timing.GetBeatFromElapsedTime( fSeconds + 0.5f ); } + // This should be fine: it will convert to the same I believe. -Wolfman2000 float fStopAtSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStopPlayingAt) ) + 1; if( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fMusicSeconds > fStopAtSeconds ) { @@ -1638,7 +1641,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_BPM_UP: case EDIT_BUTTON_BPM_DOWN: { - float fBPM = m_pSteps->m_Timing.GetBPMAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); + float fBPM = GetAppropriateTiming().GetBPMAtBeat( GetBeat() ); float fDelta; switch( EditB ) { @@ -1659,7 +1662,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } float fNewBPM = fBPM + fDelta; - m_pSteps->m_Timing.SetBPMAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fNewBPM ); + GetAppropriateTiming().SetBPMAtBeat( GetBeat(), fNewBPM ); (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); } @@ -1686,24 +1689,24 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) fDelta *= 40; } unsigned i; - for( i=0; im_Timing.m_StopSegments.size(); i++ ) + for( i=0; im_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat) ) + if( GetAppropriateTiming().m_StopSegments[i].m_iStartRow == BeatToNoteRow( GetBeat() ) ) break; } - if( i == m_pSteps->m_Timing.m_StopSegments.size() ) // there is no StopSegment at the current beat + if( i == GetAppropriateTiming().m_StopSegments.size() ) // there is no StopSegment at the current beat { // create a new StopSegment if( fDelta > 0 ) - m_pSteps->m_Timing.AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat), fDelta) ); + GetAppropriateTiming().AddStopSegment( StopSegment(BeatToNoteRow( GetBeat() ), fDelta) ); } else // StopSegment being modified is m_SongTiming.m_StopSegments[i] { - m_pSteps->m_Timing.m_StopSegments[i].m_fStopSeconds += fDelta; - if( m_pSteps->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 ) - m_pSteps->m_Timing.m_StopSegments.erase( m_pSteps->m_Timing.m_StopSegments.begin()+i, - m_pSteps->m_Timing.m_StopSegments.begin()+i+1); + GetAppropriateTiming().m_StopSegments[i].m_fStopSeconds += fDelta; + if( GetAppropriateTiming().m_StopSegments[i].m_fStopSeconds <= 0 ) + GetAppropriateTiming().m_StopSegments.erase( GetAppropriateTiming().m_StopSegments.begin()+i, + GetAppropriateTiming().m_StopSegments.begin()+i+1); } (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); @@ -1732,13 +1735,13 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) fDelta *= 40; } unsigned i; - for( i=0; im_Timing.m_StopSegments.size(); i++ ) + for( i=0; im_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) + if( GetAppropriateTiming().m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_Position.m_fSongBeat) ) break; } - if( i == m_pSteps->m_Timing.m_StopSegments.size() ) // there is no delay segment at the current beat + if( i == GetAppropriateTiming().m_StopSegments.size() ) // there is no delay segment at the current beat { // create a new delay segment if( fDelta > 0 ) @@ -1746,10 +1749,10 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } else // delay segment being modified is m_SongTiming.m_StopSegments[i] { - m_pSteps->m_Timing.m_StopSegments[i].m_fStopSeconds += fDelta; - if( m_pSteps->m_Timing.m_StopSegments[i].m_fStopSeconds <= 0 ) - m_pSteps->m_Timing.m_StopSegments.erase( m_pSteps->m_Timing.m_StopSegments.begin()+i, - m_pSteps->m_Timing.m_StopSegments.begin()+i+1); + GetAppropriateTiming().m_StopSegments[i].m_fStopSeconds += fDelta; + if( GetAppropriateTiming().m_StopSegments[i].m_fStopSeconds <= 0 ) + GetAppropriateTiming().m_StopSegments.erase( GetAppropriateTiming().m_StopSegments.begin()+i, + GetAppropriateTiming().m_StopSegments.begin()+i+1); } (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); @@ -1777,7 +1780,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) else fDelta *= 40; } - m_pSteps->m_Timing.m_fBeat0OffsetInSeconds += fDelta; + GetAppropriateTiming().m_fBeat0OffsetInSeconds += fDelta; (fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play(); SetDirty( true ); } @@ -1958,6 +1961,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_OPEN_COURSE_ATTACK_MENU: { + // TODO: Give Song/Step Timing switches/functions here? Course *pCourse = GAMESTATE->m_pCurCourse; if( pCourse == NULL ) break; @@ -2003,6 +2007,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) } else { + // TODO: Give Song/Step Timing switches/functions here? fStart = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); int iAttack = FindAttackAtTime( ce.attacks, fStart ); @@ -2336,7 +2341,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB ) fOffsetDelta *= 40; } - m_pSteps->m_Timing.m_fBeat0OffsetInSeconds += fOffsetDelta; + GetAppropriateTiming().m_fBeat0OffsetInSeconds += fOffsetDelta; } break; } @@ -2444,9 +2449,10 @@ void ScreenEdit::TransitionEditState( EditState em ) if( bStateChanging ) AdjustSync::ResetOriginalSyncData(); - /* Give a 1 second lead-in. If we're loading Player, this must be done first. */ - float fSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1; - GAMESTATE->UpdateSongPosition( fSeconds, m_pSteps->m_Timing, RageZeroTimer, true ); + /* Give a 1 second lead-in. If we're loading Player, this must be done first. + * Also be sure to get the right timing. */ + float fSeconds = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_iStartPlayingAt) ) - 1; + GAMESTATE->UpdateSongPosition( fSeconds, GetAppropriateTiming(), RageZeroTimer, true ); GAMESTATE->m_bGameplayLeadIn.Set( false ); @@ -2527,7 +2533,7 @@ void ScreenEdit::TransitionEditState( EditState em ) { case STATE_PLAYING: case STATE_RECORDING: - const float fStartSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat(GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat); + const float fStartSeconds = GetAppropriateTiming().GetElapsedTimeFromBeat( GetBeat() ); LOG->Trace( "Starting playback at %f", fStartSeconds ); RageSoundParams p; @@ -2828,6 +2834,8 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) Course *pCourse = GAMESTATE->m_pCurCourse; CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; int iAttack; + + // TODO: Handle Song/Step Timing functions/switches here? g_fLastInsertAttackPositionSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( GAMESTATE->m_Position.m_fSongBeat ); g_fLastInsertAttackDurationSeconds = StringToFloat( g_InsertCourseAttack.rows[0].choices[iDurationChoice] ); @@ -3630,7 +3638,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex ); // scale timing data - m_pSteps->m_Timing.ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); + GetAppropriateTiming().ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); // scale all other steps. /* From e26868a2d7ed49d213e41618e9956c804d433aeb Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 10:51:09 -0400 Subject: [PATCH 072/197] [splittiming] More SST. --- src/ScreenEdit.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 10adb8c403..c1d721de8c 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1326,7 +1326,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) ShiftToRightSide( iCol, m_NoteDataEdit.GetNumTracks() ); - const float fSongBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + const float fSongBeat = GetBeat(); const int iSongIndex = BeatToNoteRow( fSongBeat ); if( iCol >= m_NoteDataEdit.GetNumTracks() ) // this button is not in the range of columns for this Style @@ -2179,7 +2179,7 @@ void ScreenEdit::InputRecord( const InputEventPlus &input, EditButton EditB ) } // Add a tap - float fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + float fBeat = GetBeat(); fBeat = Quantize( fBeat, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ); const int iRow = BeatToNoteRow( fBeat ); @@ -2695,21 +2695,21 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { float fBPM = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fBPM > 0 ) - GetAppropriateTiming().SetBPMAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fBPM ); + GetAppropriateTiming().SetBPMAtBeat( GetBeat(), fBPM ); SetDirty( true ); } else if( SM == SM_BackFromStopChange ) { float fStop = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fStop >= 0 ) - GetAppropriateTiming().SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fStop ); + GetAppropriateTiming().SetStopAtBeat( GetBeat(), fStop ); SetDirty( true ); } else if( SM == SM_BackFromDelayChange ) { float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer ); if( fDelay >= 0 ) - GetAppropriateTiming().SetStopAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fDelay, true ); + GetAppropriateTiming().SetStopAtBeat( GetBeat(), fDelay, true ); SetDirty( true ); } else if( SM == SM_BackFromTimeSignatureNumeratorChange ) @@ -2717,7 +2717,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iNum = StringToInt( ScreenTextEntry::s_sLastAnswer ); if( iNum > 0 ) { - GetAppropriateTiming().SetTimeSignatureNumeratorAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iNum ); + GetAppropriateTiming().SetTimeSignatureNumeratorAtBeat( GetBeat(), iNum ); } SetDirty( true ); } @@ -2726,7 +2726,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iDen = StringToInt( ScreenTextEntry::s_sLastAnswer ); if( iDen > 0) { - GetAppropriateTiming().SetTimeSignatureDenominatorAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iDen ); + GetAppropriateTiming().SetTimeSignatureDenominatorAtBeat( GetBeat(), iDen ); } SetDirty( true ); } @@ -2735,7 +2735,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iTick = StringToInt( ScreenTextEntry::s_sLastAnswer ); if ( iTick >= 0 && iTick <= ROWS_PER_BEAT ) { - GetAppropriateTiming().SetTickcountAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iTick ); + GetAppropriateTiming().SetTickcountAtBeat( GetBeat(), iTick ); } SetDirty( true ); } @@ -2744,7 +2744,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iCombo = StringToInt( ScreenTextEntry::s_sLastAnswer ); if ( iCombo >= 0 ) { - GetAppropriateTiming().SetComboAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, iCombo ); + GetAppropriateTiming().SetComboAtBeat( GetBeat(), iCombo ); } SetDirty( true ); } @@ -2755,14 +2755,14 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { sLabel.Replace("=", "_"); sLabel.Replace(",", "_"); - GetAppropriateTiming().SetLabelAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, sLabel ); + GetAppropriateTiming().SetLabelAtBeat( GetBeat(), sLabel ); SetDirty( true ); } } else if ( SM == SM_BackFromWarpChange ) { float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer ); - GetAppropriateTiming().SetWarpAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, fWarp ); + GetAppropriateTiming().SetWarpAtBeat( GetBeat(), fWarp ); SetDirty( true ); } else if( SM == SM_BackFromBGChange ) @@ -3494,6 +3494,8 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case paste_at_current_beat: case paste_at_begin_marker: { + // TODO: Song/Step Timing checks? + int iDestFirstRow = -1; switch( c ) { From e3cec47a419f3a67b1889cce1c92840b83283582 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 15:21:48 -0400 Subject: [PATCH 073/197] [splittiming] More SST adjustments. --- src/ScreenEdit.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index c1d721de8c..ed6d0bb541 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1472,42 +1472,40 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_SCROLL_NEXT_MEASURE: { - float fDestinationBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat + beatsPerMeasure; + float fDestinationBeat = GetBeat() + beatsPerMeasure; fDestinationBeat = ftruncf( fDestinationBeat, (float)beatsPerMeasure ); ScrollTo( fDestinationBeat ); break; } case EDIT_BUTTON_SCROLL_PREV_MEASURE: { - float fDestinationBeat = QuantizeUp( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat, (float)beatsPerMeasure ); + float fDestinationBeat = QuantizeUp( GetBeat(), (float)beatsPerMeasure ); fDestinationBeat -= (float)beatsPerMeasure; ScrollTo( fDestinationBeat ); break; } case EDIT_BUTTON_SCROLL_NEXT: { - int iRow = BeatToNoteRow( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); + int iRow = BeatToNoteRow( GetBeat() ); NoteDataUtil::GetNextEditorPosition( m_NoteDataEdit, iRow ); ScrollTo( NoteRowToBeat(iRow) ); } break; case EDIT_BUTTON_SCROLL_PREV: { - int iRow = BeatToNoteRow( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); + int iRow = BeatToNoteRow( GetBeat() ); NoteDataUtil::GetPrevEditorPosition( m_NoteDataEdit, iRow ); ScrollTo( NoteRowToBeat(iRow) ); } break; case EDIT_BUTTON_LABEL_NEXT: { - ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming. - GetNextLabelSegmentBeatAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) ); + ScrollTo( GetAppropriateTiming().GetNextLabelSegmentBeatAtBeat( GetBeat() ) ); } break; case EDIT_BUTTON_LABEL_PREV: { - ScrollTo( GAMESTATE->m_pCurSong->m_SongTiming. - GetPreviousLabelSegmentBeatAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) ); + ScrollTo( GetAppropriateTiming().GetPreviousLabelSegmentBeatAtBeat( GetBeat() ) ); } break; case EDIT_BUTTON_SNAP_NEXT: From 9e747aa84b7c21f6692f4fa42f57560487754009 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 15:25:19 -0400 Subject: [PATCH 074/197] [splittiming] No longer just pauses and BPMs. --- Themes/_fallback/Languages/en.ini | 4 ++-- src/ScreenEdit.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 03cef7dd16..49bc09f431 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -983,8 +983,8 @@ Set modifiers=Set modifiers Set Mods=Set Mods Set selection start=Set selection start Set selection end=Set selection end -Shift pauses and BPM changes down=Shift pauses and BPM changes down -Shift pauses and BPM changes up=Shift pauses and BPM changes up +Shift all timing changes down=Shift all timing changes down +Shift all timing changes up=Shift all timing changes up ShowBanners=Show Banners ShowBeginnerHelper=Beginner Helper ShowCaution=Caution diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index ed6d0bb541..158250f238 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -516,8 +516,8 @@ static MenuDef g_AreaMenu( MenuRowDef( ScreenEdit::record, "Record in selection", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::insert_and_shift, "Insert beat and shift down", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::delete_and_shift, "Delete beat and shift up", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::shift_pauses_forward, "Shift pauses and BPM changes down", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::shift_pauses_backward, "Shift pauses and BPM changes up", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::shift_pauses_forward, "Shift all timing changes down", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::shift_pauses_backward, "Shift all timing changes up", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::convert_to_pause, "Convert selection to pause", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::convert_pause_to_beat, "Convert pause to beats", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::undo, "Undo", true, EditMode_Practice, true, true, 0, NULL ) From e95ac1eef0f743d3e68c873b93ad71a7752c73e3 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 15:38:21 -0400 Subject: [PATCH 075/197] [splittiming] Song Timings don't get warps. Song Timing is meant for background changes and emergency fallback Step Timing. Warps do not belong here. --- src/NotesWriterSSC.cpp | 19 +++++++++++-------- src/ScreenEdit.cpp | 8 +++----- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 445aa9ee5b..3e7882741e 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -82,7 +82,7 @@ struct TimingTagWriter { }; -static void GetTimingTags( vector &lines, TimingData timing ) +static void GetTimingTags( vector &lines, TimingData timing, bool bIsSong = false ) { TimingTagWriter w ( &lines ); @@ -105,10 +105,13 @@ static void GetTimingTags( vector &lines, TimingData timing ) w.Write( ss->m_iStartRow, ss->m_fStopSeconds ); w.Finish(); - w.Init( "WARPS" ); - FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws ) - w.Write( ws->m_iStartRow, ws->m_fEndBeat ); - w.Finish(); + if( !bIsSong ) + { + w.Init( "WARPS" ); + FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws ) + w.Write( ws->m_iStartRow, ws->m_fEndBeat ); + w.Finish(); + } ASSERT( !timing.m_vTimeSignatureSegments.empty() ); w.Init( "TIMESIGNATURES" ); @@ -134,12 +137,12 @@ static void GetTimingTags( vector &lines, TimingData timing ) w.Finish(); } -static void WriteTimingTags( RageFile &f, const TimingData &timing ) +static void WriteTimingTags( RageFile &f, const TimingData &timing, bool bIsSong = false ) { vector lines; - GetTimingTags( lines, timing ); + GetTimingTags( lines, timing, bIsSong ); f.PutLine( JoinLineList( lines ) ); @@ -210,7 +213,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) break; } - WriteTimingTags( f, out.m_SongTiming ); + WriteTimingTags( f, out.m_SongTiming, true ); FOREACH_BackgroundLayer( b ) { diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 158250f238..0ff4b95235 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3165,8 +3165,8 @@ void ScreenEdit::DisplayTimingMenu() { const MenuRowDef &hl = g_TimingDataLines[i]; - if( ( hl.iRowCode == ScreenEdit::tickcount || hl.iRowCode == ScreenEdit::combo ) - && !GAMESTATE->m_bIsEditorStepTiming ) + if( ( hl.iRowCode == ScreenEdit::tickcount || hl.iRowCode == ScreenEdit::combo + || hl.iRowCode == ScreenEdit::warp ) && !GAMESTATE->m_bIsEditorStepTiming ) { continue; } @@ -3179,7 +3179,6 @@ void ScreenEdit::DisplayTimingMenu() // TODO: Better way of guaranteeing that we don't go out of bounds between timings. int posLabel = ScreenEdit::tickcount; - int posWarp = ScreenEdit::combo; g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pTime.m_fBeat0OffsetInSeconds) ); g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); @@ -3192,11 +3191,10 @@ void ScreenEdit::DisplayTimingMenu() { g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); posLabel = ScreenEdit::label; - posWarp = ScreenEdit::warp; } g_TimingDataInformation.rows[posLabel].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); - g_TimingDataInformation.rows[posWarp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); } From 323f1b0059709741d1941639b42cdd2236e44cb5 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 16:04:17 -0400 Subject: [PATCH 076/197] [splittiming] Remove hack, just use bEnabled. Wish I saw this sooner. --- src/ScreenEdit.cpp | 62 ++++++++++++++-------------------------------- src/ScreenEdit.h | 2 +- 2 files changed, 20 insertions(+), 44 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 0ff4b95235..2c547ac03d 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -562,23 +562,19 @@ static MenuDef g_SongInformation( MenuRowDef( ScreenEdit::max_bpm, "Max BPM", true, EditMode_Full, true, true, 0, NULL ) ); -static const MenuRowDef g_TimingDataLines[] = -{ - MenuRowDef( ScreenEdit::beat_0_offset, "Beat 0 Offset", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::bpm, "Edit BPM change", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::stop, "Edit stop", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::delay, "Edit delay", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::time_signature_numerator, "Edit time signature (top)", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::time_signature_denominator, "Edit time signature (bottom)", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::combo, "Edit combo", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::label, "Edit label", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ), -}; static MenuDef g_TimingDataInformation( - "ScreenMiniMenuTimingDataInformation" - // fill this in dynamically too. + "ScreenMiniMenuTimingDataInformation", + MenuRowDef( ScreenEdit::beat_0_offset, "Beat 0 Offset", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::bpm, "Edit BPM change", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::stop, "Edit stop", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::delay, "Edit delay", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::time_signature_numerator, "Edit time signature (top)", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::time_signature_denominator, "Edit time signature (bottom)", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::label, "Edit label", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::combo, "Edit combo", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ) ); enum { song_bganimation, song_movie, song_bitmap, global_bganimation, global_movie, global_movie_song_group, global_movie_song_group_and_genre, dynamic_random, baked_random, none }; @@ -3159,43 +3155,23 @@ inline float ScreenEdit::GetBeat() void ScreenEdit::DisplayTimingMenu() { - g_TimingDataInformation.rows.clear(); - - for( unsigned i=0; im_bIsEditorStepTiming ) - { - continue; - } - - g_TimingDataInformation.rows.push_back(hl); - } - float fBeat = GetBeat(); TimingData &pTime = GetAppropriateTiming(); - - // TODO: Better way of guaranteeing that we don't go out of bounds between timings. - int posLabel = ScreenEdit::tickcount; - g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pTime.m_fBeat0OffsetInSeconds) ); g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[time_signature_numerator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[time_signature_denominator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[label].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); + g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); - if( GAMESTATE->m_bIsEditorStepTiming ) - { - g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); - posLabel = ScreenEdit::label; - } - g_TimingDataInformation.rows[posLabel].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); - + g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_TimingDataInformation.rows[combo].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_TimingDataInformation.rows[warp].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); } diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index f783cf5368..68a2353a83 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -492,9 +492,9 @@ public: // time_signature, time_signature_numerator, time_signature_denominator, + label, tickcount, combo, - label, warp, NUM_TIMING_DATA_INFORMATION_CHOICES }; From e078e6beef6a3d45a2f799daa6e33d609ea21290 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 16:29:35 -0400 Subject: [PATCH 077/197] [splittiming] More SST setup. Song Timing shouldn't edit notes, only timing. --- src/ScreenEdit.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 2c547ac03d..cc2a677b3c 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1544,18 +1544,20 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { // update enabled/disabled in g_AreaMenu bool bAreaSelected = m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1; - g_AreaMenu.rows[cut].bEnabled = bAreaSelected; + g_AreaMenu.rows[cut].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; g_AreaMenu.rows[copy].bEnabled = bAreaSelected; - g_AreaMenu.rows[paste_at_current_beat].bEnabled = !m_Clipboard.IsEmpty(); - g_AreaMenu.rows[paste_at_begin_marker].bEnabled = !m_Clipboard.IsEmpty() != 0 && m_NoteFieldEdit.m_iBeginMarker!=-1; - g_AreaMenu.rows[clear].bEnabled = bAreaSelected; - g_AreaMenu.rows[quantize].bEnabled = bAreaSelected; - g_AreaMenu.rows[turn].bEnabled = bAreaSelected; - g_AreaMenu.rows[transform].bEnabled = bAreaSelected; + g_AreaMenu.rows[paste_at_current_beat].bEnabled = !m_Clipboard.IsEmpty() && GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[paste_at_begin_marker].bEnabled = !m_Clipboard.IsEmpty() != 0 && m_NoteFieldEdit.m_iBeginMarker!=-1 && GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[clear].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[quantize].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[turn].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[transform].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; g_AreaMenu.rows[alter].bEnabled = bAreaSelected; g_AreaMenu.rows[tempo].bEnabled = bAreaSelected; g_AreaMenu.rows[play].bEnabled = bAreaSelected; - g_AreaMenu.rows[record].bEnabled = bAreaSelected; + g_AreaMenu.rows[record].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[insert_and_shift].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[delete_and_shift].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_AreaMenu.rows[convert_to_pause].bEnabled = bAreaSelected; g_AreaMenu.rows[undo].bEnabled = m_bHasUndo; EditMiniMenu( &g_AreaMenu, SM_BackFromAreaMenu ); @@ -2065,6 +2067,11 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) HandleMainMenuChoice( play_selection ); break; case EDIT_BUTTON_RECORD_SELECTION: + if( !GAMESTATE->m_bIsEditorStepTiming ) + { + // broadcast message maybe. + break; + } if( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ) { HandleAreaMenuChoice( record ); @@ -2221,7 +2228,12 @@ void ScreenEdit::InputRecordPaused( const InputEventPlus &input, EditButton Edit break; case EDIT_BUTTON_RECORD_SELECTION: - TransitionEditState( STATE_RECORDING ); + if( GAMESTATE->m_bIsEditorStepTiming ) + TransitionEditState( STATE_RECORDING ); + else + { + // broadcast error maybe. + } break; case EDIT_BUTTON_RECORD_FROM_CURSOR: From 7c9b54e9f0d0c6cb611722a78a3c0439a4bf37db Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 13 May 2011 23:32:14 -0400 Subject: [PATCH 078/197] [splittiming] Fix ArrowEffects 1c4b21b. Almost had this one right...just needed more vars. --- src/ArrowEffects.cpp | 6 ++++-- src/GameState.h | 5 +++++ src/ScreenEdit.cpp | 3 +++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index a0566826d1..e6f3831849 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -85,7 +85,8 @@ void ArrowEffects::Update() FOREACH_PlayerNumber( pn ) { const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn]; - const SongPosition &position = GAMESTATE->m_bIsEditorStepTiming ? GAMESTATE->m_pPlayerState[pn]->m_Position : GAMESTATE->m_Position; + const SongPosition &position = (!GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsEditorStepTiming) + ? GAMESTATE->m_pPlayerState[pn]->m_Position : GAMESTATE->m_Position; PerPlayerData &data = g_EffectData[pn]; @@ -219,7 +220,8 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float bIsPastPeakOut = true; float fYOffset = 0; - const SongPosition &position = GAMESTATE->m_bIsEditorStepTiming ? pPlayerState->m_Position : GAMESTATE->m_Position; + const SongPosition &position = (!GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsEditorStepTiming) + ? pPlayerState->m_Position : GAMESTATE->m_Position; /* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or * entirely time spacing (respectively). Occasionally, we tween between them. */ diff --git a/src/GameState.h b/src/GameState.h index 592b613dfe..0a6efc0e25 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -337,6 +337,11 @@ public: * * Different options are available depending on this setting. */ bool m_bIsEditorStepTiming; + /** + * @brief Are we presently in the Step Editor, where some rules apply differently? + * + * TODO: Find a better way to implement this. */ + bool m_bInStepEditor; BroadcastOnChange m_stEdit; BroadcastOnChange m_cdEdit; BroadcastOnChangePtr m_pEditSourceSteps; diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index cc2a677b3c..2ff3b112dc 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -698,6 +698,7 @@ void ScreenEdit::Init() m_pSoundMusic = NULL; GAMESTATE->m_bIsEditorStepTiming = true; + GAMESTATE->m_bInStepEditor = true; SubscribeToMessage( "Judgment" ); @@ -858,6 +859,8 @@ ScreenEdit::~ScreenEdit() // Reset the GameState variable in case it's needed elsewhere. GAMESTATE->m_bIsEditorStepTiming = false; + // DEFINITELY reset the InStepEditor variable. + GAMESTATE->m_bInStepEditor = false; } void ScreenEdit::BeginScreen() From f4684b8cc3f3e0c924d581eb96c2958c3ab94716 Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Fri, 13 May 2011 23:37:07 -0500 Subject: [PATCH 079/197] use player timing for autoplay row check --- src/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.cpp b/src/Player.cpp index f992b838d5..95878e4c1c 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -919,7 +919,7 @@ void Player::Update( float fDeltaTime ) /* We want to send the crossed row message exactly when we cross the row--not * .5 before the row. Use a very slow song (around 2 BPM) as a test case: without * rounding, autoplay steps early. -glenn */ - const int iRowNow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat ); + const int iRowNow = BeatToNoteRowNotRounded( m_pPlayerState->m_Position.m_fSongBeat ); if( iRowNow >= 0 ) { if( GAMESTATE->IsPlayerEnabled(m_pPlayerState) ) From e462049c1608c7accf82f5eb098ea3d98a52413a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 00:57:34 -0400 Subject: [PATCH 080/197] [splittiming] No more holds/rolls on Song Timing. --- src/ScreenEdit.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 2ff3b112dc..8ba386b31a 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2584,17 +2584,20 @@ void ScreenEdit::ScrollTo( float fDestinationBeat ) if( !EditIsBeingPressed(b) ) continue; - // create a new hold note - int iStartRow = BeatToNoteRow( min(fOriginalBeat, fDestinationBeat) ); - int iEndRow = BeatToNoteRow( max(fOriginalBeat, fDestinationBeat) ); + if( GAMESTATE->m_bIsEditorStepTiming ) + { + // create a new hold note + int iStartRow = BeatToNoteRow( min(fOriginalBeat, fDestinationBeat) ); + int iEndRow = BeatToNoteRow( max(fOriginalBeat, fDestinationBeat) ); - // Don't SaveUndo. We want to undo the whole hold, not just the last segment - // that the user made. Dragging the hold bigger can only absorb and remove - // other taps, so dragging won't cause us to exceed the note limit. - TapNote tn = EditIsBeingPressed(EDIT_BUTTON_LAY_ROLL) ? TAP_ORIGINAL_ROLL_HEAD : TAP_ORIGINAL_HOLD_HEAD; + // Don't SaveUndo. We want to undo the whole hold, not just the last segment + // that the user made. Dragging the hold bigger can only absorb and remove + // other taps, so dragging won't cause us to exceed the note limit. + TapNote tn = EditIsBeingPressed(EDIT_BUTTON_LAY_ROLL) ? TAP_ORIGINAL_ROLL_HEAD : TAP_ORIGINAL_HOLD_HEAD; - tn.pn = m_InputPlayerNumber; - m_NoteDataEdit.AddHoldNote( iCol, iStartRow, iEndRow, tn ); + tn.pn = m_InputPlayerNumber; + m_NoteDataEdit.AddHoldNote( iCol, iStartRow, iEndRow, tn ); + } } if( EditIsBeingPressed(EDIT_BUTTON_SCROLL_SELECT) ) From 361a6340db161f7518b86dced1af246edcc009f7 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 01:03:39 -0400 Subject: [PATCH 081/197] [splittiming] No BG Changes in Step Timing. --- Themes/_fallback/Languages/en.ini | 1 + src/ScreenEdit.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 49bc09f431..0fbe2863dc 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1258,6 +1258,7 @@ This change creates notes past the end of the music and is not allowed.=This cha This will destroy all unsaved changes.=This will destroy all unsaved changes. Undo=Undo You must be in Step Timing Mode to edit the notes.=You must be in Step Timing Mode to edit the notes. +You must be in Song Timing Mode to edit BG Changes.=You must be in Song Timing Mode to edit BG Changes. Current beat=Current beat Current second=Current second diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 8ba386b31a..1941179491 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1279,6 +1279,8 @@ static int FindAttackAtTime( const AttackArray& attacks, float fStartTime ) } static LocalizedString TAP_NOTE_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to edit the notes." ); +static LocalizedString BG_CHANGE_STEP_TIMING ( "ScreenEdit", "You must be in Song Timing Mode to edit BG Changes." ); + static LocalizedString SWITCHED_TO ( "ScreenEdit", "Switched to" ); static LocalizedString NO_BACKGROUNDS_AVAILABLE ( "ScreenEdit", "No backgrounds available" ); static ThemeMetric INVERT_SCROLL_BUTTONS ( "ScreenEdit", "InvertScrollSpeedButtons" ); @@ -1925,6 +1927,10 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) EditMiniMenu( &g_BackgroundChange, SM_BackFromBGChange ); } } + else + { + SCREENMAN->SystemMessage( BG_CHANGE_STEP_TIMING ); + } break; case EDIT_BUTTON_OPEN_COURSE_MENU: From 393dadcb1621fe6099556d9010f4ddb1f2627903 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 01:31:28 -0400 Subject: [PATCH 082/197] [splittiming] More SST protection. Also added InvalidSound for emphasis. --- Themes/_fallback/Languages/en.ini | 3 +++ src/ScreenEdit.cpp | 26 +++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 0fbe2863dc..85147d8920 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1259,6 +1259,9 @@ This will destroy all unsaved changes.=This will destroy all unsaved changes. Undo=Undo You must be in Step Timing Mode to edit the notes.=You must be in Step Timing Mode to edit the notes. You must be in Song Timing Mode to edit BG Changes.=You must be in Song Timing Mode to edit BG Changes. +You must be in Step Timing Mode to record steps.=You must be in Step Timing Mode to record steps. +You must be in Step Timing Mode to insert beats and shift down.=You must be in Step Timing Mode to insert beats and shift down. +You must be in Step Timing Mode to delete beats and shift up.=You must be in Step Timing Mode to delete beats and shift up. Current beat=Current beat Current second=Current second diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 1941179491..e8cbb396e5 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1280,6 +1280,9 @@ static int FindAttackAtTime( const AttackArray& attacks, float fStartTime ) static LocalizedString TAP_NOTE_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to edit the notes." ); static LocalizedString BG_CHANGE_STEP_TIMING ( "ScreenEdit", "You must be in Song Timing Mode to edit BG Changes." ); +static LocalizedString RECORD_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to record steps." ); +static LocalizedString INSERT_BEAT_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to insert beats and shift down." ); +static LocalizedString DELETE_BEAT_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to delete beats and shift up." ); static LocalizedString SWITCHED_TO ( "ScreenEdit", "Switched to" ); static LocalizedString NO_BACKGROUNDS_AVAILABLE ( "ScreenEdit", "No backgrounds available" ); @@ -1316,6 +1319,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { // Only allow steps to be hit in Step Timing. SCREENMAN->SystemMessage( TAP_NOTE_SONG_TIMING ); + SCREENMAN->PlayInvalidSound(); break; } @@ -1930,6 +1934,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) else { SCREENMAN->SystemMessage( BG_CHANGE_STEP_TIMING ); + SCREENMAN->PlayInvalidSound(); } break; @@ -2078,7 +2083,8 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_RECORD_SELECTION: if( !GAMESTATE->m_bIsEditorStepTiming ) { - // broadcast message maybe. + SCREENMAN->SystemMessage( RECORD_SONG_TIMING ); + SCREENMAN->PlayInvalidSound(); break; } if( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ) @@ -2117,7 +2123,14 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_INSERT: - HandleAreaMenuChoice( insert_and_shift ); + if( GAMESTATE->m_bIsEditorStepTiming ) + { + HandleAreaMenuChoice( insert_and_shift ); + } + else + { + SCREENMAN->SystemMessage( INSERT_BEAT_SONG_TIMING ); + } SCREENMAN->PlayInvalidSound(); break; @@ -2127,7 +2140,14 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_DELETE: - HandleAreaMenuChoice( delete_and_shift ); + if( GAMESTATE->m_bIsEditorStepTiming ) + { + HandleAreaMenuChoice( delete_and_shift ); + } + else + { + SCREENMAN->SystemMessage( DELETE_BEAT_SONG_TIMING ); + } SCREENMAN->PlayInvalidSound(); break; From 9909125b501ae51b398b1e58bc40e17d6dd5785d Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 01:37:12 -0400 Subject: [PATCH 083/197] [splittiming] Let Linux have fun with this. I forgot which folder SongPosition.* goes in. --- src/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 2a60163c84..178a263f39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -373,7 +373,8 @@ ScoreDisplayBattle.cpp ScoreDisplayBattle.h \ ScoreDisplayCalories.cpp ScoreDisplayCalories.h \ ScoreDisplayLifeTime.cpp ScoreDisplayLifeTime.h \ ScoreDisplayNormal.cpp ScoreDisplayNormal.h ScoreDisplayOni.cpp ScoreDisplayOni.h \ -ScoreDisplayPercentage.cpp ScoreDisplayPercentage.h ScoreDisplayRave.cpp ScoreDisplayRave.h +ScoreDisplayPercentage.cpp ScoreDisplayPercentage.h ScoreDisplayRave.cpp ScoreDisplayRave.h \ +SongPosition.cpp SongPosition.h PCRE = ../extern/pcre/get.c ../extern/pcre/internal.h ../extern/pcre/maketables.c ../extern/pcre/pcre.c ../extern/pcre/pcre.h ../extern/pcre/study.c EXTRA_DIST += ../extern/pcre/chartables.c From 230fd47cf082d507c2047ab8ae480d2135cae86e Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 01:41:20 -0400 Subject: [PATCH 084/197] [splittiming] This also needed SST care. --- src/ScreenEdit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index e8cbb396e5..b97d7a77bb 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1561,7 +1561,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) g_AreaMenu.rows[quantize].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; g_AreaMenu.rows[turn].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; g_AreaMenu.rows[transform].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[alter].bEnabled = bAreaSelected; + g_AreaMenu.rows[alter].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; g_AreaMenu.rows[tempo].bEnabled = bAreaSelected; g_AreaMenu.rows[play].bEnabled = bAreaSelected; g_AreaMenu.rows[record].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; From d538c548c55a5d72c20f2b587d8ef84bed0780ea Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sat, 14 May 2011 00:43:06 -0500 Subject: [PATCH 085/197] [splittiming] add an option to revert timing for steps to the song's timing to the editor --- src/ScreenEdit.cpp | 14 ++++++++++++++ src/ScreenEdit.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index b97d7a77bb..569d631549 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -83,6 +83,7 @@ AutoScreenMessage( SM_BackFromTickcountChange ); AutoScreenMessage( SM_BackFromComboChange ); AutoScreenMessage( SM_BackFromLabelChange ); AutoScreenMessage( SM_BackFromWarpChange ); +AutoScreenMessage( SM_DoEraseStepTiming ); AutoScreenMessage( SM_DoSaveAndExit ); AutoScreenMessage( SM_DoExit ); AutoScreenMessage( SM_SaveSuccessful ); @@ -575,6 +576,7 @@ static MenuDef g_TimingDataInformation( MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::combo, "Edit combo", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ) + MenuRowDef( ScreenEdit::erase_step_timing, "Erase step timing", true, EditMode_Full, true, true, 0, NULL ) ); enum { song_bganimation, song_movie, song_bitmap, global_bganimation, global_movie, global_movie_song_group, global_movie_song_group_and_genre, dynamic_random, baked_random, none }; @@ -2943,6 +2945,15 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) SetDirty( false ); } } + else if( SM == SM_DoEraseSplitTiming ) + { + if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) + { + SaveUndo(); + m_pSteps->m_Timing = m_pSong->m_SongTiming; + SetDirty( true ); + } + } else if( SM == SM_DoSaveAndExit ) // just asked "save before exiting? yes, no, cancel" { switch( ScreenPrompt::s_LastAnswer ) @@ -3893,6 +3904,7 @@ static LocalizedString ENTER_TICKCOUNT_VALUE ( "ScreenEdit", "Enter a new Tick static LocalizedString ENTER_COMBO_VALUE ( "ScreenEdit", "Enter a new Combo value." ); static LocalizedString ENTER_LABEL_VALUE ( "ScreenEdit", "Enter a new Label value." ); static LocalizedString ENTER_WARP_VALUE ( "ScreenEdit", "Enter a new Warp value." ); +static LocalizedString CONFIRM_TIMING_ERASE ( "ScreenEdit", "Are you sure you want to erase this chart's timing data?" ); void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice c, const vector &iAnswers ) { switch( c ) @@ -3974,6 +3986,8 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ssprintf( "%.4f", GetAppropriateTiming().GetWarpAtBeat( GetBeat() ) ), 10 ); + case erase_step_timing: + ScreenPrompt::Prompt( SM_DoEraseStepTiming, CONFIRM_TIMING_ERASE , PROMPT_YES_NO, ANSWER_NO ); break; } } diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 68a2353a83..68eabff5f5 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -496,6 +496,7 @@ public: tickcount, combo, warp, + erase_step_timing, NUM_TIMING_DATA_INFORMATION_CHOICES }; From cc27332f9c1848d247c3686e72206b81eeaa9567 Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sat, 14 May 2011 00:57:20 -0500 Subject: [PATCH 086/197] [splittiming] add some missing strings to en.ini --- Themes/_fallback/Languages/en.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 85147d8920..beb4ac939d 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -854,6 +854,7 @@ Edit label=Edit label Edit warp=Edit warp Editor options=Options EditorShowBGChangesPlay=Show Backgrounds +Erase step timing=Erase step timing Effect=Effect EnableAttackSounds=Attack Sounds EnableMineHitSound=Mine Sounds @@ -1226,6 +1227,7 @@ Enter a new Tickcount value.=Enter a new Tickcount value. Enter a new Combo value.=Enter a new Combo value. Enter a new Label value.=Enter a name for this section of the chart. Enter a new Warp value.=Enter the beat you will warp to when you reach this point. +Are you sure you want to erase this chart's timing data?=Are you sure you want to erase this chart's timing data? Enter a new artist transliteration.=Enter a new artist transliteration. Enter a new artist.=Enter a new artist. Enter a new genre.=Enter a new genre. From a70f087b0ca5ab5bebf6a23c2a7031468662b93c Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 02:14:00 -0400 Subject: [PATCH 087/197] [splittiming] Mino typoes. --- src/ScreenEdit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 569d631549..4fdec6b864 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -575,7 +575,7 @@ static MenuDef g_TimingDataInformation( MenuRowDef( ScreenEdit::label, "Edit label", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::combo, "Edit combo", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ) + MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::erase_step_timing, "Erase step timing", true, EditMode_Full, true, true, 0, NULL ) ); @@ -2945,7 +2945,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) SetDirty( false ); } } - else if( SM == SM_DoEraseSplitTiming ) + else if( SM == SM_DoEraseStepTiming ) { if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) { From fb0fb41ac233c75988fb1fda7f2d0b1ee14c7cc0 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Sat, 14 May 2011 21:35:43 +0700 Subject: [PATCH 088/197] initialize m_bIsEditorStepTiming with true, to be sure. --- src/GameState.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index 4a521e1ebb..88a090e8c5 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -128,7 +128,7 @@ GameState::GameState() : m_stEditSource( Message_EditSourceStepsTypeChanged ), m_iEditCourseEntryIndex( Message_EditCourseEntryIndexChanged ), m_sEditLocalProfileID( Message_EditLocalProfileIDChanged ), - m_bIsEditorStepTiming( false ) + m_bIsEditorStepTiming( true ) { g_pImpl = new GameStateImpl; From 682d679349aafbecca5debb025d18f8eee346b33 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 12:44:59 -0400 Subject: [PATCH 089/197] [splittiming] Versus scoring fix...wait. This is in the wrong branch. Transplant time! --- Themes/_fallback/Scripts/04 Scoring.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Themes/_fallback/Scripts/04 Scoring.lua b/Themes/_fallback/Scripts/04 Scoring.lua index 1c8c8df8b5..120177cd4d 100644 --- a/Themes/_fallback/Scripts/04 Scoring.lua +++ b/Themes/_fallback/Scripts/04 Scoring.lua @@ -89,11 +89,14 @@ r['DDR Extreme'] = function(params, pss) local totalItems = GetTotalItems(radarValues); local singleStep = (1 + totalItems) * totalItems / 2; if (not Shared.CurrentStep) then - Shared.CurrentStep = 0 + Shared.CurrentStep = {}; + Shared.CurrentStep["P1"] = 0; + Shared.CurrentStep["P2"] = 0; end; - Shared.CurrentStep = Shared.CurrentStep + 1; + local pn = PlayerNumberToString(params.Player); + Shared.CurrentStep[pn] = Shared.CurrentStep[pn] + 1; local stepValue = math.floor(baseScore /singleStep); - local stepLast = stepValue * Shared.CurrentStep; + local stepLast = stepValue * Shared.CurrentStep[pn]; pss:SetCurMaxScore(pss:GetCurMaxScore() + (stepLast * judgmentBase['TapNoteScore_W1'])); local judgeScore = 0; @@ -107,9 +110,9 @@ r['DDR Extreme'] = function(params, pss) end; local stepScore = judgeScore * stepLast; pss:SetScore(pss:GetScore() + stepScore); - if (Shared.CurrentStep >= totalItems) then -- Just in case. + if (Shared.CurrentStep[pn] >= totalItems) then -- Just in case. -- TODO: Implement the bonus for the last step? - Shared.CurrentStep = 0; -- Reset for the next song. + Shared.CurrentStep[pn] = 0; -- Reset for the next song. end; end; ----------------------------------------------------------- From a5be839174d9be95f595492fdae8a267314f3cb8 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 13:33:12 -0400 Subject: [PATCH 090/197] [splittiming] Missed a break. --- src/ScreenEdit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 4fdec6b864..e6d2b477e8 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3986,6 +3986,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ssprintf( "%.4f", GetAppropriateTiming().GetWarpAtBeat( GetBeat() ) ), 10 ); + break; case erase_step_timing: ScreenPrompt::Prompt( SM_DoEraseStepTiming, CONFIRM_TIMING_ERASE , PROMPT_YES_NO, ANSWER_NO ); break; From 018b5152739ecc98ab5ef7dd4d146eba7f23d41a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 16:56:50 -0400 Subject: [PATCH 091/197] [splittiming] Abstract, minor cleanup on SMA. Time we get this format properly supported. --- src/NotesLoaderSM.cpp | 47 +++++++++++++++++-------------- src/NotesLoaderSM.h | 2 ++ src/NotesLoaderSMA.cpp | 63 +++++++++++++++--------------------------- src/NotesLoaderSSC.cpp | 22 +-------------- 4 files changed, 51 insertions(+), 83 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 280063f1b6..a71fa80a1a 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -103,6 +103,31 @@ bool SMLoader::LoadTimingFromFile( const RString &fn, TimingData &out ) return true; } +void SMLoader::ProcessBGChanges( Song &out, const RString &sValueName, const RString &sPath, const RString &sParam ) +{ + BackgroundLayer iLayer = BACKGROUND_LAYER_1; + if( sscanf(sValueName, "BGCHANGES%d", &*ConvertValue(&iLayer)) == 1 ) + enum_add(iLayer, -1); // #BGCHANGES2 = BACKGROUND_LAYER_2 + + bool bValid = iLayer>=0 && iLayerUserLog( "Song file", sPath, "has a #BGCHANGES tag \"%s\" that is out of range.", sValueName.c_str() ); + } + else + { + vector aBGChangeExpressions; + split( sParam, ",", aBGChangeExpressions ); + + for( unsigned b=0; b arrayBPMChangeExpressions; @@ -632,27 +657,7 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache else if( sValueName.Left(strlen("BGCHANGES"))=="BGCHANGES" || sValueName=="ANIMATIONS" ) { - BackgroundLayer iLayer = BACKGROUND_LAYER_1; - if( sscanf(sValueName, "BGCHANGES%d", &*ConvertValue(&iLayer)) == 1 ) - enum_add(iLayer, -1); // #BGCHANGES2 = BACKGROUND_LAYER_2 - - bool bValid = iLayer>=0 && iLayerUserLog( "Song file", sPath, "has a #BGCHANGES tag \"%s\" that is out of range.", sValueName.c_str() ); - } - else - { - vector aBGChangeExpressions; - split( sParams[1], ",", aBGChangeExpressions ); - - for( unsigned b=0; b aFileNames; + GetApplicableFiles( sPath, aFileNames ); + + if( aFileNames.size() > 1 ) + { + LOG->UserLog( "Song", sPath, "has more than one SMA file. Only one SMA file is allowed per song." ); + return false; + } + ASSERT( aFileNames.size() == 1 ); + return LoadFromSMAFile( sPath + aFileNames[0], out ); +} + void SMALoader::LoadFromSMATokens( RString sStepsType, RString sDescription, @@ -83,20 +104,6 @@ void SMALoader::LoadFromSMATokens( out.TidyUpData(); } -bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) -{ - vector aFileNames; - GetApplicableFiles( sPath, aFileNames ); - - if( aFileNames.size() > 1 ) - { - LOG->UserLog( "Song", sPath, "has more than one SMA file. There can be only one!" ); - return false; - } - ASSERT( aFileNames.size() == 1 ); - return LoadFromSMAFile( sPath + aFileNames[0], out ); -} - void SMALoader::TidyUpData( Song &song, bool bFromCache ) { SMLoader::TidyUpData( song, bFromCache ); @@ -265,27 +272,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) else if( sValueName.Left(strlen("BGCHANGES"))=="BGCHANGES" || sValueName=="ANIMATIONS" ) { - BackgroundLayer iLayer = BACKGROUND_LAYER_1; - if( sscanf(sValueName, "BGCHANGES%d", &*ConvertValue(&iLayer)) == 1 ) - enum_add(iLayer, -1); // #BGCHANGES2 = BACKGROUND_LAYER_2 - - bool bValid = iLayer>=0 && iLayerUserLog( "Song file", sPath, "has a #BGCHANGES tag \"%s\" that is out of range.", sValueName.c_str() ); - } - else - { - vector aBGChangeExpressions; - split( sParams[1], ",", aBGChangeExpressions ); - - for( unsigned b=0; b(&iLayer)) == 1 ) - enum_add(iLayer, -1); // #BGCHANGES2 = BACKGROUND_LAYER_2 - - bool bValid = iLayer>=0 && iLayerUserLog( "Song file", sPath, "has a #BGCHANGES tag \"%s\" that is out of range.", sValueName.c_str() ); - } - else - { - vector aBGChangeExpressions; - split( sParams[1], ",", aBGChangeExpressions ); - - for( unsigned b=0; b Date: Sat, 14 May 2011 17:24:18 -0400 Subject: [PATCH 092/197] [splittiming] Abstract unused(?) #ATTACKS. --- src/NotesLoaderSM.cpp | 87 ++++++++++++++++++++++-------------------- src/NotesLoaderSM.h | 3 +- src/NotesLoaderSMA.cpp | 42 +------------------- src/NotesLoaderSSC.cpp | 42 +------------------- 4 files changed, 50 insertions(+), 124 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index a71fa80a1a..9e980aac14 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -128,6 +128,51 @@ void SMLoader::ProcessBGChanges( Song &out, const RString &sValueName, const RSt } } +void SMLoader::ProcessAttacks( Song &out, MsdFile::value_t sParams ) +{ + // Build the RString vector here so we can write it to file again later + for( unsigned s=1; s < sParams.params.size(); ++s ) + out.m_sAttackString.push_back( sParams[s] ); + + Attack attack; + float end = -9999; + + for( unsigned j=1; j < sParams.params.size(); ++j ) + { + vector sBits; + split( sParams[j], "=", sBits, false ); + + // Need an identifer and a value for this to work + if( sBits.size() < 2 ) + continue; + + TrimLeft( sBits[0] ); + TrimRight( sBits[0] ); + + if( !sBits[0].CompareNoCase("TIME") ) + attack.fStartSecond = strtof( sBits[1], NULL ); + else if( !sBits[0].CompareNoCase("LEN") ) + attack.fSecsRemaining = strtof( sBits[1], NULL ); + else if( !sBits[0].CompareNoCase("END") ) + end = strtof( sBits[1], NULL ); + else if( !sBits[0].CompareNoCase("MODS") ) + { + attack.sModifiers = sBits[1]; + + if( end != -9999 ) + { + attack.fSecsRemaining = end - attack.fStartSecond; + end = -9999; + } + + if( attack.fSecsRemaining < 0.0f ) + attack.fSecsRemaining = 0.0f; + + out.m_Attacks.push_back( attack ); + } + } +} + bool SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) { vector arrayBPMChangeExpressions; @@ -681,47 +726,7 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache // Attacks loaded from file else if( sValueName=="ATTACKS" ) { - // Build the RString vector here so we can write it to file again later - for( unsigned s=1; s < sParams.params.size(); ++s ) - out.m_sAttackString.push_back( sParams[s] ); - - Attack attack; - float end = -9999; - - for( unsigned j=1; j < sParams.params.size(); ++j ) - { - vector sBits; - split( sParams[j], "=", sBits, false ); - - // Need an identifer and a value for this to work - if( sBits.size() < 2 ) - continue; - - TrimLeft( sBits[0] ); - TrimRight( sBits[0] ); - - if( !sBits[0].CompareNoCase("TIME") ) - attack.fStartSecond = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("LEN") ) - attack.fSecsRemaining = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("END") ) - end = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("MODS") ) - { - attack.sModifiers = sBits[1]; - - if( end != -9999 ) - { - attack.fSecsRemaining = end - attack.fStartSecond; - end = -9999; - } - - if( attack.fSecsRemaining < 0.0f ) - attack.fSecsRemaining = 0.0f; - - out.m_Attacks.push_back( attack ); - } - } + ProcessAttacks( out, sParams ); } else if( sValueName=="NOTES" || sValueName=="NOTES2" ) diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 636df83f43..b6bc97cd60 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -3,8 +3,8 @@ #include "GameConstantsAndTypes.h" #include "BackgroundUtil.h" +#include "MsdFile.h" // we require the struct from here. -class MsdFile; class Song; class Steps; class TimingData; @@ -34,6 +34,7 @@ namespace SMLoader void ProcessTickcounts( TimingData &, const RString ); void ProcessBGChanges( Song &out, const RString &sValueName, const RString &sPath, const RString &sParam ); + void ProcessAttacks( Song &out, MsdFile::value_t sParams ); } #endif diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index f8bd8ba970..6fe8620bf3 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -296,47 +296,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) // Attacks loaded from file else if( sValueName=="ATTACKS" ) { - // Build the RString vector here so we can write it to file again later - for( unsigned s=1; s < sParams.params.size(); ++s ) - out.m_sAttackString.push_back( sParams[s] ); - - Attack attack; - float end = -9999; - - for( unsigned j=1; j < sParams.params.size(); ++j ) - { - vector sBits; - split( sParams[j], "=", sBits, false ); - - // Need an identifer and a value for this to work - if( sBits.size() < 2 ) - continue; - - TrimLeft( sBits[0] ); - TrimRight( sBits[0] ); - - if( !sBits[0].CompareNoCase("TIME") ) - attack.fStartSecond = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("LEN") ) - attack.fSecsRemaining = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("END") ) - end = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("MODS") ) - { - attack.sModifiers = sBits[1]; - - if( end != -9999 ) - { - attack.fSecsRemaining = end - attack.fStartSecond; - end = -9999; - } - - if( attack.fSecsRemaining < 0.0f ) - attack.fSecsRemaining = 0.0f; - - out.m_Attacks.push_back( attack ); - } - } + SMLoader::ProcessAttacks( out, sParams ); } else if( sValueName=="NOTES" || sValueName=="NOTES2" ) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 1dd82798a3..d50942c74d 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -335,47 +335,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach // Attacks loaded from file else if( sValueName=="ATTACKS" ) { - // Build the RString vector here so we can write it to file again later - for( unsigned s=1; s < sParams.params.size(); ++s ) - out.m_sAttackString.push_back( sParams[s] ); - - Attack attack; - float end = -9999; - - for( unsigned j=1; j < sParams.params.size(); ++j ) - { - vector sBits; - split( sParams[j], "=", sBits, false ); - - // Need an identifer and a value for this to work - if( sBits.size() < 2 ) - continue; - - TrimLeft( sBits[0] ); - TrimRight( sBits[0] ); - - if( !sBits[0].CompareNoCase("TIME") ) - attack.fStartSecond = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("LEN") ) - attack.fSecsRemaining = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("END") ) - end = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("MODS") ) - { - attack.sModifiers = sBits[1]; - - if( end != -9999 ) - { - attack.fSecsRemaining = end - attack.fStartSecond; - end = -9999; - } - - if( attack.fSecsRemaining < 0.0f ) - attack.fSecsRemaining = 0.0f; - - out.m_Attacks.push_back( attack ); - } - } + SMLoader::ProcessAttacks( out, sParams ); } else if( sValueName=="OFFSET" ) From 9196c695774a51382e9cda4ad41e4fa91ac6af9b Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 17:34:22 -0400 Subject: [PATCH 093/197] [splittiming] Temp breakage for parsing. Going to do this the SSC way, because that's how we roll. --- src/NotesLoaderSMA.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 0fceb3977d..94d6ae9dbb 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -9,6 +9,16 @@ class Song; class Steps; class TimingData; +/** + * @brief The various states while parsing a .sma file. + */ +enum SMALoadingStates +{ + SMA_GETTING_SONG_INFO, /**< Retrieving song information. */ + SMA_GETTING_STEP_INFO, /**< Retrieving step information. */ + NUM_SMALoadingStates /**< The number of states used. */ +}; + /** @brief Reads a Song from a .SMA file. */ namespace SMALoader { @@ -25,8 +35,7 @@ namespace SMALoader bool LoadFromSMAFile( const RString &sPath, Song &out ); void GetApplicableFiles( const RString &sPath, vector &out ); - bool LoadTimingFromFile( const RString &fn, TimingData &out ); - void LoadTimingFromSMAFile( const MsdFile &msd, TimingData &out ); + bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); From 4b89c0fae76025e833f738a257ab2bd680a29fad Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 17:41:08 -0400 Subject: [PATCH 094/197] [splittiming] Abstraction, prep work. --- src/NotesLoaderSM.cpp | 31 ++++++++++++++++++------------- src/NotesLoaderSM.h | 1 + src/NotesLoaderSMA.cpp | 22 +++++++--------------- src/NotesLoaderSSC.cpp | 14 +------------- 4 files changed, 27 insertions(+), 41 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 9e980aac14..80d56ee33f 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -173,6 +173,23 @@ void SMLoader::ProcessAttacks( Song &out, MsdFile::value_t sParams ) } } +void SMLoader::ProcessInstrumentTracks( Song &out, const RString &sParam ) +{ + vector vs1; + split( sParam, ",", vs1 ); + FOREACH_CONST( RString, vs1, s ) + { + vector vs2; + split( *s, "=", vs2 ); + if( vs2.size() >= 2 ) + { + InstrumentTrack it = StringToInstrumentTrack( vs2[0] ); + if( it != InstrumentTrack_Invalid ) + out.m_sInstrumentTrackFile[it] = vs2[1]; + } + } +} + bool SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) { vector arrayBPMChangeExpressions; @@ -597,19 +614,7 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache else if( sValueName=="INSTRUMENTTRACK" ) { - vector vs1; - split( sParams[1], ",", vs1 ); - FOREACH_CONST( RString, vs1, s ) - { - vector vs2; - split( *s, "=", vs2 ); - if( vs2.size() >= 2 ) - { - InstrumentTrack it = StringToInstrumentTrack( vs2[0] ); - if( it != InstrumentTrack_Invalid ) - out.m_sInstrumentTrackFile[it] = vs2[1]; - } - } + ProcessInstrumentTracks( out, sParams[1] ); } else if( sValueName=="MUSICLENGTH" ) diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index b6bc97cd60..8628d7dde2 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -35,6 +35,7 @@ namespace SMLoader void ProcessBGChanges( Song &out, const RString &sValueName, const RString &sPath, const RString &sParam ); void ProcessAttacks( Song &out, MsdFile::value_t sParams ); + void ProcessInstrumentTracks( Song &out, const RString &sParam ); } #endif diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 6fe8620bf3..ec6a8deb6f 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -120,8 +120,12 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) return false; } - out.m_SongTiming.m_sFile = sPath; - LoadTimingFromSMAFile( msd, out.m_SongTiming ); + out.m_SongTiming.m_sFile = sPath; // songs still have their fallback timing. + + int state = SMA_GETTING_SONG_INFO; + Steps* pNewNotes = NULL; + TimingData stepsTiming; + int iRowsPerBeat = -1; // Start with an invalid value: needed for checking. for( unsigned i=0; i vs1; - split( sParams[1], ",", vs1 ); - FOREACH_CONST( RString, vs1, s ) - { - vector vs2; - split( *s, "=", vs2 ); - if( vs2.size() >= 2 ) - { - InstrumentTrack it = StringToInstrumentTrack( vs2[0] ); - if( it != InstrumentTrack_Invalid ) - out.m_sInstrumentTrackFile[it] = vs2[1]; - } - } + SMLoader::ProcessInstrumentTracks( out, sParams[1] ); } else if( sValueName=="MUSICLENGTH" ) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index d50942c74d..abb5a72adf 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -232,19 +232,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach else if( sValueName=="INSTRUMENTTRACK" ) { - vector vs1; - split( sParams[1], ",", vs1 ); - FOREACH_CONST( RString, vs1, s ) - { - vector vs2; - split( *s, "=", vs2 ); - if( vs2.size() >= 2 ) - { - InstrumentTrack it = StringToInstrumentTrack( vs2[0] ); - if( it != InstrumentTrack_Invalid ) - out.m_sInstrumentTrackFile[it] = vs2[1]; - } - } + SMLoader::ProcessInstrumentTracks( out, sParams[1] ); } else if( sValueName=="MUSICLENGTH" ) From 6b0a9392908ffed50f18d29a37ecea2e8d4cbfc8 Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sat, 14 May 2011 17:03:49 -0500 Subject: [PATCH 095/197] [splittiming] new EffectModes (not available from Lua yet), clarified error message --- src/Actor.cpp | 16 ++++++++++++++++ src/Actor.h | 4 ++++ src/GameState.cpp | 2 ++ src/SongPosition.cpp | 2 +- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Actor.cpp b/src/Actor.cpp index 72a3ee3856..42b5eae89b 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -68,6 +68,12 @@ void Actor::SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBe g_fCurrentBGMBeatNoOffset = fBeatNoOffset; } +void Actor::SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset ) +{ + g_vfCurrentBGMBeatPlayer[pn] = fBeat; + g_vfCurrentBGMBeatPlayerNoOffset[pn] = fBeatNoOffset; +} + void Actor::SetBGMLight( int iLightNumber, float fCabinetLights ) { ASSERT( iLightNumber < NUM_CabinetLight ); @@ -675,6 +681,16 @@ void Actor::UpdateInternal( float fDeltaTime ) m_fEffectDelta = g_fCurrentBGMBeat - m_fSecsIntoEffect; m_fSecsIntoEffect = g_fCurrentBGMBeat; break; + + case CLOCK_BGM_BEAT_PLAYER1: + m_fEffectDelta = g_vfCurrentBGMBeat[PlayerNumber_P1] - m_fSecsIntoEffect; + m_fSecsIntoEffect = g_vfCurrentBGMBeat[PlayerNumber_P1]; + break; + + case CLOCK_BGM_BEAT_PLAYER2: + m_fEffectDelta = g_vfCurrentBGMBeat[PlayerNumber_P2] - m_fSecsIntoEffect; + m_fSecsIntoEffect = g_vfCurrentBGMBeat[PlayerNumber_P2]; + break; case CLOCK_BGM_TIME: m_fEffectDelta = g_fCurrentBGMTime - m_fSecsIntoEffect; diff --git a/src/Actor.h b/src/Actor.h index 45d080dabe..91634a7649 100644 --- a/src/Actor.h +++ b/src/Actor.h @@ -109,6 +109,7 @@ public: virtual void LoadFromNode( const XNode* pNode ); static void SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBeatNoOffset ); + static void SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset ); static void SetBGMLight( int iLightNumber, float fCabinetLights ); /** @@ -131,6 +132,8 @@ public: CLOCK_BGM_BEAT, CLOCK_BGM_TIME_NO_OFFSET, CLOCK_BGM_BEAT_NO_OFFSET, + CLOCK_BGM_BEAT_PLAYER1, + CLOCK_BGM_BEAT_PLAYER2, CLOCK_LIGHT_1 = 1000, CLOCK_LIGHT_LAST = 1100, NUM_CLOCKS @@ -713,6 +716,7 @@ protected: // global state static float g_fCurrentBGMTime, g_fCurrentBGMBeat; static float g_fCurrentBGMTimeNoOffset, g_fCurrentBGMBeatNoOffset; + static vector g_vfCurrentBGMBeatPlayer, g_vfCurrentBGMBeatPlayerNoOffset; private: // commands diff --git a/src/GameState.cpp b/src/GameState.cpp index 88a090e8c5..3f26469494 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -949,7 +949,9 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti if( bUpdatePlayers ) FOREACH_EnabledPlayer( pn ) if( m_pCurSteps[pn] ) + { m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); + Actor::SetPlayerBGMBeat( pn, m_pPlayerState[pn]->m_Position.m_fSongBeatVisible, m_pPlayerState[pn]->m_Position.m_fSongBeatNoOffset ); Actor::SetBGMTime( GAMESTATE->m_Position.m_fMusicSecondsVisible, GAMESTATE->m_Position.m_fSongBeatVisible, fPositionSeconds, GAMESTATE->m_Position.m_fSongBeatNoOffset ); // LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze ); diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp index 79e925658f..bcfee26f80 100644 --- a/src/SongPosition.cpp +++ b/src/SongPosition.cpp @@ -20,7 +20,7 @@ void SongPosition::UpdateSongPosition( float fPositionSeconds, const TimingData timing.GetBeatAndBPSFromElapsedTime( fPositionSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze, m_bDelay, m_iWarpBeginRow, m_fWarpDestination ); // "Crash reason : -243478.890625 -48695.773438" - ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds", m_fSongBeat, fPositionSeconds) ); + ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds is less than -2000!", m_fSongBeat, fPositionSeconds) ); m_fMusicSeconds = fPositionSeconds; From 1349350eb261c607e40ae29218990cc05a7ec30f Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 18:04:11 -0400 Subject: [PATCH 096/197] [splittiming] Minor update. --- src/NotesLoaderSM.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 80d56ee33f..598c0d40ff 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -381,10 +381,7 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString sParam ) 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] ); + TimeSignatureSegment seg( BeatToNoteRow( fBeat ), StringToInt( vs2[1] ), StringToInt( vs2[2] )); if( fBeat < 0 ) { From 11c4c2fd03e32904a96234910954dbfa9ad08301 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 18:04:31 -0400 Subject: [PATCH 097/197] [splittiming] Another tag or two. --- src/NotesLoaderSMA.cpp | 107 ++++++++++++++++++++++++++++------------- src/NotesLoaderSMA.h | 2 + 2 files changed, 76 insertions(+), 33 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index ec6a8deb6f..8890f7cfe3 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -39,6 +39,42 @@ bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) return LoadFromSMAFile( sPath + aFileNames[0], out ); } +void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) +{ + vector vs1; + split( sParam, ",", vs1 ); + + FOREACH_CONST( RString, vs1, s1 ) + { + vector vs2; + split( *s1, "=", vs2 ); + + if( vs2.size() < 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid beats per measure change with %i values.", (int)vs2.size() ); + continue; + } + + const float fBeat = StringToFloat( vs2[0] ); + + TimeSignatureSegment seg( BeatToNoteRow( fBeat ), StringToInt( vs2[1] ), StringToInt( 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; + } + + out.AddTimeSignatureSegment( seg ); + } +} + void SMALoader::LoadFromSMATokens( RString sStepsType, RString sDescription, @@ -201,7 +237,8 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) } else if( sValueName=="LASTBEAT" ) { - ; } + ; + } else if( sValueName=="SONGFILENAME" ) { ; @@ -241,6 +278,41 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) } } + else if( sValueName=="SMAVERSION" ) + { + ; // ignore it. + } + + else if( sValueName=="ROWSPERBEAT" ) + { + /* This value is used to help translate the timings + * the SMA format uses. Starting with the second + * appearance, it delimits NoteData. Right now, this + * value doesn't seem to be editable in SMA. When it + * becomes so, make adjustments to this code. */ + if( iRowsPerBeat < 0 ) + { + vector arrayBeatChangeExpressions; + split( sParams[1], ",", arrayBeatChangeExpressions ); + + vector arrayBeatChangeValues; + split( arrayBeatChangeExpressions[0], "=", arrayBeatChangeValues ); + iRowsPerBeat = StringToInt(arrayBeatChangeValues[1]); + } + else + { + state = SMA_GETTING_STEP_INFO; + // start again. + } + } + + else if( sValueName=="BEATSPERMEASURE" ) + { + TimingData &timing = (state == SMA_GETTING_STEP_INFO + ? pNewNotes->m_Timing : out.m_SongTiming); + ProcessBeatsPerMeasure( timing, sParams[1] ); + } + else if( sValueName=="SELECTABLE" ) { if(sParams[1].EqualsNoCase("YES")) @@ -329,20 +401,6 @@ void SMALoader::GetApplicableFiles( const RString &sPath, vector &out ) GetDirListing( sPath + RString("*.sma"), out ); } -bool SMALoader::LoadTimingFromFile( const RString &fn, TimingData &out ) -{ - MsdFile msd; - if( !msd.ReadFile( fn, true ) ) // unescape - { - LOG->UserLog( "Song file", fn, "couldn't be loaded: %s", msd.GetError().c_str() ); - return false; - } - - out.m_sFile = fn; - LoadTimingFromSMAFile( msd, out ); - return true; -} - void SMALoader::LoadTimingFromSMAFile( const MsdFile &msd, TimingData &out ) { out.m_fBeat0OffsetInSeconds = 0; @@ -362,24 +420,7 @@ void SMALoader::LoadTimingFromSMAFile( const MsdFile &msd, TimingData &out ) RString sValueName = sParams[0]; sValueName.MakeUpper(); - if( sValueName=="ROWSPERBEAT") - { - if( encountered ) - { - break; - } - encountered = true; - rowsPerMeasure = StringToInt( sParams[1] ); - } - else if( sValueName=="BEATSPERMEASURE" ) - { - TimeSignatureSegment new_seg; - new_seg.m_iStartRow = 0; - new_seg.m_iNumerator = StringToInt( sParams[1] ); - new_seg.m_iDenominator = 4; - out.AddTimeSignatureSegment( new_seg ); - } - else if( sValueName=="OFFSET" ) + if( sValueName=="OFFSET" ) { out.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] ); } diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 94d6ae9dbb..4d59e79f0a 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -40,6 +40,8 @@ namespace SMALoader bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ); + + void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); }; #endif From 3ac85df29fdc3eee2b378cc7ef0aaa7b36f6574f Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sat, 14 May 2011 17:12:27 -0500 Subject: [PATCH 098/197] [splittiming] some. times in our lives. we all have pains. we all have sorrow --- src/Actor.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Actor.h b/src/Actor.h index 91634a7649..deb9ba3716 100644 --- a/src/Actor.h +++ b/src/Actor.h @@ -5,6 +5,7 @@ #include "RageUtil_AutoPtr.h" #include "LuaReference.h" #include "EnumHelper.h" +#include "PlayerNumber.h" #include class XNode; struct lua_State; From efb37b47d7c4dce5fe8231a098864f0bdb3b79be Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 18:17:48 -0400 Subject: [PATCH 099/197] [splittiming] Hey FSX, catch! --- src/GameState.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index 3f26469494..8205d4143f 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -947,12 +947,16 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti m_Position.UpdateSongPosition( fPositionSeconds, timing, timestamp ); if( bUpdatePlayers ) + { FOREACH_EnabledPlayer( pn ) + { if( m_pCurSteps[pn] ) { m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); Actor::SetPlayerBGMBeat( pn, m_pPlayerState[pn]->m_Position.m_fSongBeatVisible, m_pPlayerState[pn]->m_Position.m_fSongBeatNoOffset ); - + } + } + } Actor::SetBGMTime( GAMESTATE->m_Position.m_fMusicSecondsVisible, GAMESTATE->m_Position.m_fSongBeatVisible, fPositionSeconds, GAMESTATE->m_Position.m_fSongBeatNoOffset ); // LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze ); } From 2652a7c10b18bdbbc49221c8f207297b92d461a9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 18:22:36 -0400 Subject: [PATCH 100/197] [splittiming] #OFFSET done. Now for the rest. --- src/NotesLoaderSMA.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 8890f7cfe3..9e9d2ab7b6 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -262,6 +262,11 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) //else if( sValueName=="SAMPLEPATH" ) //out.m_sMusicSamplePath = sParams[1]; + else if( sValueName=="LISTSORT" ) + { + ; + } + else if( sValueName=="DISPLAYBPM" ) { // #DISPLAYBPM:[xxx][xxx:xxx]|[*]; @@ -302,7 +307,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) else { state = SMA_GETTING_STEP_INFO; - // start again. + pNewNotes = out.CreateSteps(); } } @@ -352,6 +357,15 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) } } + else if( sValueName=="OFFSET" ) + { + TimingData &timing = (state == SMA_GETTING_STEP_INFO + ? pNewNotes->m_Timing : out.m_SongTiming); + timing.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] ); + } + + + else if( sValueName=="KEYSOUNDS" ) { split( sParams[1], ",", out.m_vsKeysoundFile ); @@ -371,7 +385,6 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) continue; } - Steps* pNewNotes = out.CreateSteps(); LoadFromSMATokens( sParams[1], sParams[2], @@ -387,7 +400,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) * We used to check for timing data in this section. That has * since been moved to a dedicated function. */ - else if( sValueName=="OFFSET" || sValueName=="BPMS" || sValueName=="STOPS" || sValueName=="FREEZES" || sValueName=="DELAYS" || sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" || sValueName=="TICKCOUNTS" ) + else if( sValueName=="BPMS" || sValueName=="STOPS" || sValueName=="FREEZES" || sValueName=="DELAYS" || sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" || sValueName=="TICKCOUNTS" ) ; else LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() ); @@ -420,11 +433,7 @@ void SMALoader::LoadTimingFromSMAFile( const MsdFile &msd, TimingData &out ) RString sValueName = sParams[0]; sValueName.MakeUpper(); - if( sValueName=="OFFSET" ) - { - out.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] ); - } - else if( sValueName=="STOPS" ) + if( sValueName=="STOPS" ) { vector arrayFreezeExpressions; split( sParams[1], ",", arrayFreezeExpressions ); From 0464a86faf722a29695d74634d762debd7409280 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 18:36:46 -0400 Subject: [PATCH 101/197] [splittiming] More progress. --- src/NotesLoaderSM.cpp | 9 +- src/NotesLoaderSM.h | 7 ++ src/NotesLoaderSMA.cpp | 196 +++++++++++++++++++---------------------- src/NotesLoaderSMA.h | 3 + 4 files changed, 103 insertions(+), 112 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 598c0d40ff..360ceaf111 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -15,11 +15,6 @@ /** @brief The maximum file size for edits. */ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60KB -/** - * @brief The highest allowable speed before Warps come in. - * - * This was brought in from StepMania 4's recent betas. */ -const float FAST_BPM_WARP = 9999999.f; void SMLoader::LoadFromSMTokens( RString sStepsType, @@ -251,9 +246,7 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) highspeedBeat = -1; } { - BPMSegment new_seg; - new_seg.m_iStartRow = BeatToNoteRow(fBeat); - new_seg.SetBPM( fNewBPM ); + BPMSegment new_seg( BeatToNoteRow( fBeat ), fNewBPM ); out.AddBPMSegment( new_seg ); } } diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 8628d7dde2..d1c4feded0 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -8,6 +8,13 @@ class Song; class Steps; class TimingData; + +/** + * @brief The highest allowable speed before Warps come in. + * + * This was brought in from StepMania 4's recent betas. */ +const float FAST_BPM_WARP = 9999999.f; + /** @brief Reads a Song from an .SM file. */ namespace SMLoader { diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 9e9d2ab7b6..0fd989a7b5 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -39,6 +39,91 @@ bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) return LoadFromSMAFile( sPath + aFileNames[0], out ); } +float SMALoader::RowToBeat( RString sLine, const int iRowsPerBeat ) +{ + if( sLine.Right(0).MakeUpper() == "R" ) + { + sLine = sLine.Left(sLine.size()-1); + return StringToFloat( sLine ) / iRowsPerBeat; + } + else + { + return StringToFloat( sLine ); + } +} + +bool SMALoader::ProcessBPMs( TimingData &out, const int iRowsPerBeat, const RString sParam ) +{ + vector arrayBPMChangeExpressions; + split( sParam, ",", arrayBPMChangeExpressions ); + + // prepare storage variables for negative BPMs -> Warps. + float negBeat = -1; + float negBPM = 1; + float highspeedBeat = -1; + bool bNotEmpty = false; + + for( unsigned b=0; b arrayBPMChangeValues; + split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); + // XXX: Hard to tell which file caused this. + if( arrayBPMChangeValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #BPMs value \"%s\" (must have exactly one '='), ignored.", + arrayBPMChangeExpressions[b].c_str() ); + continue; + } + + bNotEmpty = true; + + const float fBeat = RowToBeat( arrayBPMChangeValues[0], iRowsPerBeat ); + const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); + + if( fNewBPM < 0.0f ) + { + out.m_bHasNegativeBpms = true; + negBeat = fBeat; + negBPM = fNewBPM; + } + else if( fNewBPM > 0.0f ) + { + // add in a warp. + if( negBPM < 0 ) + { + float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat); + WarpSegment new_seg(negBeat, endBeat); + out.AddWarpSegment( new_seg ); + + negBeat = -1; + negBPM = 1; + } + // too fast. make it a warp. + if( fNewBPM > FAST_BPM_WARP ) + { + highspeedBeat = fBeat; + } + else + { + // add in a warp. + if( highspeedBeat > 0 ) + { + WarpSegment new_seg(highspeedBeat, fBeat); + out.AddWarpSegment( new_seg ); + highspeedBeat = -1; + } + { + BPMSegment new_seg( BeatToNoteRow( fBeat ), fNewBPM ); + out.AddBPMSegment( new_seg ); + } + } + } + } + + return bNotEmpty; +} + + void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) { vector vs1; @@ -364,7 +449,12 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) timing.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] ); } - + else if( sValueName=="BPMS" ) + { + TimingData &timing = (state == SMA_GETTING_STEP_INFO + ? pNewNotes->m_Timing : out.m_SongTiming); + ProcessBPMs( timing, iRowsPerBeat, sParams[1] ); + } else if( sValueName=="KEYSOUNDS" ) { @@ -400,7 +490,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) * We used to check for timing data in this section. That has * since been moved to a dedicated function. */ - else if( sValueName=="BPMS" || sValueName=="STOPS" || sValueName=="FREEZES" || sValueName=="DELAYS" || sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" || sValueName=="TICKCOUNTS" ) + else if( sValueName=="STOPS" || sValueName=="FREEZES" || sValueName=="DELAYS" || sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" || sValueName=="TICKCOUNTS" ) ; else LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() ); @@ -488,108 +578,6 @@ void SMALoader::LoadTimingFromSMAFile( const MsdFile &msd, TimingData &out ) } } - else if( sValueName=="BPMS" ) - { - vector arrayBPMChangeExpressions; - split( sParams[1], ",", arrayBPMChangeExpressions ); - - for( unsigned b=0; b 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; - } - - float fBeat = 0; - RString beat = arrayBPMChangeValues[0]; - if( beat.Right(0).MakeUpper() == "R" ) - { - beat = beat.Left(beat.size()-1); - fBeat = StringToFloat( beat ) / rowsPerMeasure; - } - else - { - fBeat = StringToFloat(beat); - } - - //float fBeat = StringToFloat( arrayBPMChangeValues[0] ); - const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); - // XXX: Remove Negatives Bug? - BPMSegment new_seg; - new_seg.m_iStartRow = BeatToNoteRow(fBeat); - new_seg.SetBPM( fNewBPM ); - - // convert negative BPMs into Warp segments - if( fNewBPM < 0.0f ) - { - vector arrayNextBPMChangeValues; - // get next bpm in sequence - if((b+1) < arrayBPMChangeExpressions.size()) - { - split( arrayBPMChangeExpressions[b+1], "=", arrayNextBPMChangeValues ); - const float fNextPositiveBeat = StringToFloat( arrayNextBPMChangeValues[0] ); - const float fNextPositiveBPM = StringToFloat( arrayNextBPMChangeValues[1] ); - - // tJumpPos = (tPosBPS-abs(negBPS)) + (gPosBPMPosition - fNegPosition) - float fDeltaBeat = ((fNextPositiveBPM/60.0f)-abs(fNewBPM/60.0f)) + (fNextPositiveBeat-fBeat); - //float fWarpLengthBeats = fNextPositiveBeat + fDeltaBeat; - WarpSegment wsTemp(BeatToNoteRow(fBeat),fDeltaBeat); - arrayWarpsFromNegativeBPMs.push_back(wsTemp); - - /* - LOG->Trace( ssprintf("==NotesLoSM negbpm==\nfnextposbeat = %f, fnextposbpm = %f,\nfdelta = %f, fwarpto = %f", - fNextPositiveBeat, - fNextPositiveBPM, - fDeltaBeat, - fWarpToBeat - ) ); - */ - /* - LOG->Trace( ssprintf("==Negative/Subtractive BPM in NotesLoader==\nNegBPM has noterow = %i, BPM = %f\nNextBPM @ noterow %i\nDelta value = %i noterows\nThis warp will have us end up at noterow %i", - BeatToNoteRow(fBeat), fNewBPM, - BeatToNoteRow(fNextPositiveBeat), - BeatToNoteRow(fDeltaBeat), - BeatToNoteRow(fWarpToBeat)) - ); - */ - //float fDeltaBeat = ((fNextPositiveBPM/60.0f)-abs(fNewBPM/60.0f)) + (fNextPositiveBeat-fBeat); - /* - LOG->Trace( ssprintf("==NotesLoader Delta as NoteRows==\nfDeltaBeat = %f (beat)\nfDeltaBeat = (NextBPMSeg %f - abs(fBPS %f)) + (nextStartRow %i - thisRow %i)", - fDeltaBeat,(fNextPositiveBPM/60.0f),abs(fNewBPM/60.0f),BeatToNoteRow(fNextPositiveBeat),BeatToNoteRow(fBeat)) - ); - */ - - out.AddBPMSegment( new_seg ); - - continue; - } - else - { - // last BPM is a negative one? ugh. -aj (MAX_NOTE_ROW exists btw) - out.AddBPMSegment( new_seg ); - } - } - - if(fNewBPM > 0.0f) - out.AddBPMSegment( new_seg ); - else - { - out.m_bHasNegativeBpms = true; - // only add Negative BPMs in quirks mode -aj - if( PREFSMAN->m_bQuirksMode ) - out.AddBPMSegment( new_seg ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM ); - } - } - } - - // Note: Even though it is possible to have Negative BPMs and Stops in // a song along with Warps, we should not support files that contain // both styles of warp tricks (Negatives vs. #WARPS). diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 4d59e79f0a..5c7300d133 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -42,6 +42,9 @@ namespace SMALoader bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ); void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); + bool ProcessBPMs( TimingData &out, const int iRowsPerBeat, const RString sParam ); + + float RowToBeat( RString sLine, const int iRowsPerBeat ); }; #endif From 725224863dfe7c875b2d0e3cac8b1fead6e47ae4 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 18:44:43 -0400 Subject: [PATCH 102/197] [splittiming] SMA stops and delays. --- src/NotesLoaderSMA.cpp | 208 ++++++++++++++++++++++------------------- src/NotesLoaderSMA.h | 2 + 2 files changed, 116 insertions(+), 94 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 0fd989a7b5..352def3295 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -123,6 +123,105 @@ bool SMALoader::ProcessBPMs( TimingData &out, const int iRowsPerBeat, const RStr return bNotEmpty; } +void SMALoader::ProcessStops( TimingData &out, const int iRowsPerBeat, const RString sParam ) +{ + vector arrayFreezeExpressions; + split( sParam, ",", arrayFreezeExpressions ); + + // Prepare variables for negative stop conversion. + float negBeat = -1; + float negPause = 0; + + for( unsigned f=0; f arrayFreezeValues; + split( arrayFreezeExpressions[f], "=", arrayFreezeValues ); + if( arrayFreezeValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #STOPS value \"%s\" (must have exactly one '='), ignored.", + arrayFreezeExpressions[f].c_str() ); + continue; + } + + const float fFreezeBeat = RowToBeat( arrayFreezeValues[0], iRowsPerBeat ); + const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ); + + // Process the prior stop. + if( negPause > 0 ) + { + BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); + float fSecondsPerBeat = 60 / oldBPM.GetBPM(); + float fSkipBeats = negPause / fSecondsPerBeat; + + if( negBeat + fSkipBeats > fFreezeBeat ) + fSkipBeats = fFreezeBeat - negBeat; + + WarpSegment ws( negBeat, negBeat + fSkipBeats); + out.AddWarpSegment( ws ); + + negBeat = -1; + negPause = 0; + } + + if( fFreezeSeconds < 0.0f ) + { + negBeat = fFreezeBeat; + negPause = -fFreezeSeconds; + } + else if( fFreezeSeconds > 0.0f ) + { + StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); + out.AddStopSegment( ss ); + } + + } + + // Process the prior stop if there was one. + if( negPause > 0 ) + { + BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); + float fSecondsPerBeat = 60 / oldBPM.GetBPM(); + float fSkipBeats = negPause / fSecondsPerBeat; + + WarpSegment ws( negBeat, negBeat + fSkipBeats); + out.AddWarpSegment( ws ); + } +} + +void SMALoader::ProcessDelays( TimingData &out, const int iRowsPerBeat, const RString sParam ) +{ + vector arrayDelayExpressions; + split( sParam, ",", arrayDelayExpressions ); + + for( unsigned f=0; f arrayDelayValues; + split( arrayDelayExpressions[f], "=", arrayDelayValues ); + if( arrayDelayValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #DELAYS value \"%s\" (must have exactly one '='), ignored.", + arrayDelayExpressions[f].c_str() ); + continue; + } + + const float fFreezeBeat = RowToBeat( arrayDelayValues[0], iRowsPerBeat ); + const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] ); + + StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true ); + // XXX: Remove Negatives Bug? + new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat); + new_seg.m_fStopSeconds = fFreezeSeconds; + + // LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); + + if(fFreezeSeconds > 0.0f) + out.AddStopSegment( new_seg ); + else + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); + } +} void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) { @@ -456,6 +555,20 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) ProcessBPMs( timing, iRowsPerBeat, sParams[1] ); } + else if( sValueName=="STOPS" || sValueName=="FREEZES" ) + { + TimingData &timing = (state == SMA_GETTING_STEP_INFO + ? pNewNotes->m_Timing : out.m_SongTiming); + ProcessStops( timing, iRowsPerBeat, sParams[1] ); + } + + else if( sValueName=="DELAYS" ) + { + TimingData &timing = (state == SMA_GETTING_STEP_INFO + ? pNewNotes->m_Timing : out.m_SongTiming); + ProcessDelays( timing, iRowsPerBeat, sParams[1] ); + } + else if( sValueName=="KEYSOUNDS" ) { split( sParams[1], ",", out.m_vsKeysoundFile ); @@ -490,7 +603,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) * We used to check for timing data in this section. That has * since been moved to a dedicated function. */ - else if( sValueName=="STOPS" || sValueName=="FREEZES" || sValueName=="DELAYS" || sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" || sValueName=="TICKCOUNTS" ) + else if( sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" || sValueName=="TICKCOUNTS" ) ; else LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() ); @@ -504,99 +617,6 @@ void SMALoader::GetApplicableFiles( const RString &sPath, vector &out ) GetDirListing( sPath + RString("*.sma"), out ); } -void SMALoader::LoadTimingFromSMAFile( const MsdFile &msd, TimingData &out ) -{ - out.m_fBeat0OffsetInSeconds = 0; - out.m_BPMSegments.clear(); - out.m_StopSegments.clear(); - out.m_WarpSegments.clear(); - out.m_vTimeSignatureSegments.clear(); - - vector arrayWarpsFromNegativeBPMs; - //vector arrayWarpsFromNegativeStops; - int rowsPerMeasure = 0; - bool encountered = false; - - for( unsigned i=0; i arrayFreezeExpressions; - split( sParams[1], ",", arrayFreezeExpressions ); - - for( unsigned f=0; f 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; - } - - float fFreezeBeat = 0; - RString beat = arrayFreezeValues[0]; - if( beat.Right(0).MakeUpper() == "R" ) - { - beat = beat.Left(beat.size()-1); - fFreezeBeat = StringToFloat( beat ) / rowsPerMeasure; - } - else - { - fFreezeBeat = StringToFloat(beat); - } - - //float fFreezeBeat = StringToFloat( arrayBPMChangeValues[0] ); - const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ); - StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); - // XXX: Remove Negatives Bug? - new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat); - new_seg.m_fStopSeconds = fFreezeSeconds; - - if(fFreezeSeconds > 0.0f) - { - // LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); - out.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.AddStopSegment( new_seg ); - } - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid stop at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } - } - } - - // Note: Even though it is possible to have Negative BPMs and Stops in - // a song along with Warps, we should not support files that contain - // both styles of warp tricks (Negatives vs. #WARPS). - // If Warps have been populated from Negative BPMs, then go through that - // instead of using the data in the Warps tag. This should be above, - // but it breaks compiling so... - if(arrayWarpsFromNegativeBPMs.size() > 0) - { - // zomg we already have some warps... - for( unsigned j=0; jTrace( "SMALoader::LoadEditFromFile(%s)", sEditFilePath.c_str() ); diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 5c7300d133..089eabe5ca 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -43,6 +43,8 @@ namespace SMALoader void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); bool ProcessBPMs( TimingData &out, const int iRowsPerBeat, const RString sParam ); + void ProcessStops( TimingData &out, const int iRowsPerBeat, const RString sParam ); + void ProcessDelays( TimingData &out, const int iRowsPerBeat, const RString sParam ); float RowToBeat( RString sLine, const int iRowsPerBeat ); }; From 68272d4fdaecd1d90e532970196487fb97e23d62 Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sat, 14 May 2011 17:56:39 -0500 Subject: [PATCH 103/197] [splittiming] blah --- src/Actor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Actor.cpp b/src/Actor.cpp index 42b5eae89b..6d276ac473 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -683,13 +683,13 @@ void Actor::UpdateInternal( float fDeltaTime ) break; case CLOCK_BGM_BEAT_PLAYER1: - m_fEffectDelta = g_vfCurrentBGMBeat[PlayerNumber_P1] - m_fSecsIntoEffect; - m_fSecsIntoEffect = g_vfCurrentBGMBeat[PlayerNumber_P1]; + m_fEffectDelta = g_vfCurrentBGMBeat[PLAYER_1] - m_fSecsIntoEffect; + m_fSecsIntoEffect = g_vfCurrentBGMBeat[PLAYER_1]; break; case CLOCK_BGM_BEAT_PLAYER2: - m_fEffectDelta = g_vfCurrentBGMBeat[PlayerNumber_P2] - m_fSecsIntoEffect; - m_fSecsIntoEffect = g_vfCurrentBGMBeat[PlayerNumber_P2]; + m_fEffectDelta = g_vfCurrentBGMBeat[PLAYER_2] - m_fSecsIntoEffect; + m_fSecsIntoEffect = g_vfCurrentBGMBeat[PLAYER_2]; break; case CLOCK_BGM_TIME: From 600599569801b131c65957a516fd147bc977ecf9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 18:56:58 -0400 Subject: [PATCH 104/197] [splittiming] #MULTIPLIER tag. Acts like #COMBO. Well, it really does more, but they are more Pump specific behavior right now. Let's try to stick with things that can work for all on this parser. --- src/NotesLoaderSMA.cpp | 66 +++++++++++++++++++++++++++++++++++++++++- src/NotesLoaderSMA.h | 2 ++ src/NotesLoaderSSC.cpp | 2 +- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 352def3295..4a20ff4b14 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -223,6 +223,53 @@ void SMALoader::ProcessDelays( TimingData &out, const int iRowsPerBeat, const RS } } +void SMALoader::ProcessTickcounts( TimingData &out, const int iRowsPerBeat, const RString sParam ) +{ + vector arrayTickcountExpressions; + split( sParam, ",", arrayTickcountExpressions ); + + for( unsigned f=0; f arrayTickcountValues; + split( arrayTickcountExpressions[f], "=", arrayTickcountValues ); + if( arrayTickcountValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #TICKCOUNTS value \"%s\" (must have exactly one '='), ignored.", + arrayTickcountExpressions[f].c_str() ); + continue; + } + + const float fTickcountBeat = RowToBeat( arrayTickcountValues[0], iRowsPerBeat ); + int iTicks = clamp(atoi( arrayTickcountValues[1] ), 0, ROWS_PER_BEAT); + + TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks ); + out.AddTickcountSegment( new_seg ); + } +} + +void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ) +{ + vector arrayMultiplierExpressions; + split( sParam, ",", arrayMultiplierExpressions ); + + for( unsigned f=0; f arrayMultiplierValues; + split( arrayMultiplierExpressions[f], "=", arrayMultiplierValues ); + if( arrayMultiplierValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #MULTIPLIER value \"%s\" (must have exactly one '='), ignored.", + arrayMultiplierExpressions[f].c_str() ); + continue; + } + const float fComboBeat = RowToBeat( arrayMultiplierValues[0], iRowsPerBeat ); + const int iCombos = StringToInt( arrayMultiplierValues[1] ); + ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos ); + out.AddComboSegment( new_seg ); + } +} + void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) { vector vs1; @@ -569,6 +616,23 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) ProcessDelays( timing, iRowsPerBeat, sParams[1] ); } + else if( sValueName=="TICKCOUNT" ) + { + TimingData &timing = (state == SMA_GETTING_STEP_INFO + ? pNewNotes->m_Timing : out.m_SongTiming); + ProcessTickcounts( timing, iRowsPerBeat, sParams[1] ); + } + + else if( sValueName=="SPEED" ) + { + ; // This is something we should consider implementing. + } + + else if( sValueName=="MULTIPLIER" ) + { + ProcessMultipliers( pNewNotes->m_Timing, iRowsPerBeat, sParams[1] ); + } + else if( sValueName=="KEYSOUNDS" ) { split( sParams[1], ",", out.m_vsKeysoundFile ); @@ -603,7 +667,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) * We used to check for timing data in this section. That has * since been moved to a dedicated function. */ - else if( sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" || sValueName=="TICKCOUNTS" ) + else if( sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" ) ; else LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() ); diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 089eabe5ca..1c40b462f2 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -45,6 +45,8 @@ namespace SMALoader bool ProcessBPMs( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessStops( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessDelays( TimingData &out, const int iRowsPerBeat, const RString sParam ); + void ProcessTickcounts( TimingData &out, const int iRowsPerBeat, const RString sParam ); + void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); float RowToBeat( RString sLine, const int iRowsPerBeat ); }; diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index abb5a72adf..74015106f5 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -120,7 +120,7 @@ void SSCLoader::ProcessCombos( TimingData &out, const RString sParam ) continue; } const float fComboBeat = StringToFloat( arrayComboValues[0] ); - const int iCombos = atoi( arrayComboValues[1] ); + const int iCombos = StringToInt( arrayComboValues[1] ); ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos ); out.AddComboSegment( new_seg ); } From 1cf2f266ebd53c49c909b8d387d8a83e6c329c06 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 19:05:01 -0400 Subject: [PATCH 105/197] [splittiming] Actor compiles, but not links here. Perhaps I'm doing it wrong? --- src/Actor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Actor.cpp b/src/Actor.cpp index 6d276ac473..e41d573059 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -683,13 +683,13 @@ void Actor::UpdateInternal( float fDeltaTime ) break; case CLOCK_BGM_BEAT_PLAYER1: - m_fEffectDelta = g_vfCurrentBGMBeat[PLAYER_1] - m_fSecsIntoEffect; - m_fSecsIntoEffect = g_vfCurrentBGMBeat[PLAYER_1]; + m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_1] - m_fSecsIntoEffect; + m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayer[PLAYER_1]; break; case CLOCK_BGM_BEAT_PLAYER2: - m_fEffectDelta = g_vfCurrentBGMBeat[PLAYER_2] - m_fSecsIntoEffect; - m_fSecsIntoEffect = g_vfCurrentBGMBeat[PLAYER_2]; + m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_2] - m_fSecsIntoEffect; + m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayer[PLAYER_2]; break; case CLOCK_BGM_TIME: From 75f19591227c1dfc77c90d5d127f782864bfe21d Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 19:09:23 -0400 Subject: [PATCH 106/197] [splittiming] Last seen tag. Time to try to make clean and give it a go. --- src/NotesLoaderSMA.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 4a20ff4b14..9cfca78a83 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -633,6 +633,11 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) ProcessMultipliers( pNewNotes->m_Timing, iRowsPerBeat, sParams[1] ); } + else if( sValueName=="METERTYPE" ) + { + ; // We don't use this...yet. + } + else if( sValueName=="KEYSOUNDS" ) { split( sParams[1], ",", out.m_vsKeysoundFile ); @@ -663,10 +668,6 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) out.AddSteps( pNewNotes ); } - /* - * We used to check for timing data in this section. That has - * since been moved to a dedicated function. - */ else if( sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" ) ; else From 5a06315926bfd907422304faa2b81f338dd22b04 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 19:34:57 -0400 Subject: [PATCH 107/197] [splittiming] Right, song timing always is X/4. --- src/NotesLoaderSMA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 9cfca78a83..f845127975 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -288,7 +288,7 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) const float fBeat = StringToFloat( vs2[0] ); - TimeSignatureSegment seg( BeatToNoteRow( fBeat ), StringToInt( vs2[1] ), StringToInt( vs2[2] )); + TimeSignatureSegment seg( BeatToNoteRow( fBeat ), StringToInt( vs2[1] ), 4 ); if( fBeat < 0 ) { From 574fee596e94a8facfcff1cc7e67c621d1caecd9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 20:04:33 -0400 Subject: [PATCH 108/197] [splittiming] Convert properly. --- src/NotesLoaderSMA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index f845127975..2d17557deb 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -41,7 +41,7 @@ bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) float SMALoader::RowToBeat( RString sLine, const int iRowsPerBeat ) { - if( sLine.Right(0).MakeUpper() == "R" ) + if( sLine.find("R") || sLine.find("r") ) { sLine = sLine.Left(sLine.size()-1); return StringToFloat( sLine ) / iRowsPerBeat; From a32a03b2e98b933d604710a0ec57a7d4f7cb9eaa Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 20:05:27 -0400 Subject: [PATCH 109/197] [splittiming] Trying to restore #COMBOS. --- src/Actor.cpp | 16 ---------------- src/Actor.h | 5 ----- src/GameState.cpp | 2 +- src/ScoreKeeperNormal.cpp | 2 +- 4 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/Actor.cpp b/src/Actor.cpp index e41d573059..72a3ee3856 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -68,12 +68,6 @@ void Actor::SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBe g_fCurrentBGMBeatNoOffset = fBeatNoOffset; } -void Actor::SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset ) -{ - g_vfCurrentBGMBeatPlayer[pn] = fBeat; - g_vfCurrentBGMBeatPlayerNoOffset[pn] = fBeatNoOffset; -} - void Actor::SetBGMLight( int iLightNumber, float fCabinetLights ) { ASSERT( iLightNumber < NUM_CabinetLight ); @@ -681,16 +675,6 @@ void Actor::UpdateInternal( float fDeltaTime ) m_fEffectDelta = g_fCurrentBGMBeat - m_fSecsIntoEffect; m_fSecsIntoEffect = g_fCurrentBGMBeat; break; - - case CLOCK_BGM_BEAT_PLAYER1: - m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_1] - m_fSecsIntoEffect; - m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayer[PLAYER_1]; - break; - - case CLOCK_BGM_BEAT_PLAYER2: - m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_2] - m_fSecsIntoEffect; - m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayer[PLAYER_2]; - break; case CLOCK_BGM_TIME: m_fEffectDelta = g_fCurrentBGMTime - m_fSecsIntoEffect; diff --git a/src/Actor.h b/src/Actor.h index deb9ba3716..45d080dabe 100644 --- a/src/Actor.h +++ b/src/Actor.h @@ -5,7 +5,6 @@ #include "RageUtil_AutoPtr.h" #include "LuaReference.h" #include "EnumHelper.h" -#include "PlayerNumber.h" #include class XNode; struct lua_State; @@ -110,7 +109,6 @@ public: virtual void LoadFromNode( const XNode* pNode ); static void SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBeatNoOffset ); - static void SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset ); static void SetBGMLight( int iLightNumber, float fCabinetLights ); /** @@ -133,8 +131,6 @@ public: CLOCK_BGM_BEAT, CLOCK_BGM_TIME_NO_OFFSET, CLOCK_BGM_BEAT_NO_OFFSET, - CLOCK_BGM_BEAT_PLAYER1, - CLOCK_BGM_BEAT_PLAYER2, CLOCK_LIGHT_1 = 1000, CLOCK_LIGHT_LAST = 1100, NUM_CLOCKS @@ -717,7 +713,6 @@ protected: // global state static float g_fCurrentBGMTime, g_fCurrentBGMBeat; static float g_fCurrentBGMTimeNoOffset, g_fCurrentBGMBeatNoOffset; - static vector g_vfCurrentBGMBeatPlayer, g_vfCurrentBGMBeatPlayerNoOffset; private: // commands diff --git a/src/GameState.cpp b/src/GameState.cpp index 8205d4143f..abb3c63552 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -953,7 +953,7 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti if( m_pCurSteps[pn] ) { m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); - Actor::SetPlayerBGMBeat( pn, m_pPlayerState[pn]->m_Position.m_fSongBeatVisible, m_pPlayerState[pn]->m_Position.m_fSongBeatNoOffset ); + // Actor::SetPlayerBGMBeat( pn, m_pPlayerState[pn]->m_Position.m_fSongBeatVisible, m_pPlayerState[pn]->m_Position.m_fSongBeatNoOffset ); } } } diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 36c405501e..8aaa35ffcf 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -443,7 +443,7 @@ void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumH if( iNumBreakCombo == 0 ) { - TimingData td = GAMESTATE->m_pCurSong->m_SongTiming; + TimingData td = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing; int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo ); m_pPlayerStageStats->m_iCurCombo += iNumHitContinueCombo * multiplier; } From 77dbafe9965a05c40e0d957a03a779b7397e21e1 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 20:13:46 -0400 Subject: [PATCH 110/197] [splittiming] Found the other location. Is there perhaps more to this? Hopefully not. --- src/ScoreKeeperNormal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 8aaa35ffcf..d1530a9be0 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -463,7 +463,7 @@ void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsIn if ( tns >= m_MinScoreToContinueCombo ) { m_pPlayerStageStats->m_iCurMissCombo = 0; - TimingData td = GAMESTATE->m_pCurSong->m_SongTiming; + TimingData td = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing; int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo ); m_pPlayerStageStats->m_iCurCombo += iNumTapsInRow * multiplier; } From f4800b0e070c39e3618af3d85305da90f4e6d4e6 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 14 May 2011 20:37:29 -0400 Subject: [PATCH 111/197] [splittiming] Helper function won't work here. Not counting #TICKCOUNTS and #COMBOS interactions... I think the loader is good. --- src/NotesLoaderSMA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 2d17557deb..5f4d2faea4 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -538,7 +538,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) else { state = SMA_GETTING_STEP_INFO; - pNewNotes = out.CreateSteps(); + pNewNotes = new Steps; } } From acfccd04c7c6a3f943e38a1400cf42dd4f6386ff Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 00:09:44 -0400 Subject: [PATCH 112/197] [splittiming] Revert Song Timing Restrictions. I still think BG Changes should be Song Timing only though. --- Themes/_fallback/Languages/en.ini | 4 -- src/ScreenEdit.cpp | 90 ++++++++----------------------- 2 files changed, 22 insertions(+), 72 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index beb4ac939d..5221f213de 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1259,11 +1259,7 @@ This change creates more than %d notes in a measure.=This change creates more th This change creates notes past the end of the music and is not allowed.=This change creates notes past the end of the music and is not allowed. This will destroy all unsaved changes.=This will destroy all unsaved changes. Undo=Undo -You must be in Step Timing Mode to edit the notes.=You must be in Step Timing Mode to edit the notes. You must be in Song Timing Mode to edit BG Changes.=You must be in Song Timing Mode to edit BG Changes. -You must be in Step Timing Mode to record steps.=You must be in Step Timing Mode to record steps. -You must be in Step Timing Mode to insert beats and shift down.=You must be in Step Timing Mode to insert beats and shift down. -You must be in Step Timing Mode to delete beats and shift up.=You must be in Step Timing Mode to delete beats and shift up. Current beat=Current beat Current second=Current second diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index e6d2b477e8..38ff20c18a 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -995,7 +995,7 @@ void ScreenEdit::Update( float fDeltaTime ) } float fLastBeat = NoteRowToBeat(m_iStopPlayingAt); - if( bButtonIsBeingPressed && m_EditState == STATE_RECORDING && GAMESTATE->m_bIsEditorStepTiming ) + if( bButtonIsBeingPressed && m_EditState == STATE_RECORDING ) { float fSeconds = m_pSteps->m_Timing.GetElapsedTimeFromBeat( fLastBeat ); fLastBeat = m_pSteps->m_Timing.GetBeatFromElapsedTime( fSeconds + 0.5f ); @@ -1280,11 +1280,7 @@ static int FindAttackAtTime( const AttackArray& attacks, float fStartTime ) return -1; } -static LocalizedString TAP_NOTE_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to edit the notes." ); static LocalizedString BG_CHANGE_STEP_TIMING ( "ScreenEdit", "You must be in Song Timing Mode to edit BG Changes." ); -static LocalizedString RECORD_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to record steps." ); -static LocalizedString INSERT_BEAT_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to insert beats and shift down." ); -static LocalizedString DELETE_BEAT_SONG_TIMING ( "ScreenEdit", "You must be in Step Timing Mode to delete beats and shift up." ); static LocalizedString SWITCHED_TO ( "ScreenEdit", "Switched to" ); static LocalizedString NO_BACKGROUNDS_AVAILABLE ( "ScreenEdit", "No backgrounds available" ); @@ -1316,15 +1312,6 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( input.type != IET_FIRST_PRESS ) break; // We only care about first presses - - if( !GAMESTATE->m_bIsEditorStepTiming ) - { - // Only allow steps to be hit in Step Timing. - SCREENMAN->SystemMessage( TAP_NOTE_SONG_TIMING ); - SCREENMAN->PlayInvalidSound(); - break; - } - int iCol = EditB - EDIT_BUTTON_COLUMN_0; @@ -1555,20 +1542,18 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { // update enabled/disabled in g_AreaMenu bool bAreaSelected = m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1; - g_AreaMenu.rows[cut].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[cut].bEnabled = bAreaSelected; g_AreaMenu.rows[copy].bEnabled = bAreaSelected; - g_AreaMenu.rows[paste_at_current_beat].bEnabled = !m_Clipboard.IsEmpty() && GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[paste_at_begin_marker].bEnabled = !m_Clipboard.IsEmpty() != 0 && m_NoteFieldEdit.m_iBeginMarker!=-1 && GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[clear].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[quantize].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[turn].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[transform].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[alter].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[paste_at_current_beat].bEnabled = !m_Clipboard.IsEmpty(); + g_AreaMenu.rows[paste_at_begin_marker].bEnabled = !m_Clipboard.IsEmpty() != 0 && m_NoteFieldEdit.m_iBeginMarker!=-1; + g_AreaMenu.rows[clear].bEnabled = bAreaSelected; + g_AreaMenu.rows[quantize].bEnabled = bAreaSelected; + g_AreaMenu.rows[turn].bEnabled = bAreaSelected; + g_AreaMenu.rows[transform].bEnabled = bAreaSelected; + g_AreaMenu.rows[alter].bEnabled = bAreaSelected; g_AreaMenu.rows[tempo].bEnabled = bAreaSelected; g_AreaMenu.rows[play].bEnabled = bAreaSelected; - g_AreaMenu.rows[record].bEnabled = bAreaSelected && GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[insert_and_shift].bEnabled = GAMESTATE->m_bIsEditorStepTiming; - g_AreaMenu.rows[delete_and_shift].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_AreaMenu.rows[record].bEnabled = bAreaSelected; g_AreaMenu.rows[convert_to_pause].bEnabled = bAreaSelected; g_AreaMenu.rows[undo].bEnabled = m_bHasUndo; EditMiniMenu( &g_AreaMenu, SM_BackFromAreaMenu ); @@ -2083,12 +2068,6 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) HandleMainMenuChoice( play_selection ); break; case EDIT_BUTTON_RECORD_SELECTION: - if( !GAMESTATE->m_bIsEditorStepTiming ) - { - SCREENMAN->SystemMessage( RECORD_SONG_TIMING ); - SCREENMAN->PlayInvalidSound(); - break; - } if( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ) { HandleAreaMenuChoice( record ); @@ -2125,14 +2104,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_INSERT: - if( GAMESTATE->m_bIsEditorStepTiming ) - { - HandleAreaMenuChoice( insert_and_shift ); - } - else - { - SCREENMAN->SystemMessage( INSERT_BEAT_SONG_TIMING ); - } + HandleAreaMenuChoice( insert_and_shift ); SCREENMAN->PlayInvalidSound(); break; @@ -2142,14 +2114,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_DELETE: - if( GAMESTATE->m_bIsEditorStepTiming ) - { - HandleAreaMenuChoice( delete_and_shift ); - } - else - { - SCREENMAN->SystemMessage( DELETE_BEAT_SONG_TIMING ); - } + HandleAreaMenuChoice( delete_and_shift ); SCREENMAN->PlayInvalidSound(); break; @@ -2190,9 +2155,6 @@ void ScreenEdit::InputRecord( const InputEventPlus &input, EditButton EditB ) TransitionEditState( STATE_EDITING ); return; } - - if ( !GAMESTATE->m_bIsEditorStepTiming ) - return; // can't allow changes if in song timing. if( input.pn != PLAYER_1 ) return; // ignore @@ -2259,12 +2221,7 @@ void ScreenEdit::InputRecordPaused( const InputEventPlus &input, EditButton Edit break; case EDIT_BUTTON_RECORD_SELECTION: - if( GAMESTATE->m_bIsEditorStepTiming ) - TransitionEditState( STATE_RECORDING ); - else - { - // broadcast error maybe. - } + TransitionEditState( STATE_RECORDING ); break; case EDIT_BUTTON_RECORD_FROM_CURSOR: @@ -2612,20 +2569,17 @@ void ScreenEdit::ScrollTo( float fDestinationBeat ) if( !EditIsBeingPressed(b) ) continue; - if( GAMESTATE->m_bIsEditorStepTiming ) - { - // create a new hold note - int iStartRow = BeatToNoteRow( min(fOriginalBeat, fDestinationBeat) ); - int iEndRow = BeatToNoteRow( max(fOriginalBeat, fDestinationBeat) ); + // create a new hold note + int iStartRow = BeatToNoteRow( min(fOriginalBeat, fDestinationBeat) ); + int iEndRow = BeatToNoteRow( max(fOriginalBeat, fDestinationBeat) ); - // Don't SaveUndo. We want to undo the whole hold, not just the last segment - // that the user made. Dragging the hold bigger can only absorb and remove - // other taps, so dragging won't cause us to exceed the note limit. - TapNote tn = EditIsBeingPressed(EDIT_BUTTON_LAY_ROLL) ? TAP_ORIGINAL_ROLL_HEAD : TAP_ORIGINAL_HOLD_HEAD; + // Don't SaveUndo. We want to undo the whole hold, not just the last segment + // that the user made. Dragging the hold bigger can only absorb and remove + // other taps, so dragging won't cause us to exceed the note limit. + TapNote tn = EditIsBeingPressed(EDIT_BUTTON_LAY_ROLL) ? TAP_ORIGINAL_ROLL_HEAD : TAP_ORIGINAL_HOLD_HEAD; - tn.pn = m_InputPlayerNumber; - m_NoteDataEdit.AddHoldNote( iCol, iStartRow, iEndRow, tn ); - } + tn.pn = m_InputPlayerNumber; + m_NoteDataEdit.AddHoldNote( iCol, iStartRow, iEndRow, tn ); } if( EditIsBeingPressed(EDIT_BUTTON_SCROLL_SELECT) ) From 83ba698ced1c04bb119cbae19d64491fd3f3e7e4 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 00:57:01 -0400 Subject: [PATCH 113/197] [splittiming] This TODO seems obsolete. --- src/SongPosition.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SongPosition.h b/src/SongPosition.h index 56cf0e38d5..9ca7bbe778 100644 --- a/src/SongPosition.h +++ b/src/SongPosition.h @@ -15,7 +15,6 @@ class SongPosition // Arcade - the current stage (one song). // Oni/Endless - a single song in a course. // Let a lot of classes access this info here so they don't have to keep their own copies. - // todo: [NUM_PLAYERS] this for split bpm lolol -aj float m_fMusicSeconds; // time into the current song, not scaled by music rate float m_fSongBeat; float m_fSongBeatNoOffset; From d99e7b5c5b80a6358b369455642fea82b3ca2c8e Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 00:57:35 -0400 Subject: [PATCH 114/197] [splittiming] Re-establish Actor code. --- src/Actor.cpp | 21 +++++++++++++++++++-- src/Actor.h | 6 ++++++ src/GameState.cpp | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/Actor.cpp b/src/Actor.cpp index 72a3ee3856..3191d98d56 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -34,6 +34,8 @@ REGISTER_ACTOR_CLASS_WITH_NAME( HiddenActor, Actor ); float Actor::g_fCurrentBGMTime = 0, Actor::g_fCurrentBGMBeat; float Actor::g_fCurrentBGMTimeNoOffset = 0, Actor::g_fCurrentBGMBeatNoOffset = 0; +vector Actor::g_vfCurrentBGMBeatPlayer(NUM_PlayerNumber, 0); +vector Actor::g_vfCurrentBGMBeatPlayerNoOffset(NUM_PlayerNumber, 0); Actor *Actor::Copy() const { return new Actor(*this); } @@ -68,6 +70,12 @@ void Actor::SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBe g_fCurrentBGMBeatNoOffset = fBeatNoOffset; } +void Actor::SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset ) +{ + g_vfCurrentBGMBeatPlayer[pn] = fBeat; + g_vfCurrentBGMBeatPlayerNoOffset[pn] = fBeatNoOffset; +} + void Actor::SetBGMLight( int iLightNumber, float fCabinetLights ) { ASSERT( iLightNumber < NUM_CabinetLight ); @@ -150,8 +158,7 @@ Actor::Actor() lua_setfield( L, -2, "ctx" ); lua_pop( L, 1 ); LUA->Release( L ); - - + m_size = RageVector2( 1, 1 ); InitState(); m_pParent = NULL; @@ -676,6 +683,16 @@ void Actor::UpdateInternal( float fDeltaTime ) m_fSecsIntoEffect = g_fCurrentBGMBeat; break; + case CLOCK_BGM_BEAT_PLAYER1: + m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_1] - m_fSecsIntoEffect; + m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayerNoOffset[PLAYER_1]; + break; + + case CLOCK_BGM_BEAT_PLAYER2: + m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_2] - m_fSecsIntoEffect; + m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayerNoOffset[PLAYER_2]; + break; + case CLOCK_BGM_TIME: m_fEffectDelta = g_fCurrentBGMTime - m_fSecsIntoEffect; m_fSecsIntoEffect = g_fCurrentBGMTime; diff --git a/src/Actor.h b/src/Actor.h index 45d080dabe..919d4994f7 100644 --- a/src/Actor.h +++ b/src/Actor.h @@ -1,6 +1,7 @@ #ifndef ACTOR_H #define ACTOR_H +#include "PlayerNumber.h" #include "RageTypes.h" #include "RageUtil_AutoPtr.h" #include "LuaReference.h" @@ -109,6 +110,7 @@ public: virtual void LoadFromNode( const XNode* pNode ); static void SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBeatNoOffset ); + static void SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset ); static void SetBGMLight( int iLightNumber, float fCabinetLights ); /** @@ -131,6 +133,8 @@ public: CLOCK_BGM_BEAT, CLOCK_BGM_TIME_NO_OFFSET, CLOCK_BGM_BEAT_NO_OFFSET, + CLOCK_BGM_BEAT_PLAYER1, + CLOCK_BGM_BEAT_PLAYER2, CLOCK_LIGHT_1 = 1000, CLOCK_LIGHT_LAST = 1100, NUM_CLOCKS @@ -713,6 +717,8 @@ protected: // global state static float g_fCurrentBGMTime, g_fCurrentBGMBeat; static float g_fCurrentBGMTimeNoOffset, g_fCurrentBGMBeatNoOffset; + static vector g_vfCurrentBGMBeatPlayer; + static vector g_vfCurrentBGMBeatPlayerNoOffset; private: // commands diff --git a/src/GameState.cpp b/src/GameState.cpp index abb3c63552..8205d4143f 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -953,7 +953,7 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti if( m_pCurSteps[pn] ) { m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp ); - // Actor::SetPlayerBGMBeat( pn, m_pPlayerState[pn]->m_Position.m_fSongBeatVisible, m_pPlayerState[pn]->m_Position.m_fSongBeatNoOffset ); + Actor::SetPlayerBGMBeat( pn, m_pPlayerState[pn]->m_Position.m_fSongBeatVisible, m_pPlayerState[pn]->m_Position.m_fSongBeatNoOffset ); } } } From 84f2457aa487db86cd450e40a23580929f5f74d6 Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sun, 15 May 2011 07:53:06 -0500 Subject: [PATCH 115/197] [splittiming] Add PlayerState.GetSongPosition() and GameState.GetSongPosition() to Lua; add lua bindings to SongPosition --- src/GameState.cpp | 3 +++ src/PlayerState.cpp | 1 + src/SongPosition.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/GameState.cpp b/src/GameState.cpp index 8205d4143f..7b1be3f3c9 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -2251,11 +2251,13 @@ public: DEFINE_METHOD( GetHardestStepsDifficulty, GetHardestStepsDifficulty() ) DEFINE_METHOD( IsEventMode, IsEventMode() ) DEFINE_METHOD( GetNumPlayersEnabled, GetNumPlayersEnabled() ) + //TODO: move GetSongBeat (etc.) to a compatbility layer DEFINE_METHOD( GetSongBeat, m_Position.m_fSongBeat ) DEFINE_METHOD( GetSongBeatVisible, m_Position.m_fSongBeatVisible ) DEFINE_METHOD( GetSongBPS, m_Position.m_fCurBPS ) DEFINE_METHOD( GetSongFreeze, m_Position.m_bFreeze ) DEFINE_METHOD( GetSongDelay, m_Position.m_bDelay ) + DEFINE_METHOD( GetSongPosition, m_Position ) DEFINE_METHOD( GetGameplayLeadIn, m_bGameplayLeadIn ) DEFINE_METHOD( GetCoins, m_iCoins ) DEFINE_METHOD( IsSideJoined, m_bSideIsJoined[Enum::Check(L, 1)] ) @@ -2465,6 +2467,7 @@ public: ADD_METHOD( GetSongBPS ); ADD_METHOD( GetSongFreeze ); ADD_METHOD( GetSongDelay ); + ADD_METHOD( GetSongPosition ); ADD_METHOD( GetGameplayLeadIn ); ADD_METHOD( GetCoins ); ADD_METHOD( IsSideJoined ); diff --git a/src/PlayerState.cpp b/src/PlayerState.cpp index d6583059bf..ac76b0fbc2 100644 --- a/src/PlayerState.cpp +++ b/src/PlayerState.cpp @@ -197,6 +197,7 @@ class LunaPlayerState: public Luna { public: DEFINE_METHOD( GetPlayerNumber, m_PlayerNumber ); + DEFINE_METHOD( GetSongPosition, m_Position ); DEFINE_METHOD( GetMultiPlayerNumber, m_mp ); DEFINE_METHOD( GetPlayerController, m_PlayerController ); static int SetPlayerOptions( T* p, lua_State *L ) diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp index bcfee26f80..134c3f8b5d 100644 --- a/src/SongPosition.cpp +++ b/src/SongPosition.cpp @@ -74,6 +74,38 @@ void SongPosition::Reset() } +//lua start +#include "LuaBinding.h" +class LunaSongPosition: public Luna +{ +public: + DEFINE_METHOD( GetMusicSecondsVisible, m_fMusicSecondsVisible ); + DEFINE_METHOD( GetSongBeatVisible, m_fSongBeatVisible ); + DEFINE_METHOD( GetMusicSeconds, m_fMusicSeconds ); + DEFINE_METHOD( GetSongBeat, m_fSongBeat ); + DEFINE_METHOD( GetSongBeatNoOffset, m_fSongBeatNoOffset ); + DEFINE_METHOD( GetCurBPS, m_fCurBPS ); + DEFINE_METHOD( GetFreeze, m_bFreeze ); + DEFINE_METHOD( GetDelay, m_bDelay ); + DEFINE_METHOD( GetWarpBeginRow, m_fWarpBeginRow ); + DEFINE_METHOD( GetWarpDestination, m_fWarpDestination ); + + LunaSongPosition() + { + ADD_METHOD( GetMusicSecondsVisible ); + ADD_METHOD( GetSongBeatVisible ); + ADD_METHOD( GetMusicSeconds ); + ADD_METHOD( GetSongBeat ); + ADD_METHOD( GetSongBeatNoOffset ); + ADD_METHOD( GetCurBPS ); + ADD_METHOD( GetFreeze ); + ADD_METHOD( GetDelay ); + ADD_METHOD( GetWarpBeginRow ); + ADD_METHOD( GetWarpDestination ); + } +}; + +LUA_REGISTER_CLASS( SongPosition ) /** * @file * @author Thai Pangsakulyanont (c) 2011 From 4d14654147061e0f075ee68addbf3ce6f539aa79 Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sun, 15 May 2011 08:17:32 -0500 Subject: [PATCH 116/197] [splittiming] remove GameState "current timing" functions; add compatibility functions to 01 compat.lua --- Themes/_fallback/Scripts/01 alias.lua | 2 +- Themes/_fallback/Scripts/01 compat.lua | 12 +++++++++++- src/GameState.cpp | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Themes/_fallback/Scripts/01 alias.lua b/Themes/_fallback/Scripts/01 alias.lua index 05935425bf..126d9c69ef 100644 --- a/Themes/_fallback/Scripts/01 alias.lua +++ b/Themes/_fallback/Scripts/01 alias.lua @@ -20,4 +20,4 @@ local _screen = { h = SCREEN_HEIGHT, cx = SCREEN_CENTER_X, cy = SCREEN_CENTER_Y -} \ No newline at end of file +} diff --git a/Themes/_fallback/Scripts/01 compat.lua b/Themes/_fallback/Scripts/01 compat.lua index c2f171e1f0..dbdf4a819c 100644 --- a/Themes/_fallback/Scripts/01 compat.lua +++ b/Themes/_fallback/Scripts/01 compat.lua @@ -63,4 +63,14 @@ end if ScreenMetric then ScreenMetric = Screen.Metric -end \ No newline at end of file +end + +--[[ GameState ]] +--Aliases for old GAMESTATE timing functions. +--These have been converted to SongPosition, but most themes still use these old functions. + +function GameState:GetSongBeat() return self:GetSongPosition():GetSongBeat() end +function GameState:GetSongBeatNoOffset() return self:GetSongPosition():GetSongBeatNoOffset() end +function GameState:GetSongBPS() return self:GetSongPosition():GetCurBPS() end +function GameState:GetSongDelay() return self:GetSongPosition:GetDelay() end +function GameState:GetSongFreeze() return self:GetSongPosition:GetFreeze() end diff --git a/src/GameState.cpp b/src/GameState.cpp index 7b1be3f3c9..f9451ff119 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -2462,11 +2462,11 @@ public: ADD_METHOD( GetHardestStepsDifficulty ); ADD_METHOD( IsEventMode ); ADD_METHOD( GetNumPlayersEnabled ); - ADD_METHOD( GetSongBeat ); + /*ADD_METHOD( GetSongBeat ); ADD_METHOD( GetSongBeatVisible ); ADD_METHOD( GetSongBPS ); ADD_METHOD( GetSongFreeze ); - ADD_METHOD( GetSongDelay ); + ADD_METHOD( GetSongDelay );*/ ADD_METHOD( GetSongPosition ); ADD_METHOD( GetGameplayLeadIn ); ADD_METHOD( GetCoins ); From ec09a40d39c6517b170ec0cba525d4d5c9c9182d Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sun, 15 May 2011 08:21:16 -0500 Subject: [PATCH 117/197] [splittiming] finish removing bindings --- src/GameState.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index f9451ff119..9ed0c33f78 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -2251,12 +2251,11 @@ public: DEFINE_METHOD( GetHardestStepsDifficulty, GetHardestStepsDifficulty() ) DEFINE_METHOD( IsEventMode, IsEventMode() ) DEFINE_METHOD( GetNumPlayersEnabled, GetNumPlayersEnabled() ) - //TODO: move GetSongBeat (etc.) to a compatbility layer - DEFINE_METHOD( GetSongBeat, m_Position.m_fSongBeat ) + /*DEFINE_METHOD( GetSongBeat, m_Position.m_fSongBeat ) DEFINE_METHOD( GetSongBeatVisible, m_Position.m_fSongBeatVisible ) DEFINE_METHOD( GetSongBPS, m_Position.m_fCurBPS ) DEFINE_METHOD( GetSongFreeze, m_Position.m_bFreeze ) - DEFINE_METHOD( GetSongDelay, m_Position.m_bDelay ) + DEFINE_METHOD( GetSongDelay, m_Position.m_bDelay )*/ DEFINE_METHOD( GetSongPosition, m_Position ) DEFINE_METHOD( GetGameplayLeadIn, m_bGameplayLeadIn ) DEFINE_METHOD( GetCoins, m_iCoins ) From 2f83c163276b5e601d31ad125ff99a4983d61910 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 13:06:46 -0400 Subject: [PATCH 118/197] [splittiming] Minor typo. --- src/SongPosition.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SongPosition.cpp b/src/SongPosition.cpp index 134c3f8b5d..5aa148e552 100644 --- a/src/SongPosition.cpp +++ b/src/SongPosition.cpp @@ -87,7 +87,7 @@ public: DEFINE_METHOD( GetCurBPS, m_fCurBPS ); DEFINE_METHOD( GetFreeze, m_bFreeze ); DEFINE_METHOD( GetDelay, m_bDelay ); - DEFINE_METHOD( GetWarpBeginRow, m_fWarpBeginRow ); + DEFINE_METHOD( GetWarpBeginRow, m_iWarpBeginRow ); DEFINE_METHOD( GetWarpDestination, m_fWarpDestination ); LunaSongPosition() @@ -105,7 +105,7 @@ public: } }; -LUA_REGISTER_CLASS( SongPosition ) +LUA_REGISTER_CLASS( SongPosition ); /** * @file * @author Thai Pangsakulyanont (c) 2011 From 702ebfe94b1f3ec836ab6e678f3f96710971384c Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 13:09:13 -0400 Subject: [PATCH 119/197] [splittiming] The start of SpeedSegments. ...I'm seriously debating moving the structs to their own file at this rate. It's getting a tiny bit unwieldy. --- src/TimingData.h | 107 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/TimingData.h b/src/TimingData.h index 2c5ad2ecf6..c1d1b2ea87 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -647,6 +647,107 @@ struct LabelSegment bool operator>=( const LabelSegment &other ) const { return !operator<(other); } }; +/** + * @brief Identifies when the arrow scroll changes. + * + * SpeedSegments take a Player's scrolling BPM (Step's BPM * speed mod), + * and then multiplies it with the percentage value. No matter the player's + * speed mod, the ratio will be the same. Unlike forced attacks, these + * cannot be turned off at a set time: reset it by setting the precentage + * back to 1. + * + * These were inspired by the Pump It Up series. */ +struct SpeedSegment +{ + /** @brief Sets up the SpeedSegment with default values. */ + SpeedSegment(): m_iStartRow(0), m_fPercent(1), m_fWait(0) {} + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param i The row this activates. + * @param p The percentage to use. */ + SpeedSegment(int i, float p): m_iStartRow(0), m_fPercent(p), m_fWait(0) {} + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param r The beat this activates. + * @param p The percentage to use. */ + SpeedSegment(float r, float p): m_iStartRow(BeatToNoteRow(r)), + m_fPercent(p), m_fWait(0) {} + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param i The row this activates. + * @param p The percentage to use. + * @param w The number of beats to wait. */ + SpeedSegment(int i, float p, float w): m_iStartRow(i), + m_fPercent(p), m_fWait(w) {} + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param r The beat this activates. + * @param p The percentage to use. + * @param w The number of beats to wait. */ + SpeedSegment(float r, float p, float w): m_iStartRow(BeatToNoteRow(r)), + m_fPercent(p), m_fWait(w) {} + + /** @brief The row in which the ComboSegment activates. */ + int m_iStartRow; + /** @brief The percentage to use when multiplying the Player's BPM. */ + float m_fPercent; + /** + * @brief The number of beats to wait for the change to take place. + * + * A value of 0 means this is immediate. */ + float m_fWait; + + /** + * @brief Compares two SpeedSegments to see if they are equal to each other. + * @param other the other SpeedSegment to compare to. + * @return the equality of the two segments. + */ + bool operator==( const SpeedSegment &other ) const + { + COMPARE( m_iStartRow ); + COMPARE( m_fPercent ); + COMPARE( m_fWait ); + return true; + } + /** + * @brief Compares two SpeedSegments to see if they are not equal to each other. + * @param other the other SpeedSegment to compare to. + * @return the inequality of the two segments. + */ + bool operator!=( const SpeedSegment &other ) const { return !operator==(other); } + /** + * @brief Compares two SpeedSegments to see if one is less than the other. + * @param other the other SpeedSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const SpeedSegment &other ) const { return m_iStartRow < other.m_iStartRow; } + /** + * @brief Compares two SpeedSegments to see if one is less than or equal to the other. + * @param other the other SpeedSegment to compare to. + * @return the truth/falsehood of if the first is less or equal to than the second. + */ + bool operator<=( const SpeedSegment &other ) const + { + return ( operator<(other) || operator==(other) ); + } + /** + * @brief Compares two SpeedSegments to see if one is greater than the other. + * @param other the other SpeedSegment to compare to. + * @return the truth/falsehood of if the first is greater than the second. + */ + bool operator>( const SpeedSegment &other ) const { return !operator<=(other); } + /** + * @brief Compares two SpeedSegments to see if one is greater than or equal to the other. + * @param other the other SpeedSegment to compare to. + * @return the truth/falsehood of if the first is greater than or equal to the second. + */ + bool operator>=( const SpeedSegment &other ) const { return !operator<(other); } +}; + /** * @brief Holds data for translating beats<->seconds. @@ -1305,8 +1406,12 @@ public: COMPARE( m_ComboSegments.size() ); for( unsigned i=0; i m_LabelSegments; + /** @brief The collection of SpeedSegments. */ + vector m_SpeedSegments; /** * @brief The initial offset of a song. */ From 9870ed9ebb19e036f9f2126ff691860330d877c7 Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sun, 15 May 2011 12:16:02 -0500 Subject: [PATCH 120/197] [splittiming] another fix for le bad lua bindings --- src/SongPosition.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SongPosition.h b/src/SongPosition.h index 9ca7bbe778..830924b84a 100644 --- a/src/SongPosition.h +++ b/src/SongPosition.h @@ -6,6 +6,8 @@ #include "LightsManager.h" #include "MessageManager.h" #include "TimingData.h" +//XXX: where does this come from? might need another include +struct lua_State; class SongPosition { @@ -36,6 +38,8 @@ class SongPosition void Reset(); void UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp = RageZeroTimer ); + // Lua + void PushSelf( lua_State *L ); }; #endif From 9ffe6166e2927df4065584d1141003079892ae57 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 13:48:10 -0400 Subject: [PATCH 121/197] [splittiming] Implement, add lua hook. --- Docs/Luadoc/Lua.xml | 1 + Docs/Luadoc/LuaDocumentation.xml | 3 + src/TimingData.cpp | 124 ++++++++++++++++++++++++++++++- src/TimingData.h | 99 ++++++++++++++++++++++++ 4 files changed, 226 insertions(+), 1 deletion(-) diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index f41bb848cb..966502afbc 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -1405,6 +1405,7 @@ + diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index 39df9f4188..24492431aa 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -3516,6 +3516,9 @@ Returns true if the TimingData contains warps. + + Returns true if the TimingData contains speed scrolling changes. + diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 2f93424bc7..45302128b8 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -68,6 +68,11 @@ void TimingData::AddLabelSegment( const LabelSegment &seg ) m_LabelSegments.insert( upper_bound(m_LabelSegments.begin(), m_LabelSegments.end(), seg), seg ); } +void TimingData::AddSpeedSegment( const SpeedSegment &seg ) +{ + m_SpeedSegments.insert( upper_bound(m_SpeedSegments.begin(), m_SpeedSegments.end(), seg), seg ); +} + /* Change an existing BPM segment, merge identical segments together or insert a new one. */ void TimingData::SetBPMAtRow( int iNoteRow, float fBPM ) { @@ -250,6 +255,47 @@ void TimingData::SetLabelAtRow( int iRow, const RString sLabel ) } } +void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait ) +{ + unsigned i; + for( i = 0; i < m_SpeedSegments.size(); i++ ) + { + if( m_SpeedSegments[i].m_iStartRow >= iRow) + break; + } + + if ( i == m_SpeedSegments.size() || m_SpeedSegments[i].m_iStartRow != iRow ) + { + if( i == 0 || + ( m_SpeedSegments[i-1].m_fPercent != fPercent + || m_SpeedSegments[i-1].m_fWait != fWait ) ) + AddSpeedSegment( SpeedSegment(iRow, fPercent, fWait) ); + } + else + { + if( i > 0 && m_SpeedSegments[i-1].m_fPercent == fPercent + && m_SpeedSegments[i-1].m_fWait == fWait ) + m_SpeedSegments.erase( m_SpeedSegments.begin()+i, + m_SpeedSegments.begin()+i+1 ); + else + { + m_SpeedSegments[i].m_fPercent = fPercent; + m_SpeedSegments[i].m_fWait = fWait; + } + } +} + +void TimingData::SetSpeedPercentAtRow( int iRow, float fPercent ) +{ + SetSpeedAtRow( iRow, fPercent, GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fWait ); +} + +void TimingData::SetSpeedWaitAtRow( int iRow, float fWait ) +{ + SetSpeedAtRow( iRow, GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fPercent, fWait ); +} + + float TimingData::GetStopAtRow( int iNoteRow, bool bDelay ) const { for( unsigned i=0; i(i); } +int TimingData::GetSpeedSegmentIndexAtRow( int iRow ) const +{ + unsigned i; + for (i=0; i < m_SpeedSegments.size() - 1; i++ ) + if( m_SpeedSegments[i+1].m_iStartRow > iRow ) + break; + return static_cast(i); +} + BPMSegment& TimingData::GetBPMSegmentAtRow( int iNoteRow ) { static BPMSegment empty; @@ -451,6 +516,15 @@ TimeSignatureSegment& TimingData::GetTimeSignatureSegmentAtRow( int iRow ) return m_vTimeSignatureSegments[i]; } +SpeedSegment& TimingData::GetSpeedSegmentAtRow( int iRow ) +{ + unsigned i; + for( i=0; i iRow ) + break; + return m_SpeedSegments[i]; +} + int TimingData::GetTimeSignatureNumeratorAtRow( int iRow ) { return GetTimeSignatureSegmentAtRow( iRow ).m_iNumerator; @@ -845,6 +919,17 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool m_LabelSegments[i].m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; } + for ( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) + { + const int iSegStart = m_SpeedSegments[i].m_iStartRow; + if( iSegStart < iStartIndex ) + continue; + else if( iSegStart > iEndIndex ) + m_SpeedSegments[i].m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + else + m_SpeedSegments[i].m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; + } + // adjust BPM changes to preserve timing if( bAdjustBPM ) { @@ -929,6 +1014,14 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) continue; labl.m_iStartRow += iRowsToAdd; } + + for( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) + { + SpeedSegment &sped = m_SpeedSegments[i]; + if( sped.m_iStartRow < iStartRow ) + continue; + sped.m_iStartRow += iRowsToAdd; + } if( iStartRow == 0 ) { @@ -1086,6 +1179,22 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) } labl.m_iStartRow -= iRowsToDelete; } + + for( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) + { + SpeedSegment &sped = m_SpeedSegments[i]; + + if( sped.m_iStartRow < iStartRow ) + continue; + + if( sped.m_iStartRow < iStartRow+iRowsToDelete ) + { + m_SpeedSegments.erase( m_SpeedSegments.begin()+i, m_SpeedSegments.begin()+i+1 ); + --i; + continue; + } + sped.m_iStartRow -= iRowsToDelete; + } this->SetBPMAtRow( iStartRow, fNewBPM ); } @@ -1133,7 +1242,13 @@ void TimingData::TidyUpData() LabelSegment seg(0, "Song Start"); m_LabelSegments.push_back( seg ); } - + + // Always be sure there is a starting speed. + if( m_SpeedSegments.empty() ) + { + SpeedSegment seg(0, 1, 0); + m_SpeedSegments.push_back( seg ); + } } @@ -1155,6 +1270,11 @@ bool TimingData::HasWarps() const return m_WarpSegments.size()>0; } +bool TimingData::HasSpeedChanges() const +{ + return m_SpeedSegments.size()>1; +} + void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, int &iBeatIndexOut, int &iRowsRemainder ) const { iMeasureIndexOut = 0; @@ -1201,6 +1321,7 @@ public: static int HasStops( T* p, lua_State *L ) { lua_pushboolean(L, p->HasStops()); return 1; } static int HasBPMChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasBpmChanges()); return 1; } static int HasWarps( T* p, lua_State *L ) { lua_pushboolean(L, p->HasWarps()); return 1; } + static int HasSpeedChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasSpeedChanges()); return 1; } static int GetStops( T* p, lua_State *L ) { vector vStops; @@ -1288,6 +1409,7 @@ public: ADD_METHOD( HasStops ); ADD_METHOD( HasBPMChanges ); ADD_METHOD( HasWarps ); + ADD_METHOD( HasSpeedChanges ); ADD_METHOD( GetStops ); ADD_METHOD( GetDelays ); ADD_METHOD( GetBPMs ); diff --git a/src/TimingData.h b/src/TimingData.h index c1d1b2ea87..d68e2ec98e 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -1339,6 +1339,101 @@ public: */ float GetNextLabelSegmentBeatAtBeat( float fBeat ) const { return GetNextLabelSegmentBeatAtRow( BeatToNoteRow(fBeat) ); } + + /** + * @brief Retrieve the Speed's percent at the given row. + * @param iNoteRow the row in question. + * @return the percent. + */ + float GetSpeedPercentAtRow( int iNoteRow ); + /** + * @brief Retrieve the Speed's percent at the given beat. + * @param fBeat the beat in question. + * @return the percent. + */ + float GetSpeedPercentAtBeat( float fBeat ) { return GetSpeedPercentAtRow( BeatToNoteRow(fBeat) ); } + /** + * @brief Retrieve the Speed's wait at the given row. + * @param iNoteRow the row in question. + * @return the wait. + */ + float GetSpeedWaitAtRow( int iNoteRow ); + /** + * @brief Retrieve the Speed's wait at the given beat. + * @param fBeat the beat in question. + * @return the wait. + */ + float GetSpeedWaitAtBeat( float fBeat ) { return GetSpeedWaitAtRow( BeatToNoteRow(fBeat) ); } + /** + * @brief Set the row to have the new Speed. + * @param iNoteRow the row to have the new Speed. + * @param fPercent the percent. + * @param fWait the wait. + */ + void SetSpeedAtRow( int iNoteRow, float fPercent, float fWait ); + /** + * @brief Set the beat to have the new Speed. + * @param fBeat the beat to have the new Speed. + * @param fPercent the percent. + * @param fWait the wait. + */ + void SetSpeedAtBeat( float fBeat, float fPercent, float fWait ) { SetSpeedAtRow( BeatToNoteRow(fBeat), fPercent, fWait ); } + /** + * @brief Set the row to have the new Speed percent. + * @param iNoteRow the row to have the new Speed percent. + * @param fPercent the percent. + */ + void SetSpeedPercentAtRow( int iNoteRow, float fPercent ); + /** + * @brief Set the beat to have the new Speed percent. + * @param fBeat the beat to have the new Speed percent. + * @param fPercent the percent. + */ + void SetSpeedPercentAtBeat( float fBeat, float fPercent ) { SetSpeedPercentAtRow( BeatToNoteRow(fBeat), fPercent); } + /** + * @brief Set the row to have the new Speed wait. + * @param iNoteRow the row to have the new Speed wait. + * @param fWait the wait. + */ + void SetSpeedWaitAtRow( int iNoteRow, float fWait ); + /** + * @brief Set the beat to have the new Speed wait. + * @param fBeat the beat to have the new Speed wait. + * @param fWait the wait. + */ + void SetSpeedWaitAtBeat( float fBeat, float fWait ) { SetSpeedWaitAtRow( BeatToNoteRow(fBeat), fWait); } + /** + * @brief Retrieve the SpeedSegment at the specified row. + * @param iNoteRow the row that has a SpeedSegment. + * @return the SpeedSegment in question. + */ + SpeedSegment& GetSpeedSegmentAtRow( int iNoteRow ); + /** + * @brief Retrieve the SpeedSegment at the specified beat. + * @param fBeat the beat that has a SpeedSegment. + * @return the SpeedSegment in question. + */ + SpeedSegment& GetSpeedSegmentAtBeat( float fBeat ) { return GetSpeedSegmentAtRow( BeatToNoteRow(fBeat) ); } + /** + * @brief Retrieve the index of the SpeedSegments at the specified row. + * @param iNoteRow the row that has a SpeedSegment. + * @return the SpeedSegment's index in question. + */ + int GetSpeedSegmentIndexAtRow( int iNoteRow ) const; + /** + * @brief Retrieve the index of the SpeedSegments at the specified beat. + * @param fBeat the beat that has a SpeedSegment. + * @return the SpeedSegment's index in question. + */ + int GetSpeedSegmentIndexAtBeat( float fBeat ) const { return GetSpeedSegmentIndexAtRow( BeatToNoteRow(fBeat) ); } + /** + * @brief Add the SpeedSegment to the TimingData. + * @param seg the new SpeedSegment. + */ + void AddSpeedSegment( const SpeedSegment &seg ); + + + void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor ); void NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, int &iBeatIndexOut, int &iRowsRemainder ) const; @@ -1381,6 +1476,10 @@ public: * @return true if there is at least one warp, false otherwise. */ bool HasWarps() const; + /** + * @brief View the TimingData to see if a song changes its speed scrolling at any point. + * @return true if there is at least one change, false otherwise. */ + bool HasSpeedChanges() const; /** * @brief Compare two sets of timing data to see if they are equal. * @param other the other TimingData. From 640f8fe9fc3c9133c18db2afc67065877f93d3e2 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 14:05:02 -0400 Subject: [PATCH 122/197] [splittiming] PlayerOptions -> HasTimingChanges. Steps gained most of the functionality and lua doc. Leaving song version in: may still have a use thanks to #DISPLAYBPM. --- Docs/Luadoc/Lua.xml | 1 + Docs/Luadoc/LuaDocumentation.xml | 3 +++ src/PlayerOptions.cpp | 2 +- src/Steps.cpp | 18 ++++++++++++++++++ src/Steps.h | 5 +++++ 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index 966502afbc..dfb4c7cce3 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -1349,6 +1349,7 @@ + diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index 24492431aa..df9f17081b 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -3368,6 +3368,9 @@ Returns the numerical difficulty of the Steps. + + Returns true if the song has significant timing changes. + Returns the complete list of RadarValues for player pn. Use to grab a specific value. diff --git a/src/PlayerOptions.cpp b/src/PlayerOptions.cpp index 036f1d314c..cbfb031bbf 100644 --- a/src/PlayerOptions.cpp +++ b/src/PlayerOptions.cpp @@ -680,7 +680,7 @@ bool PlayerOptions::operator==( const PlayerOptions &other ) const bool PlayerOptions::IsEasierForSongAndSteps( Song* pSong, Steps* pSteps, PlayerNumber pn ) const { - if( m_fTimeSpacing && pSong->HasSignificantBpmChangesOrStops() ) + if( m_fTimeSpacing && pSteps->HasSignificantTimingChanges() ) return true; const RadarValues &rv = pSteps->GetRadarValues( pn ); if( m_bTransforms[TRANSFORM_NOHOLDS] && rv[RadarCategory_Holds]>0 ) diff --git a/src/Steps.cpp b/src/Steps.cpp index 5c2c91f063..3174e011b2 100644 --- a/src/Steps.cpp +++ b/src/Steps.cpp @@ -402,6 +402,21 @@ void Steps::SetMeter( int meter ) m_iMeter = meter; } +bool Steps::HasSignificantTimingChanges() const +{ + if( m_Timing.HasStops() ) + return true; + + /* TODO: Deal with DisplayBPM here...if possible? + * Song's version may still be useful. */ + + else if( m_Timing.HasBpmChanges() || m_Timing.HasWarps() || m_Timing.HasSpeedChanges() ) + { + return true; + } + return false; +} + void Steps::SetCachedRadarValues( const RadarValues v[NUM_PLAYERS] ) { DeAutogen(); @@ -426,6 +441,8 @@ public: DEFINE_METHOD( IsAnEdit, IsAnEdit() ) DEFINE_METHOD( IsAPlayerEdit, IsAPlayerEdit() ) + static int HasSignificantTimingChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasSignificantTimingChanges()); return 1; } + static int GetRadarValues( T* p, lua_State *L ) { PlayerNumber pn = Enum::Check(L, 1); @@ -454,6 +471,7 @@ public: ADD_METHOD( GetFilename ); ADD_METHOD( GetHash ); ADD_METHOD( GetMeter ); + ADD_METHOD( HasSignificantTimingChanges ); ADD_METHOD( GetRadarValues ); //ADD_METHOD( GetSMNoteData ); ADD_METHOD( GetStepsType ); diff --git a/src/Steps.h b/src/Steps.h index e796f99847..078295bc71 100644 --- a/src/Steps.h +++ b/src/Steps.h @@ -120,6 +120,11 @@ public: /** @brief Timing data */ TimingData m_Timing; + + /** + * @brief Determine if the Steps have any major timing changes during gameplay. + * @return true if it does, or false otherwise. */ + bool HasSignificantTimingChanges() const; // Lua void PushSelf( lua_State *L ); From 6975b9393a79d1a7f03c0964e44efc0bbd58a8bd Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sun, 15 May 2011 13:34:01 -0500 Subject: [PATCH 123/197] [splittiming] GetSongPosition works. --- src/GameState.cpp | 6 +++++- src/PlayerState.cpp | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index 9ed0c33f78..3b4f792986 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -2256,7 +2256,11 @@ public: DEFINE_METHOD( GetSongBPS, m_Position.m_fCurBPS ) DEFINE_METHOD( GetSongFreeze, m_Position.m_bFreeze ) DEFINE_METHOD( GetSongDelay, m_Position.m_bDelay )*/ - DEFINE_METHOD( GetSongPosition, m_Position ) + static int GetSongPosition( T* p, lua_State *L ) + { + p->m_Position.PushSelf(L); + return 1; + } DEFINE_METHOD( GetGameplayLeadIn, m_bGameplayLeadIn ) DEFINE_METHOD( GetCoins, m_iCoins ) DEFINE_METHOD( IsSideJoined, m_bSideIsJoined[Enum::Check(L, 1)] ) diff --git a/src/PlayerState.cpp b/src/PlayerState.cpp index ac76b0fbc2..9d7b652851 100644 --- a/src/PlayerState.cpp +++ b/src/PlayerState.cpp @@ -197,7 +197,11 @@ class LunaPlayerState: public Luna { public: DEFINE_METHOD( GetPlayerNumber, m_PlayerNumber ); - DEFINE_METHOD( GetSongPosition, m_Position ); + static int GetSongPosition( T* p, lua_State *L ) + { + p->m_Position.PushSelf(L); + return 1; + } DEFINE_METHOD( GetMultiPlayerNumber, m_mp ); DEFINE_METHOD( GetPlayerController, m_PlayerController ); static int SetPlayerOptions( T* p, lua_State *L ) @@ -247,6 +251,7 @@ public: ADD_METHOD( GetPlayerOptionsArray ); ADD_METHOD( GetPlayerOptionsString ); ADD_METHOD( GetCurrentPlayerOptions ); + ADD_METHOD( GetSongPosition ); ADD_METHOD( GetHealthState ); } }; From 3b684e8c20a62a922d2904620ec055ed776874d6 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 15:24:36 -0400 Subject: [PATCH 124/197] [splittiming] Write out the #SPEEDS tag. We're not incrementing the version due to 0.70 being the main one with Split Timing. If requested, maybe a version 0.64 or something. --- src/NotesLoaderSMA.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/NotesLoaderSMA.h | 1 + src/NotesLoaderSSC.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/NotesLoaderSSC.h | 1 + src/NotesWriterSSC.cpp | 9 +++++++++ 5 files changed, 95 insertions(+) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 16cbeaa1fe..fb7d1fb11d 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -306,6 +306,48 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) } } +void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ) +{ + vector vs1; + split( sParam, ",", vs1 ); + + FOREACH_CONST( RString, vs1, s1 ) + { + vector vs2; + split( *s1, "=", vs2 ); + + if( vs2[0] == 0 ) // First one always seems to have 2. + { + vs2.push_back(0); + } + + if( vs2.size() < 3 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with %i values.", (int)vs2.size() ); + continue; + } + + const float fBeat = RowToBeat( vs2[0], iRowsPerBeat ); + + SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] )); + + if( fBeat < 0 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f.", fBeat ); + continue; + } + + if( seg.m_fWait < 0 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, fWait %f.", fBeat, seg.m_fWait ); + continue; + } + + out.AddSpeedSegment( seg ); + } +} + + void SMALoader::LoadFromSMATokens( RString sStepsType, RString sDescription, diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 1c40b462f2..af397205fb 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -47,6 +47,7 @@ namespace SMALoader void ProcessDelays( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessTickcounts( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); + void ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ); float RowToBeat( RString sLine, const int iRowsPerBeat ); }; diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index b576d26ca0..8003a20754 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -126,6 +126,48 @@ void SSCLoader::ProcessCombos( TimingData &out, const RString sParam ) } } +void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) +{ + vector vs1; + split( sParam, ",", vs1 ); + + FOREACH_CONST( RString, vs1, s1 ) + { + vector vs2; + split( *s1, "=", vs2 ); + + if( vs2[0] == 0 ) // First one always seems to have 2. + { + vs2.push_back(0); + } + + if( vs2.size() < 3 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with %i values.", (int)vs2.size() ); + continue; + } + + const float fBeat = StringToFloat( vs2[0] ); + + SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] )); + + if( fBeat < 0 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f.", fBeat ); + continue; + } + + if( seg.m_fWait < 0 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, fWait %f.", fBeat, seg.m_fWait ); + continue; + } + + out.AddSpeedSegment( seg ); + } +} + + bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCache ) { LOG->Trace( "Song::LoadFromSSCFile(%s)", sPath.c_str() ); diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index 7d185cc690..c78231677b 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -80,6 +80,7 @@ namespace SSCLoader void ProcessWarps( TimingData &, const RString ); void ProcessLabels( TimingData &, const RString ); void ProcessCombos( TimingData &, const RString ); + void ProcessSpeeds( TimingData &, const RString ); } #endif /** diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 3e7882741e..3d036c538c 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -76,6 +76,7 @@ struct TimingTagWriter { void Write( const int row, const float value ) { Write( row, ssprintf( "%.6f", value ) ); } void Write( const int row, const int value ) { Write( row, ssprintf( "%d", value ) ); } void Write( const int row, const int a, const int b ) { Write( row, ssprintf( "%d=%d", a, b ) ); } + void Write( const int row, const float a, const float b ) { Write( row, ssprintf( "%.6f=%.6f", a, b) ); } void Init( const RString sTag ) { m_sNext = "#" + sTag + ":"; } void Finish( ) { m_pvsLines->push_back( ( m_sNext != "," ? m_sNext : "" ) + ";" ); } @@ -131,6 +132,14 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Write( cs->m_iStartRow, cs->m_iCombo ); w.Finish(); + if( !bIsSong ) + { + w.Init( "SPEEDS" ); + FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss ) + w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait ); + w.Finish(); + } + w.Init( "LABELS" ); FOREACH_CONST( LabelSegment, timing.m_LabelSegments, ls ) w.Write( ls->m_iStartRow, ls->m_sLabel.c_str() ); From ad1c4cabce7e318134601976aadfe450665f4a8b Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 15:27:02 -0400 Subject: [PATCH 125/197] [splittiming] Log typo. --- src/NotesLoaderSMA.cpp | 2 +- src/NotesLoaderSSC.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index fb7d1fb11d..6963b98ac9 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -339,7 +339,7 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS if( seg.m_fWait < 0 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, fWait %f.", fBeat, seg.m_fWait ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, fWait %f.", fBeat, seg.m_fWait ); continue; } diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 8003a20754..116f4c1d98 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -159,7 +159,7 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) if( seg.m_fWait < 0 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, fWait %f.", fBeat, seg.m_fWait ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, fWait %f.", fBeat, seg.m_fWait ); continue; } From cdd43f77f4ec4715e725619c0e54815552481c31 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 15:37:46 -0400 Subject: [PATCH 126/197] [splittiming] Display Speeds in Step Timing. --- Docs/Changelog_SSCformat.txt | 1 + Docs/Changelog_sm5.txt | 5 +++++ Themes/_fallback/metrics.ini | 9 ++++++--- src/NoteField.cpp | 34 +++++++++++++++++++++++++++++++++- src/NoteField.h | 1 + 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Docs/Changelog_SSCformat.txt b/Docs/Changelog_SSCformat.txt index fb04d68912..baa1f8ecc7 100644 --- a/Docs/Changelog_SSCformat.txt +++ b/Docs/Changelog_SSCformat.txt @@ -11,6 +11,7 @@ ________________________________________________________________________________ [v0.7] - theDtTvB, Wolfman2000 * Split Timing officially implemented. +* #SPEEDS tag for modified scroll speeds. [v0.59] - Wolfman2000 * Typo fix: #RADARVALUES needed a semicolon at the end, not a colon. diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index daf91cd16f..fccd9d9425 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -8,6 +8,11 @@ ________________________________________________________________________________ StepMania 5.0 $NEXT | 20110xyy -------------------------------------------------------------------------------- +2011/05/15 +---------- +* Added #SPEEDS to the SSC format. This multiplies your scrolling speed during + gameplay, not replaces it (see mod attacks for replacing). [Wolfman2000] + 2011/05/14 ---------- * [ModIcon] Added StopWords metric. [AJ] diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 4be294753a..ed69511b12 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -989,6 +989,7 @@ TimeSignatureColor=color("1,0.55,0,1") TickcountColor=color("0,1,0,1") ComboColor=color("0.55,1,0,1") LabelColor=color("1,0,0,1") +SpeedColor=color("0.5,1,1,1") # BPMIsLeftSide=true StopIsLeftSide=true @@ -998,15 +999,17 @@ TimeSignatureIsLeftSide=true TickcountIsLeftSide=false ComboIsLeftSide=false LabelIsLeftSide=false +SpeedIsLeftSide=false # BPMOffsetX=60 StopOffsetX=50 DelayOffsetX=120 WarpOffsetX=60 TimeSignatureOffsetX=30 -TickcountOffsetX=10 -ComboOffsetX=30 -LabelOffsetX=80 +TickcountOffsetX=105 +ComboOffsetX=95 +LabelOffsetX=120 +SpeedOffsetX=30 [PlayerStageStats] # Original CVS Grading diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 6982277071..c3aa03708c 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -454,6 +454,7 @@ static ThemeMetric TIME_SIGNATURE_COLOR ( "NoteField", "TimeSignature static ThemeMetric TICKCOUNT_COLOR ( "NoteField", "TickcountColor" ); static ThemeMetric COMBO_COLOR ( "NoteField", "ComboColor" ); static ThemeMetric LABEL_COLOR ( "NoteField", "LabelColor" ); +static ThemeMetric SPEED_COLOR ( "NoteField", "SpeedColor" ); static ThemeMetric BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" ); static ThemeMetric STOP_IS_LEFT_SIDE ( "NoteField", "StopIsLeftSide" ); static ThemeMetric DELAY_IS_LEFT_SIDE ( "NoteField", "DelayIsLeftSide" ); @@ -462,6 +463,7 @@ static ThemeMetric TIME_SIGNATURE_IS_LEFT_SIDE ( "NoteField", "TimeSignatu static ThemeMetric TICKCOUNT_IS_LEFT_SIDE ( "NoteField", "TickcountIsLeftSide" ); static ThemeMetric COMBO_IS_LEFT_SIDE ( "NoteField", "ComboIsLeftSide" ); static ThemeMetric LABEL_IS_LEFT_SIDE ( "NoteField", "LabelIsLeftSide" ); +static ThemeMetric SPEED_IS_LEFT_SIDE ( "NoteField", "SpeedIsLeftSide" ); static ThemeMetric BPM_OFFSETX ( "NoteField", "BPMOffsetX" ); static ThemeMetric STOP_OFFSETX ( "NoteField", "StopOffsetX" ); static ThemeMetric DELAY_OFFSETX ( "NoteField", "DelayOffsetX" ); @@ -470,7 +472,7 @@ static ThemeMetric TIME_SIGNATURE_OFFSETX ( "NoteField", "TimeSignatureOf static ThemeMetric TICKCOUNT_OFFSETX ( "NoteField", "TickcountOffsetX" ); static ThemeMetric COMBO_OFFSETX ( "NoteField", "ComboOffsetX" ); static ThemeMetric LABEL_OFFSETX ( "NoteField", "LabelOffsetX" ); - +static ThemeMetric SPEED_OFFSETX ( "NoteField", "SpeedOffsetX" ); void NoteField::DrawBPMText( const float fBeat, const float fBPM ) { @@ -600,6 +602,23 @@ void NoteField::DrawLabelText( const float fBeat, RString sLabel ) m_textMeasureNumber.Draw(); } +void NoteField::DrawSpeedText( const float fBeat, float fPercent, float fWait ) +{ + const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat ); + const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels ); + const float fZoom = ArrowEffects::GetZoom( m_pPlayerState ); + const float xBase = GetWidth()/2.f; + const float xOffset = SPEED_OFFSETX * fZoom; + + m_textMeasureNumber.SetZoom( fZoom ); + m_textMeasureNumber.SetHorizAlign( SPEED_IS_LEFT_SIDE ? align_right : align_left ); + m_textMeasureNumber.SetDiffuse( SPEED_COLOR ); + m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) ); + m_textMeasureNumber.SetText( ssprintf("%.6f\n--\n%.6f", fPercent, fWait) ); + m_textMeasureNumber.SetXY( (SPEED_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos ); + m_textMeasureNumber.Draw(); +} + void NoteField::DrawAttackText( const float fBeat, const Attack &attack ) { const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat ); @@ -913,6 +932,19 @@ void NoteField::DrawPrimitives() DrawLabelText( fBeat, seg->m_sLabel ); } } + + if( GAMESTATE->m_bIsEditorStepTiming ) + { + FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, seg ) + { + if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + { + float fBeat = NoteRowToBeat(seg->m_iStartRow); + if( IS_ON_SCREEN(fBeat) ) + DrawSpeedText( fBeat, seg->m_fPercent, seg->m_fWait ); + } + } + } // Course mods text const Course *pCourse = GAMESTATE->m_pCurCourse; diff --git a/src/NoteField.h b/src/NoteField.h index c389676cfb..5cd582b322 100644 --- a/src/NoteField.h +++ b/src/NoteField.h @@ -64,6 +64,7 @@ protected: void DrawTickcountText( const float fBeat, int iTicks ); void DrawComboText( const float fBeat, int iCombo ); void DrawLabelText( const float fBeat, RString sLabel ); + void DrawSpeedText( const float fBeat, float fPercent, float fWait ); void DrawAttackText( const float fBeat, const Attack &attack ); void DrawBGChangeText( const float fBeat, const RString sNewBGName ); float GetWidth() const; From 466f0be35a898a16164fd5581d83800d00b92ee9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 15:53:20 -0400 Subject: [PATCH 127/197] [splittiming] ScreenEdit + Speeds Now let's try to implement the darn things. --- Themes/_fallback/Languages/en.ini | 4 +++ src/ScreenEdit.cpp | 44 ++++++++++++++++++++++++++++++- src/ScreenEdit.h | 3 +++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 5221f213de..cca665ecc4 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -852,6 +852,8 @@ Edit tickcount=Edit tickcount Edit combo=Edit combo Edit label=Edit label Edit warp=Edit warp +Edit speed (percent)=Edit speed (percent) +Edit speed (wait)=Edit speed (wait in beats) Editor options=Options EditorShowBGChangesPlay=Show Backgrounds Erase step timing=Erase step timing @@ -1227,6 +1229,8 @@ Enter a new Tickcount value.=Enter a new Tickcount value. Enter a new Combo value.=Enter a new Combo value. Enter a new Label value.=Enter a name for this section of the chart. Enter a new Warp value.=Enter the beat you will warp to when you reach this point. +Enter a new Speed percent value.=Enter the ratio for speed scrolling. 1 is the default. +Enter a new Speed wait value.=Enter how long in beats it takes to change. 0 is instant. Are you sure you want to erase this chart's timing data?=Are you sure you want to erase this chart's timing data? Enter a new artist transliteration.=Enter a new artist transliteration. Enter a new artist.=Enter a new artist. diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 38ff20c18a..aba80b9090 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -83,6 +83,8 @@ AutoScreenMessage( SM_BackFromTickcountChange ); AutoScreenMessage( SM_BackFromComboChange ); AutoScreenMessage( SM_BackFromLabelChange ); AutoScreenMessage( SM_BackFromWarpChange ); +AutoScreenMessage( SM_BackFromSpeedPercentChange ); +AutoScreenMessage( SM_BackFromSpeedWaitChange ); AutoScreenMessage( SM_DoEraseStepTiming ); AutoScreenMessage( SM_DoSaveAndExit ); AutoScreenMessage( SM_DoExit ); @@ -576,7 +578,9 @@ static MenuDef g_TimingDataInformation( MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::combo, "Edit combo", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::erase_step_timing, "Erase step timing", true, EditMode_Full, true, true, 0, NULL ) + MenuRowDef( ScreenEdit::speed_percent, "Edit speed (percent)", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::speed_wait, "Edit speed (wait)", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::erase_step_timing, "Erase step timing", true, EditMode_Full, true, true, 0, NULL ) ); enum { song_bganimation, song_movie, song_bitmap, global_bganimation, global_movie, global_movie_song_group, global_movie_song_group_and_genre, dynamic_random, baked_random, none }; @@ -2759,6 +2763,22 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) GetAppropriateTiming().SetWarpAtBeat( GetBeat(), fWarp ); SetDirty( true ); } + else if( SM == SM_BackFromSpeedPercentChange ) + { + float fNum = StringToFloat( ScreenTextEntry::s_sLastAnswer ); + GetAppropriateTiming().SetSpeedPercentAtBeat( GetBeat(), fNum ); + SetDirty( true ); + } + else if ( SM == SM_BackFromSpeedWaitChange ) + { + float fDen = StringToFloat( ScreenTextEntry::s_sLastAnswer ); + if( fDen >= 0) + { + GetAppropriateTiming().SetSpeedWaitAtBeat( GetBeat(), fDen ); + } + SetDirty( true ); + } + else if( SM == SM_BackFromBGChange ) { HandleBGChangeChoice( (BGChangeChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); @@ -3176,10 +3196,14 @@ void ScreenEdit::DisplayTimingMenu() g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetWarpAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[speed_percent].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetSpeedPercentAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[speed_wait].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetSpeedWaitAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[combo].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[warp].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_TimingDataInformation.rows[speed_percent].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_TimingDataInformation.rows[speed_wait].bEnabled = GAMESTATE->m_bIsEditorStepTiming; EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); } @@ -3858,6 +3882,8 @@ static LocalizedString ENTER_TICKCOUNT_VALUE ( "ScreenEdit", "Enter a new Tick static LocalizedString ENTER_COMBO_VALUE ( "ScreenEdit", "Enter a new Combo value." ); static LocalizedString ENTER_LABEL_VALUE ( "ScreenEdit", "Enter a new Label value." ); static LocalizedString ENTER_WARP_VALUE ( "ScreenEdit", "Enter a new Warp value." ); +static LocalizedString ENTER_SPEED_PERCENT_VALUE ( "ScreenEdit", "Enter a new Speed percent value." ); +static LocalizedString ENTER_SPEED_WAIT_VALUE ( "ScreenEdit", "Enter a new Speed wait value." ); static LocalizedString CONFIRM_TIMING_ERASE ( "ScreenEdit", "Are you sure you want to erase this chart's timing data?" ); void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice c, const vector &iAnswers ) { @@ -3941,6 +3967,22 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice 10 ); break; + case speed_percent: + ScreenTextEntry::TextEntry( + SM_BackFromSpeedPercentChange, + ENTER_SPEED_PERCENT_VALUE, + ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).m_fPercent ), + 10 + ); + break; + case speed_wait: + ScreenTextEntry::TextEntry( + SM_BackFromSpeedWaitChange, + ENTER_SPEED_WAIT_VALUE, + ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).m_fWait ), + 10 + ); + break; case erase_step_timing: ScreenPrompt::Prompt( SM_DoEraseStepTiming, CONFIRM_TIMING_ERASE , PROMPT_YES_NO, ANSWER_NO ); break; diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 68eabff5f5..0f31a3e759 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -496,6 +496,9 @@ public: tickcount, combo, warp, +// speed, + speed_percent, + speed_wait, erase_step_timing, NUM_TIMING_DATA_INFORMATION_CHOICES }; From 6db40f034aa5f671e5223f92dcb43719002c7cbc Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 16:07:18 -0400 Subject: [PATCH 128/197] [splittiming] Core lines set for #SPEEDS. Let's see how badly this breaks. --- src/ArrowEffects.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index e6f3831849..15ea4eb0c0 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -230,7 +230,8 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float float fSongBeat = position.m_fSongBeatVisible; float fBeatsUntilStep = fNoteBeat - fSongBeat; float fYOffsetBeatSpacing = fBeatsUntilStep; - fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); + fYOffset += GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing.GetSpeedPercentAtBeat( fNoteBeat ) * + fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); } if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f ) @@ -241,7 +242,8 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float float fBPM = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollBPM; float fBPS = fBPM/60.f; float fYOffsetTimeSpacing = fSecondsUntilStep * fBPS; - fYOffset += fYOffsetTimeSpacing * pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing; + fYOffset += GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing.GetSpeedPercentAtBeat( fNoteBeat ) * + fYOffsetTimeSpacing * pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing; } // TODO: If we allow noteskins to have metricable row spacing From 59febf0c2736078734bd2a5352f7a90abac5479c Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 16:13:56 -0400 Subject: [PATCH 129/197] [splittiming] Adjusted too much there. --- Themes/_fallback/metrics.ini | 8 ++++---- src/NoteField.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index ed69511b12..867f07e5fe 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -1004,11 +1004,11 @@ SpeedIsLeftSide=false BPMOffsetX=60 StopOffsetX=50 DelayOffsetX=120 -WarpOffsetX=60 +WarpOffsetX=70 TimeSignatureOffsetX=30 -TickcountOffsetX=105 -ComboOffsetX=95 -LabelOffsetX=120 +TickcountOffsetX=50 +ComboOffsetX=30 +LabelOffsetX=130 SpeedOffsetX=30 [PlayerStageStats] diff --git a/src/NoteField.cpp b/src/NoteField.cpp index c3aa03708c..f94cb62e9e 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -614,7 +614,7 @@ void NoteField::DrawSpeedText( const float fBeat, float fPercent, float fWait ) m_textMeasureNumber.SetHorizAlign( SPEED_IS_LEFT_SIDE ? align_right : align_left ); m_textMeasureNumber.SetDiffuse( SPEED_COLOR ); m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) ); - m_textMeasureNumber.SetText( ssprintf("%.6f\n--\n%.6f", fPercent, fWait) ); + m_textMeasureNumber.SetText( ssprintf("%.3f\n--\n%.3f", fPercent, fWait) ); m_textMeasureNumber.SetXY( (SPEED_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos ); m_textMeasureNumber.Draw(); } From 11de86e2601b2c52e568433e1d822a3c795bb0e0 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 16:40:06 -0400 Subject: [PATCH 130/197] [splittiming] Right, LOAD the #SPEEDS. --- src/NotesLoaderSMA.cpp | 4 +++- src/NotesLoaderSSC.cpp | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 6963b98ac9..6acec86ced 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -667,7 +667,9 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) else if( sValueName=="SPEED" ) { - ; // This is something we should consider implementing. + TimingData &timing = (state == SMA_GETTING_STEP_INFO + ? pNewNotes->m_Timing : out.m_SongTiming); + ProcessSpeeds( timing, iRowsPerBeat, sParams[1] ); } else if( sValueName=="MULTIPLIER" ) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 116f4c1d98..68a2886042 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -558,6 +558,11 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach ProcessWarps(stepsTiming, sParams[1]); } + else if( sValueName=="SPEED" ) + { + ProcessSpeeds( stepsTiming, sParams[1] ); + } + else if( sValueName=="LABELS" ) { ProcessLabels(stepsTiming, sParams[1]); From c25c9616d965314b23b4aa90b62ae4227b967d99 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 16:42:50 -0400 Subject: [PATCH 131/197] [splittiming] Minor fix. --- Themes/_fallback/metrics.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 867f07e5fe..3189c3444e 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -1004,10 +1004,10 @@ SpeedIsLeftSide=false BPMOffsetX=60 StopOffsetX=50 DelayOffsetX=120 -WarpOffsetX=70 +WarpOffsetX=90 TimeSignatureOffsetX=30 -TickcountOffsetX=50 -ComboOffsetX=30 +TickcountOffsetX=70 +ComboOffsetX=50 LabelOffsetX=130 SpeedOffsetX=30 From a0d3d9d6ee4febdbce4ab8c9e4f8e75950cb5f4c Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 16:56:35 -0400 Subject: [PATCH 132/197] [splittiming] SPEEDS! --- src/NotesLoaderSSC.cpp | 2 +- src/NotesWriterSSC.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 68a2886042..e01e4dd774 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -558,7 +558,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach ProcessWarps(stepsTiming, sParams[1]); } - else if( sValueName=="SPEED" ) + else if( sValueName=="SPEEDS" ) { ProcessSpeeds( stepsTiming, sParams[1] ); } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 3d036c538c..d65ddc9f13 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -136,7 +136,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo { w.Init( "SPEEDS" ); FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss ) - w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait ); + w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait ); w.Finish(); } From 87ac80c33fb36587cb697e91652096736a6cb713 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 17:14:18 -0400 Subject: [PATCH 133/197] [splittiming] We know this doesn't work. Time to find what does. --- src/ArrowEffects.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 15ea4eb0c0..e6f3831849 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -230,8 +230,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float float fSongBeat = position.m_fSongBeatVisible; float fBeatsUntilStep = fNoteBeat - fSongBeat; float fYOffsetBeatSpacing = fBeatsUntilStep; - fYOffset += GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing.GetSpeedPercentAtBeat( fNoteBeat ) * - fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); + fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); } if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f ) @@ -242,8 +241,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float float fBPM = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollBPM; float fBPS = fBPM/60.f; float fYOffsetTimeSpacing = fSecondsUntilStep * fBPS; - fYOffset += GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing.GetSpeedPercentAtBeat( fNoteBeat ) * - fYOffsetTimeSpacing * pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing; + fYOffset += fYOffsetTimeSpacing * pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing; } // TODO: If we allow noteskins to have metricable row spacing From 231f9433c3b360267955b884ca6b58b72e871ee3 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 17:39:57 -0400 Subject: [PATCH 134/197] [splittiming] Speed Changes working...somewhat. There needs to be some more math involving the beats. --- src/ArrowEffects.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index e6f3831849..f8de8cfbdd 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -222,12 +222,15 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float float fYOffset = 0; const SongPosition &position = (!GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsEditorStepTiming) ? pPlayerState->m_Position : GAMESTATE->m_Position; + + float fSongBeat = position.m_fSongBeatVisible; + + Steps *pCurSteps = GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]; /* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or * entirely time spacing (respectively). Occasionally, we tween between them. */ if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f ) { - float fSongBeat = position.m_fSongBeatVisible; float fBeatsUntilStep = fNoteBeat - fSongBeat; float fYOffsetBeatSpacing = fBeatsUntilStep; fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); @@ -235,8 +238,8 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f ) { - float fSongSeconds = position.m_fMusicSecondsVisible; - float fNoteSeconds = GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber]->m_Timing.GetElapsedTimeFromBeat(fNoteBeat); + float fSongSeconds = GAMESTATE->m_Position.m_fMusicSecondsVisible; + float fNoteSeconds = pCurSteps->m_Timing.GetElapsedTimeFromBeat(fNoteBeat); float fSecondsUntilStep = fNoteSeconds - fSongSeconds; float fBPM = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollBPM; float fBPS = fBPM/60.f; @@ -246,7 +249,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float // TODO: If we allow noteskins to have metricable row spacing // (per issue 24), edit this to reflect that. -aj - fYOffset *= ARROW_SPACING; + fYOffset *= ARROW_SPACING * pCurSteps->m_Timing.GetSpeedPercentAtBeat( fSongBeat ); // don't mess with the arrows after they've crossed 0 if( fYOffset < 0 ) @@ -293,6 +296,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float // Factor in scroll speed float fScrollSpeed = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed; + if( pPlayerState->m_PlayerOptions.GetCurrent().m_fRandomSpeed > 0 && !bAbsolute ) { // Generate a deterministically "random" speed for each arrow. From 300360a6125367af7d80d878de87e32b8fb8ee30 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 17:45:21 -0400 Subject: [PATCH 135/197] [splittiming] Setup for math fun. Feels like we're doing trig or calculus here. --- src/ArrowEffects.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index f8de8cfbdd..3224b0cb76 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -249,8 +249,15 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float // TODO: If we allow noteskins to have metricable row spacing // (per issue 24), edit this to reflect that. -aj - fYOffset *= ARROW_SPACING * pCurSteps->m_Timing.GetSpeedPercentAtBeat( fSongBeat ); - + fYOffset *= ARROW_SPACING; + + // Factor in the SpeedSegment. + SpeedSegment &seg = pCurSteps->m_Timing.GetSpeedSegmentAtBeat( fSongBeat ); + if( seg.m_fPercent != 1 && fSongBeat + seg.m_fWait <= fNoteBeat ) + { + // Math here. + fYOffset *= pCurSteps->m_Timing.GetSpeedPercentAtBeat( fSongBeat ); + } // don't mess with the arrows after they've crossed 0 if( fYOffset < 0 ) return fYOffset * pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed; From e9bcdc5568980d584cc43c6713d43c5ad95f4b3a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 18:15:52 -0400 Subject: [PATCH 136/197] [splittiming] Kind of getting there... --- src/ArrowEffects.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 3224b0cb76..9e96ee8111 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -253,10 +253,23 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float // Factor in the SpeedSegment. SpeedSegment &seg = pCurSteps->m_Timing.GetSpeedSegmentAtBeat( fSongBeat ); - if( seg.m_fPercent != 1 && fSongBeat + seg.m_fWait <= fNoteBeat ) + if( seg.m_fPercent != 1 ) { - // Math here. - fYOffset *= pCurSteps->m_Timing.GetSpeedPercentAtBeat( fSongBeat ); + if( fSongBeat + seg.m_fWait <= fNoteBeat ) + { + float fBeatsUsed = fSongBeat - NoteRowToBeat(seg.m_iStartRow); + float fRatioUsed = fBeatsUsed / seg.m_fWait; + + float fDistance = 1 - seg.m_fPercent; + + float fRatioNeed = fRatioUsed * fDistance; + + fYOffset *= (1 + fRatioNeed); + } + else + { + fYOffset *= seg.m_fPercent; + } } // don't mess with the arrows after they've crossed 0 if( fYOffset < 0 ) From eb5ae94f070ae0cd624c2925e19fadc8fd1f1527 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 18:33:47 -0400 Subject: [PATCH 137/197] [splittiming] Follow Daisu's lua a little more. --- src/ArrowEffects.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 9e96ee8111..3fe128a777 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -255,9 +255,11 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float SpeedSegment &seg = pCurSteps->m_Timing.GetSpeedSegmentAtBeat( fSongBeat ); if( seg.m_fPercent != 1 ) { - if( fSongBeat + seg.m_fWait <= fNoteBeat ) + float fStartBeat = NoteRowToBeat(seg.m_iStartRow); + + if( fStartBeat + seg.m_fWait >= fSongBeat ) { - float fBeatsUsed = fSongBeat - NoteRowToBeat(seg.m_iStartRow); + float fBeatsUsed = fSongBeat - fStartBeat; float fRatioUsed = fBeatsUsed / seg.m_fWait; float fDistance = 1 - seg.m_fPercent; From 183e74553433312ac9d103148131129c1c8092db Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 18:57:04 -0400 Subject: [PATCH 138/197] [splittiming] Of course...negative inverse. --- src/ArrowEffects.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 3fe128a777..1db9a40903 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -261,11 +261,8 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float { float fBeatsUsed = fSongBeat - fStartBeat; float fRatioUsed = fBeatsUsed / seg.m_fWait; - float fDistance = 1 - seg.m_fPercent; - - float fRatioNeed = fRatioUsed * fDistance; - + float fRatioNeed = fRatioUsed * -fDistance; fYOffset *= (1 + fRatioNeed); } else From f36121e6479180ab34683e634733f277d945817e Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 19:39:14 -0400 Subject: [PATCH 139/197] [splittiming] Remember transitions to 1x. --- src/ArrowEffects.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 1db9a40903..1719b7e1dc 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -252,18 +252,23 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float fYOffset *= ARROW_SPACING; // Factor in the SpeedSegment. - SpeedSegment &seg = pCurSteps->m_Timing.GetSpeedSegmentAtBeat( fSongBeat ); - if( seg.m_fPercent != 1 ) + TimingData &tim = pCurSteps->m_Timing; + + const int index = tim.GetSpeedSegmentIndexAtBeat( fSongBeat ); + if( index > 0 ) { + SpeedSegment &seg = tim.GetSpeedSegmentAtBeat( fSongBeat ); float fStartBeat = NoteRowToBeat(seg.m_iStartRow); if( fStartBeat + seg.m_fWait >= fSongBeat ) { + const float fPriorSpeed = tim.m_SpeedSegments[index - 1].m_fPercent; float fBeatsUsed = fSongBeat - fStartBeat; float fRatioUsed = fBeatsUsed / seg.m_fWait; - float fDistance = 1 - seg.m_fPercent; + + float fDistance = fPriorSpeed - seg.m_fPercent; float fRatioNeed = fRatioUsed * -fDistance; - fYOffset *= (1 + fRatioNeed); + fYOffset *= (fPriorSpeed + fRatioNeed); } else { From c830bf81fe10eb291fca27bb4ab402a8c5529386 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 21:15:53 -0400 Subject: [PATCH 140/197] [splittiming] Attempt at Speed Segment control. Working on another fix, will test this second. --- src/ScreenEdit.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index aba80b9090..31f6da17fd 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2438,7 +2438,7 @@ void ScreenEdit::TransitionEditState( EditState em ) // Restore the cursor position + Quantize + Clamp SetBeat( max( 0, Quantize( m_fBeatToReturnTo, NoteTypeToBeat(m_SnapDisplay.GetNoteType()) ) ) ); - + GAMESTATE->m_bInStepEditor = true; break; case STATE_PLAYING: @@ -2458,10 +2458,11 @@ void ScreenEdit::TransitionEditState( EditState em ) // XXX // GAMESTATE->ResetNoteSkins(); //GAMESTATE->res - + GAMESTATE->m_bInStepEditor = false; break; } case STATE_RECORDING_PAUSED: + GAMESTATE->m_bInStepEditor = false; break; } From 58b209959f737f9c658d0470b4291a888fe097f9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 21:22:17 -0400 Subject: [PATCH 141/197] [splittiming] Fix minor load issue on SPEEDS. --- src/NotesLoaderSMA.cpp | 4 ++-- src/NotesLoaderSSC.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 6acec86ced..ba85057746 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -316,9 +316,9 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS vector vs2; split( *s1, "=", vs2 ); - if( vs2[0] == 0 ) // First one always seems to have 2. + if( RowToBeat(vs2[0], iRowsPerBeat) == 0 ) // First one always seems to have 2. { - vs2.push_back(0); + vs2.push_back("0"); } if( vs2.size() < 3 ) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index e01e4dd774..1803b03f51 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -138,7 +138,7 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) if( vs2[0] == 0 ) // First one always seems to have 2. { - vs2.push_back(0); + vs2.push_back("0"); } if( vs2.size() < 3 ) From 275bb63ca0dd203f2c7d6a15aedb7f42e509ac67 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 21:24:39 -0400 Subject: [PATCH 142/197] [splittiming] Don't show SPEEDS in pure editor. --- src/ArrowEffects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 1719b7e1dc..047a5331af 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -255,7 +255,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float TimingData &tim = pCurSteps->m_Timing; const int index = tim.GetSpeedSegmentIndexAtBeat( fSongBeat ); - if( index > 0 ) + if( !GAMESTATE->m_bInStepEditor && index > 0 ) { SpeedSegment &seg = tim.GetSpeedSegmentAtBeat( fSongBeat ); float fStartBeat = NoteRowToBeat(seg.m_iStartRow); From 059f0357ba5e6ba4eb9a275c7fbe5f849d441bdb Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 21:28:44 -0400 Subject: [PATCH 143/197] [splittiming] Allow #COMBOS to be 0. --- src/TimingData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TimingData.h b/src/TimingData.h index d68e2ec98e..9a4d67d6f1 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -508,7 +508,7 @@ struct ComboSegment * @param t the amount the combo increases on a succesful hit. */ ComboSegment( int s, int t ): m_iStartRow(max(0, s)), - m_iCombo(max(1,t)) {} + m_iCombo(max(0,t)) {} /** * @brief The row in which the ComboSegment activates. */ From 59bbc4f4bd9e63211bb0fbce35806d4b17707707 Mon Sep 17 00:00:00 2001 From: Flameshadowxeroshin Date: Sun, 15 May 2011 21:58:15 -0500 Subject: [PATCH 144/197] [splittiming] hey it's GetTimingData for freem --- src/Steps.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Steps.cpp b/src/Steps.cpp index 3174e011b2..2a877d545b 100644 --- a/src/Steps.cpp +++ b/src/Steps.cpp @@ -451,6 +451,12 @@ public: return 1; } + static int GetTimingData( T* p, lua_State *L ) + { + p->m_SongTiming.PushSelf(L); + return 1; + } + static int GetHash( T* p, lua_State *L ) { lua_pushnumber( L, p->GetHash() ); return 1; } // untested @@ -461,6 +467,7 @@ public: lua_pushstring( L, out ); return 1; } + LunaSteps() { @@ -473,6 +480,7 @@ public: ADD_METHOD( GetMeter ); ADD_METHOD( HasSignificantTimingChanges ); ADD_METHOD( GetRadarValues ); + ADD_METHOD( GetTimingData ); //ADD_METHOD( GetSMNoteData ); ADD_METHOD( GetStepsType ); ADD_METHOD( IsAnEdit ); From e2766cf644d1731376f7a44e464952cc0ac65569 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sun, 15 May 2011 23:48:03 -0400 Subject: [PATCH 145/197] [splittiming] SpeedSegments run on Seconds now. ScreenEdit's code probably needs to be redone. At least, someone find a way to remove "Beats" or "Seconds" from the text entry area. --- Themes/_fallback/Languages/en.ini | 10 +++-- src/ArrowEffects.cpp | 18 ++++++-- src/NoteField.cpp | 6 +-- src/NoteField.h | 2 +- src/NotesLoaderSMA.cpp | 10 ++++- src/NotesLoaderSSC.cpp | 9 +++- src/NotesWriterSSC.cpp | 4 +- src/ScreenEdit.cpp | 34 +++++++++++++++ src/ScreenEdit.h | 7 +++ src/TimingData.cpp | 34 ++++++++++++--- src/TimingData.h | 71 +++++++++++++++++++++++++++---- 11 files changed, 177 insertions(+), 28 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index cca665ecc4..4267bfe208 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -558,6 +558,7 @@ Baked Random=Baked Random Bar=Bar Battery=Battery Beat=Beat +Beats=Beats Big=Big Blind=Blind Blink=Blink @@ -694,6 +695,7 @@ Right=Right Roll=Roll Romanization=Transliterate SHOW=Show +Seconds=Seconds Select=Select Servers=Servers Shift Left=Shift Left @@ -853,7 +855,8 @@ Edit combo=Edit combo Edit label=Edit label Edit warp=Edit warp Edit speed (percent)=Edit speed (percent) -Edit speed (wait)=Edit speed (wait in beats) +Edit speed (wait)=Edit speed (length) +Edit speed (mode)=Edit speed (mode) Editor options=Options EditorShowBGChangesPlay=Show Backgrounds Erase step timing=Erase step timing @@ -1229,8 +1232,9 @@ Enter a new Tickcount value.=Enter a new Tickcount value. Enter a new Combo value.=Enter a new Combo value. Enter a new Label value.=Enter a name for this section of the chart. Enter a new Warp value.=Enter the beat you will warp to when you reach this point. -Enter a new Speed percent value.=Enter the ratio for speed scrolling. 1 is the default. -Enter a new Speed wait value.=Enter how long in beats it takes to change. 0 is instant. +Enter a new Speed percent value.=Enter the ratio for speed scrolling.\n\n1 is the default scroll. +Enter a new Speed wait value.=Enter how long in seconds/beats it takes to change.\n\n0 is instant. +Enter a new Speed mode value.=Enter how this segment is handled.\n\nType "0" for beats, "1" for seconds. Are you sure you want to erase this chart's timing data?=Are you sure you want to erase this chart's timing data? Enter a new artist transliteration.=Enter a new artist transliteration. Enter a new artist.=Enter a new artist. diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 047a5331af..b2b6d60941 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -259,12 +259,24 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float { SpeedSegment &seg = tim.GetSpeedSegmentAtBeat( fSongBeat ); float fStartBeat = NoteRowToBeat(seg.m_iStartRow); + float fStartTime = tim.GetElapsedTimeFromBeat( fStartBeat ); + float fEndTime; - if( fStartBeat + seg.m_fWait >= fSongBeat ) + if( seg.m_usMode == 1 ) // seconds + { + fEndTime = fStartTime + seg.m_fWait; + } + else + { + fEndTime = tim.GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ); + } + float fCurTime = tim.GetElapsedTimeFromBeat( fSongBeat ); + + if( fEndTime >= fCurTime ) { const float fPriorSpeed = tim.m_SpeedSegments[index - 1].m_fPercent; - float fBeatsUsed = fSongBeat - fStartBeat; - float fRatioUsed = fBeatsUsed / seg.m_fWait; + float fTimeUsed = fCurTime - fStartTime; + float fRatioUsed = fTimeUsed / (fEndTime - fStartTime); float fDistance = fPriorSpeed - seg.m_fPercent; float fRatioNeed = fRatioUsed * -fDistance; diff --git a/src/NoteField.cpp b/src/NoteField.cpp index f94cb62e9e..1ad62d255b 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -602,7 +602,7 @@ void NoteField::DrawLabelText( const float fBeat, RString sLabel ) m_textMeasureNumber.Draw(); } -void NoteField::DrawSpeedText( const float fBeat, float fPercent, float fWait ) +void NoteField::DrawSpeedText( const float fBeat, float fPercent, float fWait, unsigned short usMode ) { const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat ); const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels ); @@ -614,7 +614,7 @@ void NoteField::DrawSpeedText( const float fBeat, float fPercent, float fWait ) m_textMeasureNumber.SetHorizAlign( SPEED_IS_LEFT_SIDE ? align_right : align_left ); m_textMeasureNumber.SetDiffuse( SPEED_COLOR ); m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) ); - m_textMeasureNumber.SetText( ssprintf("%.3f\n--\n%.3f", fPercent, fWait) ); + m_textMeasureNumber.SetText( ssprintf("%.3f\n%s\n%.3f", fPercent, (usMode == 1 ? "S" : "B"), fWait) ); m_textMeasureNumber.SetXY( (SPEED_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos ); m_textMeasureNumber.Draw(); } @@ -941,7 +941,7 @@ void NoteField::DrawPrimitives() { float fBeat = NoteRowToBeat(seg->m_iStartRow); if( IS_ON_SCREEN(fBeat) ) - DrawSpeedText( fBeat, seg->m_fPercent, seg->m_fWait ); + DrawSpeedText( fBeat, seg->m_fPercent, seg->m_fWait, seg->m_usMode ); } } } diff --git a/src/NoteField.h b/src/NoteField.h index 5cd582b322..b3993fd6f6 100644 --- a/src/NoteField.h +++ b/src/NoteField.h @@ -64,7 +64,7 @@ protected: void DrawTickcountText( const float fBeat, int iTicks ); void DrawComboText( const float fBeat, int iCombo ); void DrawLabelText( const float fBeat, RString sLabel ); - void DrawSpeedText( const float fBeat, float fPercent, float fWait ); + void DrawSpeedText( const float fBeat, float fPercent, float fWait, unsigned short usMode ); void DrawAttackText( const float fBeat, const Attack &attack ); void DrawBGChangeText( const float fBeat, const RString sNewBGName ); float GetWidth() const; diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index ba85057746..23dd584691 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -306,6 +306,11 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) } } +float BeatToSeconds(float fromBeat, RString toSomething) +{ + return 0; +} + void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ) { vector vs1; @@ -329,7 +334,10 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS const float fBeat = RowToBeat( vs2[0], iRowsPerBeat ); - SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] )); + unsigned short tmp = ( (vs2[2].find("s") || vs2[2].find("S") ) + ? 1 : 0); + + SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] ), tmp); if( fBeat < 0 ) { diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 1803b03f51..352387e7df 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -141,7 +141,12 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) vs2.push_back("0"); } - if( vs2.size() < 3 ) + if( vs2.size() == 3 ) + { + vs2.push_back("0"); + } + + if( vs2.size() < 4 ) { LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with %i values.", (int)vs2.size() ); continue; @@ -149,7 +154,7 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) const float fBeat = StringToFloat( vs2[0] ); - SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] )); + SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] ), static_cast(StringToInt(vs2[3]))); if( fBeat < 0 ) { diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index d65ddc9f13..3b7c4ae729 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -77,6 +77,8 @@ struct TimingTagWriter { void Write( const int row, const int value ) { Write( row, ssprintf( "%d", value ) ); } void Write( const int row, const int a, const int b ) { Write( row, ssprintf( "%d=%d", a, b ) ); } void Write( const int row, const float a, const float b ) { Write( row, ssprintf( "%.6f=%.6f", a, b) ); } + void Write( const int row, const float a, const float b, const unsigned short c ) + { Write( row, ssprintf( "%.6f=%.6f=%hd", a, b, c) ); } void Init( const RString sTag ) { m_sNext = "#" + sTag + ":"; } void Finish( ) { m_pvsLines->push_back( ( m_sNext != "," ? m_sNext : "" ) + ";" ); } @@ -136,7 +138,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo { w.Init( "SPEEDS" ); FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss ) - w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait ); + w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait, ss->m_usMode ); w.Finish(); } diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 31f6da17fd..0851795b87 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -85,6 +85,7 @@ AutoScreenMessage( SM_BackFromLabelChange ); AutoScreenMessage( SM_BackFromWarpChange ); AutoScreenMessage( SM_BackFromSpeedPercentChange ); AutoScreenMessage( SM_BackFromSpeedWaitChange ); +AutoScreenMessage( SM_BackFromSpeedModeChange ); AutoScreenMessage( SM_DoEraseStepTiming ); AutoScreenMessage( SM_DoSaveAndExit ); AutoScreenMessage( SM_DoExit ); @@ -580,6 +581,7 @@ static MenuDef g_TimingDataInformation( MenuRowDef( ScreenEdit::warp, "Edit warp", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::speed_percent, "Edit speed (percent)", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::speed_wait, "Edit speed (wait)", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::speed_mode, "Edit speed (mode)", true, EditMode_Full, true, true, 0, "Beats", "Seconds" ), MenuRowDef( ScreenEdit::erase_step_timing, "Erase step timing", true, EditMode_Full, true, true, 0, NULL ) ); @@ -2779,6 +2781,19 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } SetDirty( true ); } + else if ( SM == SM_BackFromSpeedModeChange ) + { + int tmp = StringToInt(ScreenTextEntry::s_sLastAnswer ); + if( tmp == 0 ) + { + GetAppropriateTiming().SetSpeedModeAtBeat( GetBeat(), 0 ); + } + else + { + GetAppropriateTiming().SetSpeedModeAtBeat( GetBeat(), 1 ); + } + SetDirty( true ); + } else if( SM == SM_BackFromBGChange ) { @@ -3200,11 +3215,15 @@ void ScreenEdit::DisplayTimingMenu() g_TimingDataInformation.rows[speed_percent].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetSpeedPercentAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[speed_wait].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetSpeedWaitAtBeat( fBeat ) ) ); + RString starting = ( pTime.GetSpeedModeAtBeat( fBeat ) == 1 ? "Seconds" : "Beats" ); + g_TimingDataInformation.rows[speed_mode].SetOneUnthemedChoice( starting.c_str() ); + g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[combo].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[warp].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[speed_percent].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[speed_wait].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_TimingDataInformation.rows[speed_mode].bEnabled = GAMESTATE->m_bIsEditorStepTiming; EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); } @@ -3885,6 +3904,7 @@ static LocalizedString ENTER_LABEL_VALUE ( "ScreenEdit", "Enter a new Label va static LocalizedString ENTER_WARP_VALUE ( "ScreenEdit", "Enter a new Warp value." ); static LocalizedString ENTER_SPEED_PERCENT_VALUE ( "ScreenEdit", "Enter a new Speed percent value." ); static LocalizedString ENTER_SPEED_WAIT_VALUE ( "ScreenEdit", "Enter a new Speed wait value." ); +static LocalizedString ENTER_SPEED_MODE_VALUE ( "ScreenEdit", "Enter a new Speed mode value." ); static LocalizedString CONFIRM_TIMING_ERASE ( "ScreenEdit", "Are you sure you want to erase this chart's timing data?" ); void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice c, const vector &iAnswers ) { @@ -3984,9 +4004,23 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice 10 ); break; + case speed_mode: + { + RString sMode = ( GetAppropriateTiming().GetSpeedModeAtBeat( GetBeat() ) == 0 ? + "Beats" : "Seconds" ); + ScreenTextEntry::TextEntry( + SM_BackFromSpeedModeChange, + ENTER_SPEED_MODE_VALUE, + sMode.c_str(), + 10 + ); + + break; + } case erase_step_timing: ScreenPrompt::Prompt( SM_DoEraseStepTiming, CONFIRM_TIMING_ERASE , PROMPT_YES_NO, ANSWER_NO ); break; + } } diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 0f31a3e759..e1e3bd4435 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -499,6 +499,7 @@ public: // speed, speed_percent, speed_wait, + speed_mode, erase_step_timing, NUM_TIMING_DATA_INFORMATION_CHOICES }; @@ -532,6 +533,12 @@ public: delete_change, NUM_BGCHANGE_CHOICES }; + + enum SpeedSegmentModes + { + SSMODE_Beats, + SSMODE_Seconds + }; /** * @brief Take care of any background changes that the user wants. diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 45302128b8..3fc509fab4 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -255,7 +255,7 @@ void TimingData::SetLabelAtRow( int iRow, const RString sLabel ) } } -void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait ) +void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait, unsigned short usMode ) { unsigned i; for( i = 0; i < m_SpeedSegments.size(); i++ ) @@ -268,31 +268,48 @@ void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait ) { if( i == 0 || ( m_SpeedSegments[i-1].m_fPercent != fPercent - || m_SpeedSegments[i-1].m_fWait != fWait ) ) - AddSpeedSegment( SpeedSegment(iRow, fPercent, fWait) ); + || m_SpeedSegments[i-1].m_fWait != fWait + || m_SpeedSegments[i-1].m_usMode != usMode ) ) + AddSpeedSegment( SpeedSegment(iRow, fPercent, fWait, usMode) ); } else { if( i > 0 && m_SpeedSegments[i-1].m_fPercent == fPercent - && m_SpeedSegments[i-1].m_fWait == fWait ) + && m_SpeedSegments[i-1].m_fWait == fWait + && m_SpeedSegments[i-1].m_usMode == usMode ) m_SpeedSegments.erase( m_SpeedSegments.begin()+i, m_SpeedSegments.begin()+i+1 ); else { m_SpeedSegments[i].m_fPercent = fPercent; m_SpeedSegments[i].m_fWait = fWait; + m_SpeedSegments[i].m_usMode = usMode; } } } void TimingData::SetSpeedPercentAtRow( int iRow, float fPercent ) { - SetSpeedAtRow( iRow, fPercent, GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fWait ); + SetSpeedAtRow( iRow, + fPercent, + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fWait, + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_usMode); } void TimingData::SetSpeedWaitAtRow( int iRow, float fWait ) { - SetSpeedAtRow( iRow, GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fPercent, fWait ); + SetSpeedAtRow( iRow, + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fPercent, + fWait, + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_usMode); +} + +void TimingData::SetSpeedModeAtRow( int iRow, unsigned short usMode ) +{ + SetSpeedAtRow( iRow, + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fPercent, + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fWait, + usMode ); } @@ -351,6 +368,11 @@ float TimingData::GetSpeedWaitAtRow( int iRow ) return GetSpeedSegmentAtRow( iRow ).m_fWait; } +unsigned short TimingData::GetSpeedModeAtRow( int iRow ) +{ + return GetSpeedSegmentAtRow( iRow ).m_usMode; +} + // Multiply the BPM in the range [fStartBeat,fEndBeat) by fFactor. void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor ) { diff --git a/src/TimingData.h b/src/TimingData.h index 9a4d67d6f1..b24cccdc5a 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -660,20 +660,22 @@ struct LabelSegment struct SpeedSegment { /** @brief Sets up the SpeedSegment with default values. */ - SpeedSegment(): m_iStartRow(0), m_fPercent(1), m_fWait(0) {} + SpeedSegment(): m_iStartRow(0), + m_fPercent(1), m_fWait(0), m_usMode(0) {} /** * @brief Sets up the SpeedSegment with specified values. * @param i The row this activates. * @param p The percentage to use. */ - SpeedSegment(int i, float p): m_iStartRow(0), m_fPercent(p), m_fWait(0) {} + SpeedSegment(int i, float p): m_iStartRow(0), + m_fPercent(p), m_fWait(0), m_usMode(0) {} /** * @brief Sets up the SpeedSegment with specified values. * @param r The beat this activates. * @param p The percentage to use. */ SpeedSegment(float r, float p): m_iStartRow(BeatToNoteRow(r)), - m_fPercent(p), m_fWait(0) {} + m_fPercent(p), m_fWait(0), m_usMode(0) {} /** * @brief Sets up the SpeedSegment with specified values. @@ -681,7 +683,7 @@ struct SpeedSegment * @param p The percentage to use. * @param w The number of beats to wait. */ SpeedSegment(int i, float p, float w): m_iStartRow(i), - m_fPercent(p), m_fWait(w) {} + m_fPercent(p), m_fWait(w), m_usMode(0) {} /** * @brief Sets up the SpeedSegment with specified values. @@ -689,17 +691,43 @@ struct SpeedSegment * @param p The percentage to use. * @param w The number of beats to wait. */ SpeedSegment(float r, float p, float w): m_iStartRow(BeatToNoteRow(r)), - m_fPercent(p), m_fWait(w) {} + m_fPercent(p), m_fWait(w), m_usMode(0) {} + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param i The row this activates. + * @param p The percentage to use. + * @param w The number of beats/seconds to wait. + * @param k The mode used for the wait variable. */ + SpeedSegment(int i, float p, float w, unsigned short k): m_iStartRow(i), + m_fPercent(p), m_fWait(w), m_usMode(k) {} + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param r The beat this activates. + * @param p The percentage to use. + * @param w The number of beats/seconds to wait. + * @param k The mode used for the wait variable.*/ + SpeedSegment(float r, float p, float w, unsigned short k): m_iStartRow(BeatToNoteRow(r)), + m_fPercent(p), m_fWait(w), m_usMode(k) {} /** @brief The row in which the ComboSegment activates. */ int m_iStartRow; /** @brief The percentage to use when multiplying the Player's BPM. */ float m_fPercent; /** - * @brief The number of beats to wait for the change to take place. + * @brief The number of beats or seconds to wait for the change to take place. * * A value of 0 means this is immediate. */ float m_fWait; + /** + * @brief The mode that this segment uses for the math. + * + * 0: beats + * 1: seconds + * other + */ + unsigned short m_usMode; /** * @brief Compares two SpeedSegments to see if they are equal to each other. @@ -710,6 +738,7 @@ struct SpeedSegment { COMPARE( m_iStartRow ); COMPARE( m_fPercent ); + COMPARE( m_usMode ); COMPARE( m_fWait ); return true; } @@ -1364,20 +1393,34 @@ public: * @return the wait. */ float GetSpeedWaitAtBeat( float fBeat ) { return GetSpeedWaitAtRow( BeatToNoteRow(fBeat) ); } + /** + * @brief Retrieve the Speed's mode at the given row. + * @param iNoteRow the row in question. + * @return the mode. + */ + unsigned short GetSpeedModeAtRow( int iNoteRow ); + /** + * @brief Retrieve the Speed's mode at the given beat. + * @param fBeat the beat in question. + * @return the mode. + */ + unsigned short GetSpeedModeAtBeat( float fBeat ) { return GetSpeedModeAtRow( BeatToNoteRow(fBeat) ); } /** * @brief Set the row to have the new Speed. * @param iNoteRow the row to have the new Speed. * @param fPercent the percent. * @param fWait the wait. + * @param usMode the mode. */ - void SetSpeedAtRow( int iNoteRow, float fPercent, float fWait ); + void SetSpeedAtRow( int iNoteRow, float fPercent, float fWait, unsigned short usMode ); /** * @brief Set the beat to have the new Speed. * @param fBeat the beat to have the new Speed. * @param fPercent the percent. * @param fWait the wait. + * @param usMode the mode. */ - void SetSpeedAtBeat( float fBeat, float fPercent, float fWait ) { SetSpeedAtRow( BeatToNoteRow(fBeat), fPercent, fWait ); } + void SetSpeedAtBeat( float fBeat, float fPercent, float fWait, unsigned short usMode ) { SetSpeedAtRow( BeatToNoteRow(fBeat), fPercent, fWait, usMode ); } /** * @brief Set the row to have the new Speed percent. * @param iNoteRow the row to have the new Speed percent. @@ -1402,6 +1445,18 @@ public: * @param fWait the wait. */ void SetSpeedWaitAtBeat( float fBeat, float fWait ) { SetSpeedWaitAtRow( BeatToNoteRow(fBeat), fWait); } + /** + * @brief Set the row to have the new Speed mode. + * @param iNoteRow the row to have the new Speed mode. + * @param usMode the mode. + */ + void SetSpeedModeAtRow( int iNoteRow, unsigned short usMode ); + /** + * @brief Set the beat to have the new Speed mode. + * @param fBeat the beat to have the new Speed mode. + * @param usMode the mode. + */ + void SetSpeedModeAtBeat( float fBeat, unsigned short usMode ) { SetSpeedModeAtRow( BeatToNoteRow(fBeat), usMode); } /** * @brief Retrieve the SpeedSegment at the specified row. * @param iNoteRow the row that has a SpeedSegment. From f8f47c002bf38259e28b02611ace602265bee68a Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 12:17:54 +0700 Subject: [PATCH 146/197] [splittiming] speed segment changes: - allow first speed segment to take effect - make speed segments take effect before delays - make speed segments not affect cmods --- src/ArrowEffects.cpp | 79 +++++++++++++++++++++++--------------------- src/GameState.cpp | 3 +- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index b2b6d60941..318bd75e01 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -211,6 +211,46 @@ void ArrowEffects::Update() } } +float GetSpeedMultiplier( float fSongBeat, float fMusicSeconds, const TimingData &tim ) +{ + if( tim.m_SpeedSegments.size() == 0 ) + return 1.0; + + const int index = tim.GetSpeedSegmentIndexAtBeat( fSongBeat ); + + const SpeedSegment &seg = tim.m_SpeedSegments[index]; + float fStartBeat = NoteRowToBeat(seg.m_iStartRow); + float fStartTime = tim.GetElapsedTimeFromBeat( fStartBeat ) - tim.GetDelayAtBeat( fStartBeat ); + float fEndTime; + float fCurTime = fMusicSeconds; + + if( seg.m_usMode == 1 ) // seconds + { + fEndTime = fStartTime + seg.m_fWait; + } + else + { + fEndTime = tim.GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ) - tim.GetDelayAtBeat( fStartBeat + seg.m_fWait ); + } + + if( fEndTime >= fCurTime && ( index > 0 || tim.m_SpeedSegments[0].m_fWait > 0.0 ) ) + { + const float fPriorSpeed = ( index == 0 ? 1 : tim.m_SpeedSegments[index - 1].m_fPercent ); + float fTimeUsed = fCurTime - fStartTime; + float fDuration = fEndTime - fStartTime; + float fRatioUsed = fDuration == 0.0 ? 1 : fTimeUsed / fDuration; + + float fDistance = fPriorSpeed - seg.m_fPercent; + float fRatioNeed = fRatioUsed * -fDistance; + return (fPriorSpeed + fRatioNeed); + } + else + { + return seg.m_fPercent; + } + +} + /* For visibility testing: if bAbsolute is false, random modifiers must return * the minimum possible scroll speed. */ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float fNoteBeat, float &fPeakYOffsetOut, bool &bIsPastPeakOut, bool bAbsolute ) @@ -233,7 +273,8 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float { float fBeatsUntilStep = fNoteBeat - fSongBeat; float fYOffsetBeatSpacing = fBeatsUntilStep; - fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); + float fSpeedMultiplier = GAMESTATE->m_bInStepEditor ? 1.0 : GetSpeedMultiplier( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible, pCurSteps->m_Timing ); + fYOffset += fSpeedMultiplier * fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); } if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f ) @@ -251,42 +292,6 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float // (per issue 24), edit this to reflect that. -aj fYOffset *= ARROW_SPACING; - // Factor in the SpeedSegment. - TimingData &tim = pCurSteps->m_Timing; - - const int index = tim.GetSpeedSegmentIndexAtBeat( fSongBeat ); - if( !GAMESTATE->m_bInStepEditor && index > 0 ) - { - SpeedSegment &seg = tim.GetSpeedSegmentAtBeat( fSongBeat ); - float fStartBeat = NoteRowToBeat(seg.m_iStartRow); - float fStartTime = tim.GetElapsedTimeFromBeat( fStartBeat ); - float fEndTime; - - if( seg.m_usMode == 1 ) // seconds - { - fEndTime = fStartTime + seg.m_fWait; - } - else - { - fEndTime = tim.GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ); - } - float fCurTime = tim.GetElapsedTimeFromBeat( fSongBeat ); - - if( fEndTime >= fCurTime ) - { - const float fPriorSpeed = tim.m_SpeedSegments[index - 1].m_fPercent; - float fTimeUsed = fCurTime - fStartTime; - float fRatioUsed = fTimeUsed / (fEndTime - fStartTime); - - float fDistance = fPriorSpeed - seg.m_fPercent; - float fRatioNeed = fRatioUsed * -fDistance; - fYOffset *= (fPriorSpeed + fRatioNeed); - } - else - { - fYOffset *= seg.m_fPercent; - } - } // don't mess with the arrows after they've crossed 0 if( fYOffset < 0 ) return fYOffset * pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed; diff --git a/src/GameState.cpp b/src/GameState.cpp index 3b4f792986..76bd07acd5 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -128,7 +128,8 @@ GameState::GameState() : m_stEditSource( Message_EditSourceStepsTypeChanged ), m_iEditCourseEntryIndex( Message_EditCourseEntryIndexChanged ), m_sEditLocalProfileID( Message_EditLocalProfileIDChanged ), - m_bIsEditorStepTiming( true ) + m_bIsEditorStepTiming( true ), + m_bInStepEditor( false ) { g_pImpl = new GameStateImpl; From 0904892202904ebe5ab4903d9191d8c75efb10b4 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 12:32:23 +0700 Subject: [PATCH 147/197] [splittiming] make setting beat0offset in ScreenEdit's edit timing data menu work. --- src/ScreenEdit.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 0851795b87..698ba15c05 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3133,11 +3133,7 @@ static void ChangeArtistTranslit( const RString &sNew ) static void ChangeBeat0Offset( const RString &sNew ) { - TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming; - if( GAMESTATE->m_bIsEditorStepTiming ) - { - timing = GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing; - } + TimingData &timing = GAMESTATE->m_bIsEditorStepTiming ? GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing : GAMESTATE->m_pCurSong->m_SongTiming; timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); } From 60133353c11b33392d7fd5bcbdb9290ac5cb7d35 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 02:00:17 -0400 Subject: [PATCH 148/197] [splittiming] Time for FakeSegments. No, these won't replace Fake Notes. --- Docs/Luadoc/Lua.xml | 1 + Docs/Luadoc/LuaDocumentation.xml | 3 + src/TimingData.cpp | 134 +++++++++++++++++++++++ src/TimingData.h | 182 +++++++++++++++++++++++++++++++ 4 files changed, 320 insertions(+) diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index dfb4c7cce3..6aa9eda455 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -1406,6 +1406,7 @@ + diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index df9f17081b..1e519bf91c 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -3519,6 +3519,9 @@ Returns true if the TimingData contains warps. + + Returns true if the TimingData contains fake segments. + Returns true if the TimingData contains speed scrolling changes. diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 3fc509fab4..e4f0375e39 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -73,6 +73,11 @@ void TimingData::AddSpeedSegment( const SpeedSegment &seg ) m_SpeedSegments.insert( upper_bound(m_SpeedSegments.begin(), m_SpeedSegments.end(), seg), seg ); } +void TimingData::AddFakeSegment( const FakeSegment &seg ) +{ + m_FakeSegments.insert( upper_bound(m_FakeSegments.begin(), m_FakeSegments.end(), seg), seg ); +} + /* Change an existing BPM segment, merge identical segments together or insert a new one. */ void TimingData::SetBPMAtRow( int iNoteRow, float fBPM ) { @@ -288,6 +293,31 @@ void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait, unsigned } } +void TimingData::SetFakeAtRow( int iRow, float fNew ) +{ + unsigned i; + for( i=0; i 0 && NoteRowToBeat(iRow) < fNew; + if( i == m_FakeSegments.size() ) + { + if( valid ) + { + AddFakeSegment( FakeSegment(iRow, fNew) ); + } + } + else + { + if( valid ) + { + m_FakeSegments[i].m_fEndBeat = fNew; + } + else + m_FakeSegments.erase( m_FakeSegments.begin()+i, m_FakeSegments.begin()+i+1 ); + } +} + void TimingData::SetSpeedPercentAtRow( int iRow, float fPercent ) { SetSpeedAtRow( iRow, @@ -373,6 +403,18 @@ unsigned short TimingData::GetSpeedModeAtRow( int iRow ) return GetSpeedSegmentAtRow( iRow ).m_usMode; } +float TimingData::GetFakeAtRow( int iFakeRow ) const +{ + for( unsigned i=0; i(i); } +int TimingData::GetFakeSegmentIndexAtRow( int iNoteRow ) const +{ + unsigned i; + for( i=0; i iNoteRow ) + break; + } + return static_cast(i); +} + bool TimingData::IsWarpAtRow( int iNoteRow ) const { if( m_WarpSegments.empty() ) @@ -477,6 +531,20 @@ bool TimingData::IsWarpAtRow( int iNoteRow ) const return false; } +bool TimingData::IsFakeAtRow( int iNoteRow ) const +{ + if( m_FakeSegments.empty() ) + return false; + + int i = GetFakeSegmentIndexAtRow( iNoteRow ); + const FakeSegment& s = m_FakeSegments[i]; + if( s.m_iStartRow <= iNoteRow && iNoteRow < BeatToNoteRow(s.m_fEndBeat) ) + { + return true; + } + return false; +} + int TimingData::GetTimeSignatureSegmentIndexAtRow( int iRow ) const { unsigned i; @@ -595,6 +663,16 @@ WarpSegment& TimingData::GetWarpSegmentAtRow( int iRow ) return m_WarpSegments[i]; } +FakeSegment& TimingData::GetFakeSegmentAtRow( int iRow ) +{ + static FakeSegment empty; + if( m_FakeSegments.empty() ) + return empty; + + int i = GetFakeSegmentIndexAtRow( iRow ); + return m_FakeSegments[i]; +} + int TimingData::GetTickcountSegmentIndexAtRow( int iRow ) const { unsigned i; @@ -952,6 +1030,25 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool m_SpeedSegments[i].m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; } + for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) + { + const int iSegStartRow = m_FakeSegments[i].m_iStartRow; + const int iSegEndRow = BeatToNoteRow( m_FakeSegments[i].m_fEndBeat ); + if( iSegEndRow >= iStartIndex ) + { + if( iSegEndRow > iEndIndex ) + m_FakeSegments[i].m_fEndBeat += NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))); + else + m_FakeSegments[i].m_fEndBeat = NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale) + iStartIndex); + } + if( iSegStartRow < iStartIndex ) + continue; + else if( iSegStartRow > iEndIndex ) + m_FakeSegments[i].m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + else + m_FakeSegments[i].m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + } + // adjust BPM changes to preserve timing if( bAdjustBPM ) { @@ -1044,6 +1141,16 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) continue; sped.m_iStartRow += iRowsToAdd; } + + for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) + { + FakeSegment &fake = m_FakeSegments[i]; + if( BeatToNoteRow(fake.m_fEndBeat) >= iStartRow ) + fake.m_fEndBeat += NoteRowToBeat(iRowsToAdd); + if( fake.m_iStartRow < iStartRow ) + continue; + fake.m_iStartRow += iRowsToAdd; + } if( iStartRow == 0 ) { @@ -1217,6 +1324,26 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) } sped.m_iStartRow -= iRowsToDelete; } + + for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) + { + FakeSegment &fake = m_FakeSegments[i]; + + if( BeatToNoteRow(fake.m_fEndBeat) >= iStartRow ) + fake.m_fEndBeat = max( NoteRowToBeat(iStartRow), fake.m_fEndBeat - NoteRowToBeat(iRowsToDelete) ); + + if( fake.m_iStartRow < iStartRow ) + continue; + + if( fake.m_iStartRow < iStartRow+iRowsToDelete ) + { + m_FakeSegments.erase( m_FakeSegments.begin()+i, m_FakeSegments.begin()+i+1 ); + --i; + continue; + } + + fake.m_iStartRow -= iRowsToDelete; + } this->SetBPMAtRow( iStartRow, fNewBPM ); } @@ -1292,6 +1419,11 @@ bool TimingData::HasWarps() const return m_WarpSegments.size()>0; } +bool TimingData::HasFakes() const +{ + return m_FakeSegments.size()>0; +} + bool TimingData::HasSpeedChanges() const { return m_SpeedSegments.size()>1; @@ -1343,6 +1475,7 @@ public: static int HasStops( T* p, lua_State *L ) { lua_pushboolean(L, p->HasStops()); return 1; } static int HasBPMChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasBpmChanges()); return 1; } static int HasWarps( T* p, lua_State *L ) { lua_pushboolean(L, p->HasWarps()); return 1; } + static int HasFakes( T* p, lua_State *L ) { lua_pushboolean(L, p->HasFakes()); return 1; } static int HasSpeedChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasSpeedChanges()); return 1; } static int GetStops( T* p, lua_State *L ) { @@ -1431,6 +1564,7 @@ public: ADD_METHOD( HasStops ); ADD_METHOD( HasBPMChanges ); ADD_METHOD( HasWarps ); + ADD_METHOD( HasFakes ); ADD_METHOD( HasSpeedChanges ); ADD_METHOD( GetStops ); ADD_METHOD( GetDelays ); diff --git a/src/TimingData.h b/src/TimingData.h index b24cccdc5a..61ee14cd16 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -777,6 +777,113 @@ struct SpeedSegment bool operator>=( const SpeedSegment &other ) const { return !operator<(other); } }; +/** + * @brief Identifies when a whole region of arrows is to be ignored. + * + * FakeSegments are similar to the Fake Tap Notes in that the contents + * inside are neither for nor against the player. They can be useful for + * mission modes, in conjunction with WarpSegments, or perhaps other + * uses not thought up at the time of this comment. Unlike the Warp + * Segments, these are not magically jumped over: instead, these are + * drawn normally. + * + * These were inspired by the Pump It Up series. */ +struct FakeSegment +{ + /** + * @brief Create a simple Fake Segment with default values. + * + * It is best to override the values as soon as possible. + */ + FakeSegment() : m_iStartRow(-1), m_fEndBeat(-1) { } + /** + * @brief Create a Fake Segment with the specified values. + * @param s the starting row of this segment. + * @param r the row to be real again. + */ + FakeSegment( int s, int r ): m_iStartRow(max(0, (s < r ? s : r))), + m_fEndBeat(max(0, NoteRowToBeat((r > s ? r : s)))) {} + /** + * @brief Creates a Fake Segment with the specified values. + * @param s the starting row of this segment. + * @param b the beat to be real again. + */ + FakeSegment( int s, float b ): m_iStartRow(max(0, s)), + m_fEndBeat(max(0, b)) {} + /** + * @brief Create a Fake Segment with the specified values. + * @param s the starting beat in this segment. + * @param r the row to be real again. + */ + FakeSegment( float s, int r ): + m_iStartRow(max(0, BeatToNoteRow(s))), + m_fEndBeat(max(0, NoteRowToBeat(r))) {} + /** + * @brief Creates a Fake Segment with the specified values. + * @param s the starting beat of this segment. + * @param b the beat to be real again. + */ + FakeSegment( float s, float b ): + m_iStartRow(max(0, BeatToNoteRow((s < b ? s : b)))), + m_fEndBeat(max(0, (b > s ? b : s))) {} + /** + * @brief The row in which the FakeSegment activates. + */ + int m_iStartRow; + /** + * @brief The beat that ends the FakeSegment. + */ + float m_fEndBeat; + /** + * @brief Compares two FakeSegments to see if they are equal to each other. + * @param other the other FakeSegment to compare to. + * @return the equality of the two segments. + */ + bool operator==( const FakeSegment &other ) const + { + COMPARE( m_iStartRow ); + COMPARE( m_fEndBeat ); + return true; + } + /** + * @brief Compares two FakeSegments to see if they are not equal to each other. + * @param other the other FakeSegment to compare to. + * @return the inequality of the two segments. + */ + bool operator!=( const FakeSegment &other ) const { return !operator==(other); } + /** + * @brief Compares two FakeSegments to see if one is less than the other. + * @param other the other FakeSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const FakeSegment &other ) const + { + return m_iStartRow < other.m_iStartRow || + ( m_iStartRow == other.m_iStartRow && m_fEndBeat < other.m_fEndBeat ); + } + /** + * @brief Compares two FakeSegments to see if one is less than or equal to the other. + * @param other the other FakeSegment to compare to. + * @return the truth/falsehood of if the first is less or equal to than the second. + */ + bool operator<=( const FakeSegment &other ) const + { + return ( operator<(other) || operator==(other) ); + } + /** + * @brief Compares two FakeSegments to see if one is greater than the other. + * @param other the other FakeSegment to compare to. + * @return the truth/falsehood of if the first is greater than the second. + */ + bool operator>( const FakeSegment &other ) const { return !operator<=(other); } + /** + * @brief Compares two FakeSegments to see if one is greater than or equal to the other. + * @param other the other FakeSegment to compare to. + * @return the truth/falsehood of if the first is greater than or equal to the second. + */ + bool operator>=( const FakeSegment &other ) const { return !operator<(other); } +}; + /** * @brief Holds data for translating beats<->seconds. @@ -1487,6 +1594,72 @@ public: */ void AddSpeedSegment( const SpeedSegment &seg ); + /** + * @brief Determine when the fakes end. + * @param iRow The row you start on. + * @return the time when the fakes end. + */ + float GetFakeAtRow( int iRow ) const; + /** + * @brief Determine when the fakes end. + * @param fBeat The beat you start on. + * @return the time when the fakes end. + */ + float GetFakeAtBeat( float fBeat ) const { return GetFakeAtRow( BeatToNoteRow( fBeat ) ); } + /** + * @brief Set the beat to indicate when the FakeSegment ends. + * @param iRow The row to start on. + * @param fNew The destination beat. + */ + void SetFakeAtRow( int iRow, float fNew ); + /** + * @brief Set the beat to indicate when the FakeSegment ends. + * @param fBeat The beat to start on. + * @param fNew The destination beat. + */ + void SetFakeAtBeat( float fBeat, float fNew ) { SetFakeAtRow( BeatToNoteRow( fBeat ), fNew ); } + /** + * @brief Retrieve the FakeSegment at the specified row. + * @param iRow the row to focus on. + * @return the FakeSegment in question. + */ + FakeSegment& GetFakeSegmentAtRow( int iRow ); + /** + * @brief Retrieve the FakeSegment at the specified beat. + * @param fBeat the beat to focus on. + * @return the FakeSegment in question. + */ + FakeSegment& GetFakeSegmentAtBeat( float fBeat ) { return GetFakeSegmentAtRow( BeatToNoteRow( fBeat ) ); } + /** + * @brief Retrieve the index of the FakeSegment at the specified row. + * @param iRow the row to focus on. + * @return the index in question. + */ + int GetFakeSegmentIndexAtRow( int iRow ) const; + /** + * @brief Retrieve the index of the FakeSegment at the specified beat. + * @param fBeat the beat to focus on. + * @return the index in question. + */ + int GetFakeSegmentIndexAtBeat( float fBeat ) const { return GetFakeSegmentIndexAtRow( BeatToNoteRow( fBeat ) ); } + /** + * @brief Checks if the row is inside a fake. + * @param iRow the row to focus on. + * @return true if the row is inside a fake, false otherwise. + */ + bool IsFakeAtRow( int iRow ) const; + /** + * @brief Checks if the beat is inside a fake. + * @param fBeat the beat to focus on. + * @return true if the row is inside a fake, false otherwise. + */ + bool IsFakeAtBeat( float fBeat ) const { return IsFakeAtRow( BeatToNoteRow( fBeat ) ); } + /** + * @brief Add the FakeSegment to the TimingData. + * @param seg the new FakeSegment. + */ + void AddFakeSegment( const FakeSegment &seg ); + void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor ); @@ -1531,6 +1704,10 @@ public: * @return true if there is at least one warp, false otherwise. */ bool HasWarps() const; + /** + * @brief View the TimingData to see if there is at least one fake segment involved. + * @return true if there is at least one fake segment, false otherwise. */ + bool HasFakes() const; /** * @brief View the TimingData to see if a song changes its speed scrolling at any point. * @return true if there is at least one change, false otherwise. */ @@ -1566,6 +1743,9 @@ public: COMPARE( m_SpeedSegments.size() ); for( unsigned i=0; i m_LabelSegments; /** @brief The collection of SpeedSegments. */ vector m_SpeedSegments; + /** @brief The collection of FakeSegments. */ + vector m_FakeSegments; /** * @brief The initial offset of a song. */ From 49552d41e5fb3ce3b872c7cdffe0172beca47b52 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 09:41:07 -0400 Subject: [PATCH 149/197] [splittiming] Don't need this pre-filled. --- src/ScreenEdit.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 698ba15c05..95e51299b0 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -4002,13 +4002,11 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice break; case speed_mode: { - RString sMode = ( GetAppropriateTiming().GetSpeedModeAtBeat( GetBeat() ) == 0 ? - "Beats" : "Seconds" ); ScreenTextEntry::TextEntry( SM_BackFromSpeedModeChange, ENTER_SPEED_MODE_VALUE, - sMode.c_str(), - 10 + "", + 3 ); break; From ba8791b4f990d0d3cf552d7d98b6405cd3011e23 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 09:44:07 -0400 Subject: [PATCH 150/197] [splittiming] Only care about the mod change. Nothing wrong with the rest, but for editor purposes, this kind of takes precedence before length and unit. --- src/TimingData.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/TimingData.cpp b/src/TimingData.cpp index e4f0375e39..dcc6b3e560 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -271,17 +271,14 @@ void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait, unsigned if ( i == m_SpeedSegments.size() || m_SpeedSegments[i].m_iStartRow != iRow ) { - if( i == 0 || - ( m_SpeedSegments[i-1].m_fPercent != fPercent - || m_SpeedSegments[i-1].m_fWait != fWait - || m_SpeedSegments[i-1].m_usMode != usMode ) ) + // the core mod itself matters the most for comparisons. + if( i == 0 || m_SpeedSegments[i-1].m_fPercent != fPercent ) AddSpeedSegment( SpeedSegment(iRow, fPercent, fWait, usMode) ); } else { - if( i > 0 && m_SpeedSegments[i-1].m_fPercent == fPercent - && m_SpeedSegments[i-1].m_fWait == fWait - && m_SpeedSegments[i-1].m_usMode == usMode ) + // The others aren't compared: only the mod itself matters. + if( i > 0 && m_SpeedSegments[i-1].m_fPercent == fPercent ) m_SpeedSegments.erase( m_SpeedSegments.begin()+i, m_SpeedSegments.begin()+i+1 ); else From 329798e0d612c323c2e78dca96ec6911c6aed311 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 10:02:57 -0400 Subject: [PATCH 151/197] [splittiming] Few things with NotesLoader/Writer: 1) Start to accept FakeSegments. 2) Start the transition to relative points for Warps. 3) Again, song timings don't get FakeSegments. --- src/NotesLoaderSMA.cpp | 36 +++++++++++++++++++++++ src/NotesLoaderSMA.h | 1 + src/NotesLoaderSSC.cpp | 67 +++++++++++++++++++++++++++++++++++++----- src/NotesLoaderSSC.h | 3 +- src/NotesWriterSSC.cpp | 8 ++++- 5 files changed, 105 insertions(+), 10 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 23dd584691..de181db967 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -355,6 +355,35 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS } } +void SMALoader::ProcessFakes( TimingData &out, const int iRowsPerBeat, const RString sParam ) +{ + vector arrayFakeExpressions; + split( sParam, ",", arrayFakeExpressions ); + + for( unsigned b=0; b arrayFakeValues; + split( arrayFakeExpressions[b], "=", arrayFakeValues ); + // XXX: Hard to tell which file caused this. + if( arrayFakeValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #FAKES value \"%s\" (must have exactly one '='), ignored.", + arrayFakeExpressions[b].c_str() ); + continue; + } + + const float fBeat = RowToBeat( arrayFakeValues[0], iRowsPerBeat ); + const float fNewBeat = StringToFloat( arrayFakeValues[1] ); + + if(fNewBeat > 0) + out.AddFakeSegment( FakeSegment(fBeat, fNewBeat) ); + else + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Fake at beat %f, BPM %f.", fBeat, fNewBeat ); + } + } +} + void SMALoader::LoadFromSMATokens( RString sStepsType, @@ -685,6 +714,13 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) ProcessMultipliers( pNewNotes->m_Timing, iRowsPerBeat, sParams[1] ); } + else if( sValueName=="FAKES" ) + { + TimingData &timing = (state == SMA_GETTING_STEP_INFO + ? pNewNotes->m_Timing : out.m_SongTiming); + ProcessFakes( timing, iRowsPerBeat, sParams[1] ); + } + else if( sValueName=="METERTYPE" ) { ; // We don't use this...yet. diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index af397205fb..c9e3dfa811 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -48,6 +48,7 @@ namespace SMALoader void ProcessTickcounts( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ); + void ProcessFakes( TimingData &out, const int iRowsPerBeat, const RString sParam ); float RowToBeat( RString sLine, const int iRowsPerBeat ); }; diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 352387e7df..b361629db0 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -46,7 +46,7 @@ bool SSCLoader::LoadFromDir( const RString &sPath, Song &out ) return LoadFromSSCFile( sPath + aFileNames[0], out ); } -void SSCLoader::ProcessWarps( TimingData &out, const RString sParam ) +void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float fVersion ) { vector arrayWarpExpressions; split( sParam, ",", arrayWarpExpressions ); @@ -65,8 +65,8 @@ void SSCLoader::ProcessWarps( TimingData &out, const RString sParam ) const float fBeat = StringToFloat( arrayWarpValues[0] ); const float fNewBeat = StringToFloat( arrayWarpValues[1] ); - - if(fNewBeat > fBeat) + // Early versions were absolute in beats. They should be relative. + if( ( fVersion < VERSION_SPLIT_TIMING && fNewBeat > fBeat ) || fNewBeat > 0 ) out.AddWarpSegment( WarpSegment(fBeat, fNewBeat) ); else { @@ -172,6 +172,35 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) } } +void SSCLoader::ProcessFakes( TimingData &out, const RString sParam ) +{ + vector arrayFakeExpressions; + split( sParam, ",", arrayFakeExpressions ); + + for( unsigned b=0; b arrayFakeValues; + split( arrayFakeExpressions[b], "=", arrayFakeValues ); + // XXX: Hard to tell which file caused this. + if( arrayFakeValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #FAKES value \"%s\" (must have exactly one '='), ignored.", + arrayFakeExpressions[b].c_str() ); + continue; + } + + const float fBeat = StringToFloat( arrayFakeValues[0] ); + const float fNewBeat = StringToFloat( arrayFakeValues[1] ); + + if(fNewBeat > 0) + out.AddFakeSegment( FakeSegment(fBeat, fNewBeat) ); + else + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Fake at beat %f, BPM %f.", fBeat, fNewBeat ); + } + } +} + bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCache ) { @@ -393,9 +422,9 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach SMLoader::ProcessBPMs(out.m_SongTiming, sParams[1]); } - else if( sValueName=="WARPS" ) + else if( sValueName=="WARPS" ) // Older versions allowed em here. { - ProcessWarps( out.m_SongTiming, sParams[1] ); + ProcessWarps( out.m_SongTiming, sParams[1], out.m_fVersion ); } else if( sValueName=="LABELS" ) @@ -560,7 +589,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach else if( sValueName=="WARPS" ) { - ProcessWarps(stepsTiming, sParams[1]); + ProcessWarps(stepsTiming, sParams[1], out.m_fVersion); } else if( sValueName=="SPEEDS" ) @@ -568,6 +597,11 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach ProcessSpeeds( stepsTiming, sParams[1] ); } + else if( sValueName=="FAKES" ) + { + ProcessFakes( stepsTiming, sParams[1] ); + } + else if( sValueName=="LABELS" ) { ProcessLabels(stepsTiming, sParams[1]); @@ -675,7 +709,12 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat sValueName.MakeUpper(); // handle the data - if( sValueName=="SONG" ) + if( sValueName=="VERSION" ) + { + pSong->m_fVersion = StringToFloat( sParams[1] ); + } + + else if( sValueName=="SONG" ) { if( pSong ) { @@ -795,7 +834,19 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat else if( sValueName=="WARPS" ) { - ProcessWarps(stepsTiming, sParams[1]); + ProcessWarps(stepsTiming, sParams[1], pSong->m_fVersion); + bSSCFormat = true; + } + + else if( sValueName=="SPEEDS" ) + { + ProcessSpeeds( stepsTiming, sParams[1] ); + bSSCFormat = true; + } + + else if( sValueName=="FAKES" ) + { + ProcessFakes( stepsTiming, sParams[1] ); bSSCFormat = true; } diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index c78231677b..cccf26c45f 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -77,10 +77,11 @@ namespace SSCLoader void TidyUpData( Song &song, bool bFromCache ); - void ProcessWarps( TimingData &, const RString ); + void ProcessWarps( TimingData &, const RString, const float ); void ProcessLabels( TimingData &, const RString ); void ProcessCombos( TimingData &, const RString ); void ProcessSpeeds( TimingData &, const RString ); + void ProcessFakes( TimingData &, const RString ); } #endif /** diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 3b7c4ae729..3f01843b06 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -140,6 +140,11 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss ) w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait, ss->m_usMode ); w.Finish(); + + w.Init( "FAKES" ); + FOREACH_CONST( FakeSegment, timing.m_FakeSegments, fs ) + w.Write( fs->m_iStartRow, fs->m_fEndBeat ); + w.Finish(); } w.Init( "LABELS" ); @@ -312,7 +317,8 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa GetTimingTags( lines, in.m_Timing ); - lines.push_back( "#ATTACKS:;" ); // not sure of how to handle this yet. + // For now, attacks are NOT in use for the step. + lines.push_back( "#ATTACKS:;" ); lines.push_back( ssprintf( "#OFFSET:%.6f;", in.m_Timing.m_fBeat0OffsetInSeconds ) ); RString sNoteData; From b12adc82e183d90114f11bbd54f874005e470693 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 10:05:56 -0400 Subject: [PATCH 152/197] [splittiming] Simplify. --- src/NotesLoaderSMA.cpp | 56 +++--------------------------------------- src/NotesLoaderSSC.cpp | 45 +-------------------------------- 2 files changed, 4 insertions(+), 97 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index de181db967..58ced62bd6 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -395,59 +395,9 @@ void SMALoader::LoadFromSMATokens( Steps &out ) { - // we're loading from disk, so this is by definition already saved: - out.SetSavedToDisk( true ); - - Trim( sStepsType ); - Trim( sDescription ); - Trim( sDifficulty ); - Trim( sNoteData ); - - // LOG->Trace( "Steps::LoadFromSMTokens()" ); - - // insert stepstype hacks from GameManager.cpp here? -aj - out.m_StepsType = GAMEMAN->StringToStepsType( sStepsType ); - out.SetDescription( sDescription ); - out.SetCredit( sDescription ); // this is often used for both. - out.SetDifficulty( StringToDifficulty(sDifficulty) ); - - sDescription.MakeLower(); - - // Handle hacks that originated back when StepMania didn't have - // Difficulty_Challenge. (At least v1.64, possibly v3.0 final...) - if( out.GetDifficulty() == Difficulty_Hard ) - { - // HACK: SMANIAC used to be Difficulty_Hard with a special description. - if( sDescription == "smaniac" ) - out.SetDifficulty( Difficulty_Challenge ); - - // HACK: CHALLENGE used to be Difficulty_Hard with a special description. - if( sDescription == "challenge" ) - out.SetDifficulty( Difficulty_Challenge ); - } - - out.SetMeter( StringToInt(sMeter) ); - vector saValues; - split( sRadarValues, ",", saValues, true ); - int categories = NUM_RadarCategory - 1; // Fakes aren't counted in the radar values. - if( saValues.size() == (unsigned)categories * NUM_PLAYERS ) - { - RadarValues v[NUM_PLAYERS]; - FOREACH_PlayerNumber( pn ) - { - // Can't use the foreach anymore due to flexible radar lines. - for( RadarCategory rc = (RadarCategory)0; rc < categories; - enum_add( rc, 1 ) ) - { - v[pn][rc] = StringToFloat( saValues[pn*categories + rc] ); - } - } - out.SetCachedRadarValues( v ); - } - - out.SetSMNoteData( sNoteData ); - - out.TidyUpData(); + SMLoader::LoadFromSMATokens( sStepsType, sDescription, + sDifficulty, sMeter, sRadarValues, + sNoteData, out ); } void SMALoader::TidyUpData( Song &song, bool bFromCache ) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index b361629db0..5019bf9ec0 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -609,50 +609,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach else if( sValueName=="ATTACKS" ) { - // TODO: Look into Step attacks vs Song Attacks. -Wolfman2000 - /* - // Build the RString vector here so we can write it to file again later - for( unsigned s=1; s < sParams.params.size(); ++s ) - out.m_sAttackString.push_back( sParams[s] ); - - Attack attack; - float end = -9999; - - for( unsigned j=1; j < sParams.params.size(); ++j ) - { - vector sBits; - split( sParams[j], "=", sBits, false ); - - // Need an identifer and a value for this to work - if( sBits.size() < 2 ) - continue; - - TrimLeft( sBits[0] ); - TrimRight( sBits[0] ); - - if( !sBits[0].CompareNoCase("TIME") ) - attack.fStartSecond = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("LEN") ) - attack.fSecsRemaining = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("END") ) - end = strtof( sBits[1], NULL ); - else if( !sBits[0].CompareNoCase("MODS") ) - { - attack.sModifiers = sBits[1]; - - if( end != -9999 ) - { - attack.fSecsRemaining = end - attack.fStartSecond; - end = -9999; - } - - if( attack.fSecsRemaining < 0.0f ) - attack.fSecsRemaining = 0.0f; - - out.m_Attacks.push_back( attack ); - } - } - */ + // Step Attacks aren't in yet. } else if( sValueName=="OFFSET" ) From 79135b3179300e0ca4bdab44327cde117203d86e Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 10:16:24 -0400 Subject: [PATCH 153/197] [splittiming] Oops. --- src/NotesLoaderSMA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 58ced62bd6..ca2ff66c84 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -395,7 +395,7 @@ void SMALoader::LoadFromSMATokens( Steps &out ) { - SMLoader::LoadFromSMATokens( sStepsType, sDescription, + SMLoader::LoadFromSMTokens( sStepsType, sDescription, sDifficulty, sMeter, sRadarValues, sNoteData, out ); } From b3c16e3dee4c7474a3e4edce86dc36c0972f0ea6 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 10:24:59 -0400 Subject: [PATCH 154/197] [splittiming] Warps and Fakes are relative timed. theDtTvB, time to scrutinize my work. ;) --- src/TimingData.cpp | 50 +++++++++++++++++++++------------------------- src/TimingData.h | 24 +++++++++++----------- 2 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/TimingData.cpp b/src/TimingData.cpp index dcc6b3e560..6c3adbd267 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -176,7 +176,7 @@ void TimingData::SetWarpAtRow( int iRow, float fNew ) for( i=0; i 0 && NoteRowToBeat(iRow) < fNew; + bool valid = iRow > 0 && fNew > 0; if( i == m_WarpSegments.size() ) { if( valid ) @@ -513,7 +513,7 @@ bool TimingData::IsWarpAtRow( int iNoteRow ) const int i = GetWarpSegmentIndexAtRow( iNoteRow ); const WarpSegment& s = m_WarpSegments[i]; - if( s.m_iStartRow <= iNoteRow && iNoteRow < BeatToNoteRow(s.m_fEndBeat) ) + if( s.m_iStartRow <= iNoteRow && iNoteRow < (s.m_iStartRow + BeatToNoteRow(s.m_fEndBeat) ) ) { if( m_StopSegments.empty() ) { @@ -535,7 +535,7 @@ bool TimingData::IsFakeAtRow( int iNoteRow ) const int i = GetFakeSegmentIndexAtRow( iNoteRow ); const FakeSegment& s = m_FakeSegments[i]; - if( s.m_iStartRow <= iNoteRow && iNoteRow < BeatToNoteRow(s.m_fEndBeat) ) + if( s.m_iStartRow <= iNoteRow && iNoteRow < ( s.m_iStartRow + BeatToNoteRow(s.m_fEndBeat) ) ) { return true; } @@ -829,15 +829,18 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float } break; case FOUND_WARP: - bIsWarping = true; - if( itWS->m_fEndBeat > fWarpDestination ) { - fWarpDestination = itWS->m_fEndBeat; + bIsWarping = true; + float fWarpSum = itWS->m_fEndBeat + NoteRowToBeat( itWS->m_iStartRow ); + if( fWarpSum > fWarpDestination ) + { + fWarpDestination = itWS->m_fEndBeat; + } + iWarpBeginOut = iEventRow; + fWarpDestinationOut = fWarpDestination; + itWS ++; + break; } - iWarpBeginOut = iEventRow; - fWarpDestinationOut = fWarpDestination; - itWS ++; - break; } iLastRow = iEventRow; } @@ -921,13 +924,16 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const case FOUND_MARKER: return fLastTime; case FOUND_WARP: - bIsWarping = true; - if( itWS->m_fEndBeat > fWarpDestination ) { - fWarpDestination = itWS->m_fEndBeat; + bIsWarping = true; + float fWarpSum = itWS->m_fEndBeat + NoteRowToBeat( itWS->m_iStartRow ); + if( fWarpSum > fWarpDestination ) + { + fWarpDestination = itWS->m_fEndBeat; + } + itWS ++; + break; } - itWS ++; - break; } iLastRow = iEventRow; } @@ -967,7 +973,7 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { const int iSegStartRow = m_WarpSegments[i].m_iStartRow; - const int iSegEndRow = BeatToNoteRow( m_WarpSegments[i].m_fEndBeat ); + const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_WarpSegments[i].m_fEndBeat ); if( iSegEndRow >= iStartIndex ) { if( iSegEndRow > iEndIndex ) @@ -1030,7 +1036,7 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) { const int iSegStartRow = m_FakeSegments[i].m_iStartRow; - const int iSegEndRow = BeatToNoteRow( m_FakeSegments[i].m_fEndBeat ); + const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_FakeSegments[i].m_fEndBeat ); if( iSegEndRow >= iStartIndex ) { if( iSegEndRow > iEndIndex ) @@ -1093,8 +1099,6 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { WarpSegment &warp = m_WarpSegments[i]; - if( BeatToNoteRow(warp.m_fEndBeat) >= iStartRow ) - warp.m_fEndBeat += NoteRowToBeat(iRowsToAdd); if( warp.m_iStartRow < iStartRow ) continue; warp.m_iStartRow += iRowsToAdd; @@ -1142,8 +1146,6 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) { FakeSegment &fake = m_FakeSegments[i]; - if( BeatToNoteRow(fake.m_fEndBeat) >= iStartRow ) - fake.m_fEndBeat += NoteRowToBeat(iRowsToAdd); if( fake.m_iStartRow < iStartRow ) continue; fake.m_iStartRow += iRowsToAdd; @@ -1210,9 +1212,6 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) { WarpSegment &warp = m_WarpSegments[i]; - if( BeatToNoteRow(warp.m_fEndBeat) >= iStartRow ) - warp.m_fEndBeat = max( NoteRowToBeat(iStartRow), warp.m_fEndBeat - NoteRowToBeat(iRowsToDelete) ); - if( warp.m_iStartRow < iStartRow ) continue; @@ -1326,9 +1325,6 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) { FakeSegment &fake = m_FakeSegments[i]; - if( BeatToNoteRow(fake.m_fEndBeat) >= iStartRow ) - fake.m_fEndBeat = max( NoteRowToBeat(iStartRow), fake.m_fEndBeat - NoteRowToBeat(iRowsToDelete) ); - if( fake.m_iStartRow < iStartRow ) continue; diff --git a/src/TimingData.h b/src/TimingData.h index 61ee14cd16..655a39a2a7 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -313,8 +313,8 @@ struct TimeSignatureSegment * * A warp segment is used to replicate the effects of Negative BPMs without * abusing negative BPMs. Negative BPMs should be converted to warp segments. - * WarpAt=WarpTo is the format, where both are in beats. (Technically they're - * both rows though.) */ + * WarpAt=WarpToRelative is the format, where both are in beats. + * (Technically they're both rows though.) */ struct WarpSegment { /** @@ -326,21 +326,21 @@ struct WarpSegment /** * @brief Create a Warp Segment with the specified starting row and row to warp to. * @param s the starting row of this segment. - * @param r the row to warp to. + * @param r the number of rows to jump ahead. */ WarpSegment( int s, int r ): m_iStartRow(max(0, (s < r ? s : r))), m_fEndBeat(max(0, NoteRowToBeat((r > s ? r : s)))) {} /** * @brief Creates a Warp Segment with the specified starting row and beat to warp to. * @param s the starting row of this segment. - * @param b the beat to warp to. + * @param b the number of beats to jump ahead. */ WarpSegment( int s, float b ): m_iStartRow(max(0, s)), m_fEndBeat(max(0, b)) {} /** * @brief Create a Warp Segment with the specified starting beat and row to warp to. * @param s the starting beat in this segment. - * @param r the row to warp to. + * @param r the number of rows to jump ahead. */ WarpSegment( float s, int r ): m_iStartRow(max(0, BeatToNoteRow(s))), @@ -348,7 +348,7 @@ struct WarpSegment /** * @brief Creates a Warp Segment with the specified starting beat and beat to warp to. * @param s the starting beat of this segment. - * @param b the beat to warp to. + * @param b the number of beats to jump ahead. */ WarpSegment( float s, float b ): m_iStartRow(max(0, BeatToNoteRow((s < b ? s : b)))), @@ -358,7 +358,7 @@ struct WarpSegment */ int m_iStartRow; /** - * @brief The beat to warp to. + * @brief The number of beats to warp ahead by. */ float m_fEndBeat; /** @@ -799,21 +799,21 @@ struct FakeSegment /** * @brief Create a Fake Segment with the specified values. * @param s the starting row of this segment. - * @param r the row to be real again. + * @param r the number of rows this segment lasts. */ FakeSegment( int s, int r ): m_iStartRow(max(0, (s < r ? s : r))), m_fEndBeat(max(0, NoteRowToBeat((r > s ? r : s)))) {} /** * @brief Creates a Fake Segment with the specified values. * @param s the starting row of this segment. - * @param b the beat to be real again. + * @param b the number of beats this segment lasts. */ FakeSegment( int s, float b ): m_iStartRow(max(0, s)), m_fEndBeat(max(0, b)) {} /** * @brief Create a Fake Segment with the specified values. * @param s the starting beat in this segment. - * @param r the row to be real again. + * @param r the number of rows this segment lasts. */ FakeSegment( float s, int r ): m_iStartRow(max(0, BeatToNoteRow(s))), @@ -821,7 +821,7 @@ struct FakeSegment /** * @brief Creates a Fake Segment with the specified values. * @param s the starting beat of this segment. - * @param b the beat to be real again. + * @param b the number of beats this segment lasts. */ FakeSegment( float s, float b ): m_iStartRow(max(0, BeatToNoteRow((s < b ? s : b)))), @@ -831,7 +831,7 @@ struct FakeSegment */ int m_iStartRow; /** - * @brief The beat that ends the FakeSegment. + * @brief The number of beats the FakeSegment is alive for. */ float m_fEndBeat; /** From ea21b98826dd62c4adf0be0356e837282803be83 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 10:45:03 -0400 Subject: [PATCH 155/197] [splittiming] Version fix. --- src/NotesLoaderSSC.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 5019bf9ec0..5e7a9bcc68 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -66,7 +66,11 @@ void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float const float fBeat = StringToFloat( arrayWarpValues[0] ); const float fNewBeat = StringToFloat( arrayWarpValues[1] ); // Early versions were absolute in beats. They should be relative. - if( ( fVersion < VERSION_SPLIT_TIMING && fNewBeat > fBeat ) || fNewBeat > 0 ) + if( ( fVersion < VERSION_SPLIT_TIMING && fNewBeat > fBeat ) ) + { + out.AddWarpSegment( WarpSegment(fBeat, fNewBeat - fBeat) ); + } + else if( fNewBeat > 0 ) out.AddWarpSegment( WarpSegment(fBeat, fNewBeat) ); else { From 1f7389a7a4a5534b9d2f66b700ca8cf515cc1b6a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 10:49:55 -0400 Subject: [PATCH 156/197] [splittiming] Don't do variable swapping. Next up: fixing the editor. --- src/TimingData.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/TimingData.h b/src/TimingData.h index 655a39a2a7..60ac6ae8a8 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -328,8 +328,8 @@ struct WarpSegment * @param s the starting row of this segment. * @param r the number of rows to jump ahead. */ - WarpSegment( int s, int r ): m_iStartRow(max(0, (s < r ? s : r))), - m_fEndBeat(max(0, NoteRowToBeat((r > s ? r : s)))) {} + WarpSegment( int s, int r ): m_iStartRow(s), + m_fEndBeat(NoteRowToBeat(r)) {} /** * @brief Creates a Warp Segment with the specified starting row and beat to warp to. * @param s the starting row of this segment. @@ -351,8 +351,8 @@ struct WarpSegment * @param b the number of beats to jump ahead. */ WarpSegment( float s, float b ): - m_iStartRow(max(0, BeatToNoteRow((s < b ? s : b)))), - m_fEndBeat(max(0, (b > s ? b : s))) {} + m_iStartRow(BeatToNoteRow(s)), + m_fEndBeat(b) {} /** * @brief The row in which the WarpSegment activates. */ @@ -801,8 +801,8 @@ struct FakeSegment * @param s the starting row of this segment. * @param r the number of rows this segment lasts. */ - FakeSegment( int s, int r ): m_iStartRow(max(0, (s < r ? s : r))), - m_fEndBeat(max(0, NoteRowToBeat((r > s ? r : s)))) {} + FakeSegment( int s, int r ): m_iStartRow(s), + m_fEndBeat(NoteRowToBeat(r)) {} /** * @brief Creates a Fake Segment with the specified values. * @param s the starting row of this segment. @@ -824,8 +824,8 @@ struct FakeSegment * @param b the number of beats this segment lasts. */ FakeSegment( float s, float b ): - m_iStartRow(max(0, BeatToNoteRow((s < b ? s : b)))), - m_fEndBeat(max(0, (b > s ? b : s))) {} + m_iStartRow(BeatToNoteRow(s)), + m_fEndBeat(b) {} /** * @brief The row in which the FakeSegment activates. */ From b7dc61104803f786ef364dc3cd46f55cee1a1437 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 21:55:32 +0700 Subject: [PATCH 157/197] [splittiming] rename m_fEndBeat to m_fLengthBeats. let's see how many build errors we have. --- src/TimingData.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/TimingData.h b/src/TimingData.h index 655a39a2a7..a44f566041 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -322,21 +322,21 @@ struct WarpSegment * * It is best to override the values as soon as possible. */ - WarpSegment() : m_iStartRow(-1), m_fEndBeat(-1) { } + WarpSegment() : m_iStartRow(-1), m_fLengthBeats(-1) { } /** * @brief Create a Warp Segment with the specified starting row and row to warp to. * @param s the starting row of this segment. * @param r the number of rows to jump ahead. */ WarpSegment( int s, int r ): m_iStartRow(max(0, (s < r ? s : r))), - m_fEndBeat(max(0, NoteRowToBeat((r > s ? r : s)))) {} + m_fLengthBeats(max(0, NoteRowToBeat((r > s ? r : s)))) {} /** * @brief Creates a Warp Segment with the specified starting row and beat to warp to. * @param s the starting row of this segment. * @param b the number of beats to jump ahead. */ WarpSegment( int s, float b ): m_iStartRow(max(0, s)), - m_fEndBeat(max(0, b)) {} + m_fLengthBeats(max(0, b)) {} /** * @brief Create a Warp Segment with the specified starting beat and row to warp to. * @param s the starting beat in this segment. @@ -344,7 +344,7 @@ struct WarpSegment */ WarpSegment( float s, int r ): m_iStartRow(max(0, BeatToNoteRow(s))), - m_fEndBeat(max(0, NoteRowToBeat(r))) {} + m_fLengthBeats(max(0, NoteRowToBeat(r))) {} /** * @brief Creates a Warp Segment with the specified starting beat and beat to warp to. * @param s the starting beat of this segment. @@ -352,7 +352,7 @@ struct WarpSegment */ WarpSegment( float s, float b ): m_iStartRow(max(0, BeatToNoteRow((s < b ? s : b)))), - m_fEndBeat(max(0, (b > s ? b : s))) {} + m_fLengthBeats(max(0, (b > s ? b : s))) {} /** * @brief The row in which the WarpSegment activates. */ @@ -360,7 +360,7 @@ struct WarpSegment /** * @brief The number of beats to warp ahead by. */ - float m_fEndBeat; + float m_fLengthBeats; /** * @brief Compares two WarpSegments to see if they are equal to each other. * @param other the other WarpSegment to compare to. @@ -369,7 +369,7 @@ struct WarpSegment bool operator==( const WarpSegment &other ) const { COMPARE( m_iStartRow ); - COMPARE( m_fEndBeat ); + COMPARE( m_fLengthBeats ); return true; } /** @@ -386,7 +386,7 @@ struct WarpSegment bool operator<( const WarpSegment &other ) const { return m_iStartRow < other.m_iStartRow || - ( m_iStartRow == other.m_iStartRow && m_fEndBeat < other.m_fEndBeat ); + ( m_iStartRow == other.m_iStartRow && m_fLengthBeats < other.m_fLengthBeats ); } /** * @brief Compares two WarpSegments to see if one is less than or equal to the other. @@ -795,21 +795,21 @@ struct FakeSegment * * It is best to override the values as soon as possible. */ - FakeSegment() : m_iStartRow(-1), m_fEndBeat(-1) { } + FakeSegment() : m_iStartRow(-1), m_fLengthBeats(-1) { } /** * @brief Create a Fake Segment with the specified values. * @param s the starting row of this segment. * @param r the number of rows this segment lasts. */ FakeSegment( int s, int r ): m_iStartRow(max(0, (s < r ? s : r))), - m_fEndBeat(max(0, NoteRowToBeat((r > s ? r : s)))) {} + m_fLengthBeats(max(0, NoteRowToBeat((r > s ? r : s)))) {} /** * @brief Creates a Fake Segment with the specified values. * @param s the starting row of this segment. * @param b the number of beats this segment lasts. */ FakeSegment( int s, float b ): m_iStartRow(max(0, s)), - m_fEndBeat(max(0, b)) {} + m_fLengthBeats(max(0, b)) {} /** * @brief Create a Fake Segment with the specified values. * @param s the starting beat in this segment. @@ -817,7 +817,7 @@ struct FakeSegment */ FakeSegment( float s, int r ): m_iStartRow(max(0, BeatToNoteRow(s))), - m_fEndBeat(max(0, NoteRowToBeat(r))) {} + m_fLengthBeats(max(0, NoteRowToBeat(r))) {} /** * @brief Creates a Fake Segment with the specified values. * @param s the starting beat of this segment. @@ -825,7 +825,7 @@ struct FakeSegment */ FakeSegment( float s, float b ): m_iStartRow(max(0, BeatToNoteRow((s < b ? s : b)))), - m_fEndBeat(max(0, (b > s ? b : s))) {} + m_fLengthBeats(max(0, (b > s ? b : s))) {} /** * @brief The row in which the FakeSegment activates. */ @@ -833,7 +833,7 @@ struct FakeSegment /** * @brief The number of beats the FakeSegment is alive for. */ - float m_fEndBeat; + float m_fLengthBeats; /** * @brief Compares two FakeSegments to see if they are equal to each other. * @param other the other FakeSegment to compare to. @@ -842,7 +842,7 @@ struct FakeSegment bool operator==( const FakeSegment &other ) const { COMPARE( m_iStartRow ); - COMPARE( m_fEndBeat ); + COMPARE( m_fLengthBeats ); return true; } /** @@ -859,7 +859,7 @@ struct FakeSegment bool operator<( const FakeSegment &other ) const { return m_iStartRow < other.m_iStartRow || - ( m_iStartRow == other.m_iStartRow && m_fEndBeat < other.m_fEndBeat ); + ( m_iStartRow == other.m_iStartRow && m_fLengthBeats < other.m_fLengthBeats ); } /** * @brief Compares two FakeSegments to see if one is less than or equal to the other. From fc72f2de90c857347097a06f6171e8675ee721d0 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 10:56:00 -0400 Subject: [PATCH 158/197] [splittiming] Prepare the editor. --- Themes/_fallback/Languages/en.ini | 2 +- src/ScreenEdit.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 4267bfe208..2c5192464e 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1231,7 +1231,7 @@ Enter a new Time Signature denominator value.=Enter the note value that represen Enter a new Tickcount value.=Enter a new Tickcount value. Enter a new Combo value.=Enter a new Combo value. Enter a new Label value.=Enter a name for this section of the chart. -Enter a new Warp value.=Enter the beat you will warp to when you reach this point. +Enter a new Warp value.=Enter the number of beats you will warp over. Enter a new Speed percent value.=Enter the ratio for speed scrolling.\n\n1 is the default scroll. Enter a new Speed wait value.=Enter how long in seconds/beats it takes to change.\n\n0 is instant. Enter a new Speed mode value.=Enter how this segment is handled.\n\nType "0" for beats, "1" for seconds. diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 95e51299b0..aa3dd8ca3f 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2763,8 +2763,11 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) else if ( SM == SM_BackFromWarpChange ) { float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer ); - GetAppropriateTiming().SetWarpAtBeat( GetBeat(), fWarp ); - SetDirty( true ); + if( fWarp > 0 ) + { + GetAppropriateTiming().SetWarpAtBeat( GetBeat(), fWarp ); + SetDirty( true ); + } } else if( SM == SM_BackFromSpeedPercentChange ) { From 388eb6bf1014f9f8234a6d5c5f69c4060c086281 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 10:57:14 -0400 Subject: [PATCH 159/197] [splittiming] Updated comment. --- src/ScreenEdit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index aa3dd8ca3f..680a9598af 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2763,7 +2763,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) else if ( SM == SM_BackFromWarpChange ) { float fWarp = StringToFloat( ScreenTextEntry::s_sLastAnswer ); - if( fWarp > 0 ) + if( fWarp >= 0 ) // allow 0 to kill a warp. { GetAppropriateTiming().SetWarpAtBeat( GetBeat(), fWarp ); SetDirty( true ); From d064547985e74d7a022b5756851a418a08bf40a4 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 22:05:23 +0700 Subject: [PATCH 160/197] [splittiming] fix TimingData.cpp --- src/TimingData.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 6c3adbd267..d2fe29d203 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -188,7 +188,7 @@ void TimingData::SetWarpAtRow( int iRow, float fNew ) { if( valid ) { - m_WarpSegments[i].m_fEndBeat = fNew; + m_WarpSegments[i].m_fLengthBeats = fNew; } else m_WarpSegments.erase( m_WarpSegments.begin()+i, m_WarpSegments.begin()+i+1 ); @@ -308,7 +308,7 @@ void TimingData::SetFakeAtRow( int iRow, float fNew ) { if( valid ) { - m_FakeSegments[i].m_fEndBeat = fNew; + m_FakeSegments[i].m_fLengthBeats = fNew; } else m_FakeSegments.erase( m_FakeSegments.begin()+i, m_FakeSegments.begin()+i+1 ); @@ -379,7 +379,7 @@ float TimingData::GetWarpAtRow( int iWarpRow ) const { if( m_WarpSegments[i].m_iStartRow == iWarpRow ) { - return m_WarpSegments[i].m_fEndBeat; + return m_WarpSegments[i].m_fLengthBeats; } } return 0; @@ -406,7 +406,7 @@ float TimingData::GetFakeAtRow( int iFakeRow ) const { if( m_FakeSegments[i].m_iStartRow == iFakeRow ) { - return m_FakeSegments[i].m_fEndBeat; + return m_FakeSegments[i].m_fLengthBeats; } } return 0; @@ -513,7 +513,7 @@ bool TimingData::IsWarpAtRow( int iNoteRow ) const int i = GetWarpSegmentIndexAtRow( iNoteRow ); const WarpSegment& s = m_WarpSegments[i]; - if( s.m_iStartRow <= iNoteRow && iNoteRow < (s.m_iStartRow + BeatToNoteRow(s.m_fEndBeat) ) ) + if( s.m_iStartRow <= iNoteRow && iNoteRow < (s.m_iStartRow + BeatToNoteRow(s.m_fLengthBeats) ) ) { if( m_StopSegments.empty() ) { @@ -535,7 +535,7 @@ bool TimingData::IsFakeAtRow( int iNoteRow ) const int i = GetFakeSegmentIndexAtRow( iNoteRow ); const FakeSegment& s = m_FakeSegments[i]; - if( s.m_iStartRow <= iNoteRow && iNoteRow < ( s.m_iStartRow + BeatToNoteRow(s.m_fEndBeat) ) ) + if( s.m_iStartRow <= iNoteRow && iNoteRow < ( s.m_iStartRow + BeatToNoteRow(s.m_fLengthBeats) ) ) { return true; } @@ -831,10 +831,10 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float case FOUND_WARP: { bIsWarping = true; - float fWarpSum = itWS->m_fEndBeat + NoteRowToBeat( itWS->m_iStartRow ); + float fWarpSum = itWS->m_fLengthBeats + NoteRowToBeat( itWS->m_iStartRow ); if( fWarpSum > fWarpDestination ) { - fWarpDestination = itWS->m_fEndBeat; + fWarpDestination = fWarpSum; } iWarpBeginOut = iEventRow; fWarpDestinationOut = fWarpDestination; @@ -926,10 +926,10 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const case FOUND_WARP: { bIsWarping = true; - float fWarpSum = itWS->m_fEndBeat + NoteRowToBeat( itWS->m_iStartRow ); + float fWarpSum = itWS->m_fLengthBeats + NoteRowToBeat( itWS->m_iStartRow ); if( fWarpSum > fWarpDestination ) { - fWarpDestination = itWS->m_fEndBeat; + fWarpDestination = fWarpSum; } itWS ++; break; @@ -973,13 +973,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { const int iSegStartRow = m_WarpSegments[i].m_iStartRow; - const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_WarpSegments[i].m_fEndBeat ); + const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_WarpSegments[i].m_fLengthBeats ); if( iSegEndRow >= iStartIndex ) { if( iSegEndRow > iEndIndex ) - m_WarpSegments[i].m_fEndBeat += NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))); + m_WarpSegments[i].m_fLengthBeats += NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))); else - m_WarpSegments[i].m_fEndBeat = NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale) + iStartIndex); + m_WarpSegments[i].m_fLengthBeats = NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale)); } if( iSegStartRow < iStartIndex ) continue; @@ -1036,13 +1036,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) { const int iSegStartRow = m_FakeSegments[i].m_iStartRow; - const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_FakeSegments[i].m_fEndBeat ); + const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_FakeSegments[i].m_fLengthBeats ); if( iSegEndRow >= iStartIndex ) { if( iSegEndRow > iEndIndex ) - m_FakeSegments[i].m_fEndBeat += NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))); + m_FakeSegments[i].m_fLengthBeats += NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))); else - m_FakeSegments[i].m_fEndBeat = NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale) + iStartIndex); + m_FakeSegments[i].m_fLengthBeats = NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale)); } if( iSegStartRow < iStartIndex ) continue; From c11c8db883bea75fa02c2ddc75c4418fdfb83484 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 22:06:07 +0700 Subject: [PATCH 161/197] [splittiming] it builds! time to merge. --- src/NoteField.cpp | 2 +- src/NotesWriterSSC.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 1ad62d255b..2f136a7794 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -879,7 +879,7 @@ void NoteField::DrawPrimitives() { float fBeat = NoteRowToBeat(seg->m_iStartRow); if( IS_ON_SCREEN(fBeat) ) - DrawWarpText( fBeat, seg->m_fEndBeat ); + DrawWarpText( fBeat, seg->m_fLengthBeats ); } } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 3f01843b06..fcc88c39ba 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -112,7 +112,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo { w.Init( "WARPS" ); FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws ) - w.Write( ws->m_iStartRow, ws->m_fEndBeat ); + w.Write( ws->m_iStartRow, ws->m_fLengthBeats ); w.Finish(); } @@ -143,7 +143,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Init( "FAKES" ); FOREACH_CONST( FakeSegment, timing.m_FakeSegments, fs ) - w.Write( fs->m_iStartRow, fs->m_fEndBeat ); + w.Write( fs->m_iStartRow, fs->m_fLengthBeats ); w.Finish(); } From 2e0649f6f44265e9a89ebf009e5a60b89ba35b30 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 11:30:39 -0400 Subject: [PATCH 162/197] [splittiming] Let Fakes be edited. Also expand on some descriptions. --- Themes/_fallback/Languages/en.ini | 18 ++++++++++-------- src/ScreenEdit.cpp | 24 ++++++++++++++++++++++++ src/ScreenEdit.h | 1 + 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 2c5192464e..9b9fbf2f51 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -857,6 +857,7 @@ Edit warp=Edit warp Edit speed (percent)=Edit speed (percent) Edit speed (wait)=Edit speed (length) Edit speed (mode)=Edit speed (mode) +Edit fake=Edit fake segment Editor options=Options EditorShowBGChangesPlay=Show Backgrounds Erase step timing=Erase step timing @@ -1223,18 +1224,19 @@ Can't undo - no undo data.=Can't undo - no undo data. Do you want to revert from disk?=Do you want to revert from disk? Do you want to revert to your last save?=Do you want to revert to your last save? Do you want to save changes before exiting?=Do you want to save changes before exiting? -Enter a new BPM value.=Enter a new BPM value. -Enter a new Stop value.=Enter a new Stop value. -Enter a new Delay value.=Enter a new Delay value. +Enter a new BPM value.=Enter a new BPM value.\n\nEnter the previous value to remove. +Enter a new Stop value.=Enter a new Stop value.\n\nType "0" to remove. +Enter a new Delay value.=Enter a new Delay value.\n\nType "0" to remove. Enter a new Time Signature numerator value.=Enter the number of beats per measure. Enter a new Time Signature denominator value.=Enter the note value that represents one beat. -Enter a new Tickcount value.=Enter a new Tickcount value. -Enter a new Combo value.=Enter a new Combo value. -Enter a new Label value.=Enter a name for this section of the chart. -Enter a new Warp value.=Enter the number of beats you will warp over. -Enter a new Speed percent value.=Enter the ratio for speed scrolling.\n\n1 is the default scroll. +Enter a new Tickcount value.=Enter a new Tickcount value.\n\nEnter the previous value to remove. +Enter a new Combo value.=Enter a new Combo value.\n\nEnter the previous value to remove. +Enter a new Label value.=Enter a name for this section of the chart.\n\nEnter a previously used label to remove. +Enter a new Warp value.=Enter the number of beats you will warp over.\n\nType "0" to remove this segment. +Enter a new Speed percent value.=Enter the ratio for speed scrolling.\n\nEnter the previous value to remove.\n\n1 is the default scroll. Enter a new Speed wait value.=Enter how long in seconds/beats it takes to change.\n\n0 is instant. Enter a new Speed mode value.=Enter how this segment is handled.\n\nType "0" for beats, "1" for seconds. +Enter a new Fake value.=Enter the number of beats that won't be judged.\n\nType "0" to remove this. Are you sure you want to erase this chart's timing data?=Are you sure you want to erase this chart's timing data? Enter a new artist transliteration.=Enter a new artist transliteration. Enter a new artist.=Enter a new artist. diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 680a9598af..92f4f1d6aa 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -86,6 +86,7 @@ AutoScreenMessage( SM_BackFromWarpChange ); AutoScreenMessage( SM_BackFromSpeedPercentChange ); AutoScreenMessage( SM_BackFromSpeedWaitChange ); AutoScreenMessage( SM_BackFromSpeedModeChange ); +AutoScreenMessage( SM_BackFromFakeChange ); AutoScreenMessage( SM_DoEraseStepTiming ); AutoScreenMessage( SM_DoSaveAndExit ); AutoScreenMessage( SM_DoExit ); @@ -582,6 +583,7 @@ static MenuDef g_TimingDataInformation( MenuRowDef( ScreenEdit::speed_percent, "Edit speed (percent)", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::speed_wait, "Edit speed (wait)", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::speed_mode, "Edit speed (mode)", true, EditMode_Full, true, true, 0, "Beats", "Seconds" ), + MenuRowDef( ScreenEdit::fake, "Edit fake", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::erase_step_timing, "Erase step timing", true, EditMode_Full, true, true, 0, NULL ) ); @@ -2797,6 +2799,15 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } SetDirty( true ); } + else if ( SM == SM_BackFromFakeChange ) + { + float fFake = StringToFloat( ScreenTextEntry::s_sLastAnswer ); + if( fFake >= 0 ) // allow 0 to kill a warp. + { + GetAppropriateTiming().SetFakeAtBeat( GetBeat(), fFake ); + SetDirty( true ); + } + } else if( SM == SM_BackFromBGChange ) { @@ -3217,12 +3228,15 @@ void ScreenEdit::DisplayTimingMenu() RString starting = ( pTime.GetSpeedModeAtBeat( fBeat ) == 1 ? "Seconds" : "Beats" ); g_TimingDataInformation.rows[speed_mode].SetOneUnthemedChoice( starting.c_str() ); + g_TimingDataInformation.rows[fake].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetFakeAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[combo].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[warp].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[speed_percent].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[speed_wait].bEnabled = GAMESTATE->m_bIsEditorStepTiming; g_TimingDataInformation.rows[speed_mode].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_TimingDataInformation.rows[fake].bEnabled = GAMESTATE->m_bIsEditorStepTiming; EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); } @@ -3904,6 +3918,7 @@ static LocalizedString ENTER_WARP_VALUE ( "ScreenEdit", "Enter a new Warp val static LocalizedString ENTER_SPEED_PERCENT_VALUE ( "ScreenEdit", "Enter a new Speed percent value." ); static LocalizedString ENTER_SPEED_WAIT_VALUE ( "ScreenEdit", "Enter a new Speed wait value." ); static LocalizedString ENTER_SPEED_MODE_VALUE ( "ScreenEdit", "Enter a new Speed mode value." ); +static LocalizedString ENTER_FAKE_VALUE ( "ScreenEdit", "Enter a new Fake value." ); static LocalizedString CONFIRM_TIMING_ERASE ( "ScreenEdit", "Are you sure you want to erase this chart's timing data?" ); void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice c, const vector &iAnswers ) { @@ -4014,6 +4029,15 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice break; } + case fake: + { + ScreenTextEntry::TextEntry( + SM_BackFromFakeChange, + ENTER_FAKE_VALUE, + ssprintf("%.5f", GetAppropriateTiming().GetFakeAtBeat( GetBeat() ) ), + 10 + ); + } case erase_step_timing: ScreenPrompt::Prompt( SM_DoEraseStepTiming, CONFIRM_TIMING_ERASE , PROMPT_YES_NO, ANSWER_NO ); break; diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index e1e3bd4435..4336517238 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -501,6 +501,7 @@ public: speed_wait, speed_mode, erase_step_timing, + fake, NUM_TIMING_DATA_INFORMATION_CHOICES }; From cb71d0a4c5ec63323975893c28ecc3914f0c5a61 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 22:39:02 +0700 Subject: [PATCH 163/197] [splittiming] allow b, B, beat, basically anything that begins with a 'b' to be recognized as beats here. --- src/ScreenEdit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 680a9598af..11a6a3690d 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2787,7 +2787,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) else if ( SM == SM_BackFromSpeedModeChange ) { int tmp = StringToInt(ScreenTextEntry::s_sLastAnswer ); - if( tmp == 0 ) + if( tmp == 0 || ScreenTextEntry::s_sLastAnswer.substr(0, 1) == "b" || ScreenTextEntry::s_sLastAnswer.substr(0, 1) == "B" ) { GetAppropriateTiming().SetSpeedModeAtBeat( GetBeat(), 0 ); } From 161ccdeb686d535c69de3fa91fa39efb5cca6050 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 11:42:58 -0400 Subject: [PATCH 164/197] [splittiming] Implement Fake Segments...already? This was a bit fast I think. --- src/Player.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Player.cpp b/src/Player.cpp index 95878e4c1c..98483728b7 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -1530,7 +1530,7 @@ int Player::GetClosestNoteDirectional( int col, int iStartRow, int iEndRow, bool // Is this the row we want? do { const TapNote &tn = begin->second; - if( m_Timing->IsWarpAtRow( begin->first ) ) + if( m_Timing->IsWarpAtRow( begin->first ) || m_Timing->IsFakeAtRow( begin->first ) ) break; if( tn.type == TapNote::empty ) break; @@ -1581,7 +1581,7 @@ int Player::GetClosestNonEmptyRowDirectional( int iStartRow, int iEndRow, bool b ++iter; continue; } - if( m_Timing->IsWarpAtRow( iter.Row() ) ) + if( m_Timing->IsWarpAtRow( iter.Row() ) || m_Timing->IsFakeAtRow( iter.Row() ) ) { ++iter; continue; @@ -2100,7 +2100,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b // Stepped too close to mine? if( !bRelease && ( REQUIRE_STEP_ON_MINES == !bHeld ) && fSecondsFromExact <= GetWindowSeconds(TW_Mine) && - !m_Timing->IsWarpAtRow(iSongRow) ) + !m_Timing->IsWarpAtRow(iSongRow) && !m_Timing->IsFakeAtRow(iSongRow)) score = TNS_HitMine; break; @@ -2597,8 +2597,8 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) if( !NeedsTapJudging(tn) ) continue; - // Ignore all notes that are skipped via WARPS. - if( m_Timing->IsWarpAtRow( iter.Row() ) ) + // Ignore all notes in WarpSegments or FakeSegments. + if( m_Timing->IsWarpAtRow( iter.Row() ) || m_Timing->IsFakeAtRow( iter.Row() ) ) continue; if( tn.type == TapNote::mine ) @@ -2632,8 +2632,8 @@ void Player::UpdateJudgedRows() { int iRow = iter.Row(); - // If row is within a warp section, ignore it. -aj - if( m_Timing->IsWarpAtRow(iRow) ) + // Do not judge arrows in WarpSegments or FakeSegments + if( m_Timing->IsWarpAtRow(iRow) || m_Timing->IsFakeAtRow(iRow) ) continue; if( iLastSeenRow != iRow ) @@ -2967,8 +2967,8 @@ void Player::HandleTapRowScore( unsigned row ) bNoCheating = false; #endif - // Warp hackery. -aj - if( m_Timing->IsWarpAtRow( row ) ) + // Do not score rows in WarpSegments or FakeSegments + if( m_Timing->IsWarpAtRow( row ) || m_Timing->IsFakeAtRow( row ) ) return; if( GAMESTATE->m_bDemonstrationOrJukebox ) @@ -3071,8 +3071,8 @@ void Player::HandleHoldCheckpoint( int iRow, int iNumHoldsHeldThisRow, int iNumH bNoCheating = false; #endif - // More warp hackery. -aj - if( m_Timing->IsWarpAtRow( iRow ) ) + // WarpSegments and FakeSegments aren't judged in any way. + if( m_Timing->IsWarpAtRow( iRow ) || m_Timing->IsFakeAtRow( iRow ) ) return; // don't accumulate combo if AutoPlay is on. From 1fd19c62a7e6beafed66975b26e72fd933ca2720 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 22:44:56 +0700 Subject: [PATCH 165/197] [splittiming] input fixes --- src/ScreenEdit.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 43778456be..cce5f82bf4 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2788,15 +2788,26 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } else if ( SM == SM_BackFromSpeedModeChange ) { - int tmp = StringToInt(ScreenTextEntry::s_sLastAnswer ); - if( tmp == 0 || ScreenTextEntry::s_sLastAnswer.substr(0, 1) == "b" || ScreenTextEntry::s_sLastAnswer.substr(0, 1) == "B" ) + if( ScreenTextEntry::s_sLastAnswer.substr(0, 1) == "b" || ScreenTextEntry::s_sLastAnswer.substr(0, 1) == "B" ) { GetAppropriateTiming().SetSpeedModeAtBeat( GetBeat(), 0 ); } - else + else if( ScreenTextEntry::s_sLastAnswer.substr(0, 1) == "s" || ScreenTextEntry::s_sLastAnswer.substr(0, 1) == "S" ) { GetAppropriateTiming().SetSpeedModeAtBeat( GetBeat(), 1 ); } + else + { + int tmp = StringToInt(ScreenTextEntry::s_sLastAnswer ); + if( tmp == 0 ) + { + GetAppropriateTiming().SetSpeedModeAtBeat( GetBeat(), 0 ); + } + else + { + GetAppropriateTiming().SetSpeedModeAtBeat( GetBeat(), 1 ); + } + } SetDirty( true ); } else if ( SM == SM_BackFromFakeChange ) From c0e53205ea17a5bc50df46b6a61246fb1f2b5dd4 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 11:54:58 -0400 Subject: [PATCH 166/197] [splittiming] Don't show warps on Song Timing. --- src/NoteField.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 2f136a7794..4f9c3031cf 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -873,16 +873,19 @@ void NoteField::DrawPrimitives() } // Warp text - FOREACH_CONST( WarpSegment, timing.m_WarpSegments, seg ) + if( GAMESTATE->m_bIsEditorStepTiming ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + FOREACH_CONST( WarpSegment, timing.m_WarpSegments, seg ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); - if( IS_ON_SCREEN(fBeat) ) - DrawWarpText( fBeat, seg->m_fLengthBeats ); + if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + { + float fBeat = NoteRowToBeat(seg->m_iStartRow); + if( IS_ON_SCREEN(fBeat) ) + DrawWarpText( fBeat, seg->m_fLengthBeats ); + } } } - + // Time Signature text FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, seg ) { From 5206fa2c8c75fd2d3d40cceffe3216e3f28af3d8 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 12:02:17 -0400 Subject: [PATCH 167/197] [splittiming] Show fake segments in editor. --- Themes/_fallback/metrics.ini | 3 +++ src/NoteField.cpp | 34 ++++++++++++++++++++++++++++++++++ src/NoteField.h | 1 + 3 files changed, 38 insertions(+) diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 3189c3444e..d5abd2703b 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -990,6 +990,7 @@ TickcountColor=color("0,1,0,1") ComboColor=color("0.55,1,0,1") LabelColor=color("1,0,0,1") SpeedColor=color("0.5,1,1,1") +FakeColor=color("1,1,0.5,1") # BPMIsLeftSide=true StopIsLeftSide=true @@ -1000,6 +1001,7 @@ TickcountIsLeftSide=false ComboIsLeftSide=false LabelIsLeftSide=false SpeedIsLeftSide=false +FakeIsLeftSide=true # BPMOffsetX=60 StopOffsetX=50 @@ -1010,6 +1012,7 @@ TickcountOffsetX=70 ComboOffsetX=50 LabelOffsetX=130 SpeedOffsetX=30 +FakeOffsetX=90 [PlayerStageStats] # Original CVS Grading diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 4f9c3031cf..24dfddf6e4 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -455,6 +455,7 @@ static ThemeMetric TICKCOUNT_COLOR ( "NoteField", "TickcountColor" ); static ThemeMetric COMBO_COLOR ( "NoteField", "ComboColor" ); static ThemeMetric LABEL_COLOR ( "NoteField", "LabelColor" ); static ThemeMetric SPEED_COLOR ( "NoteField", "SpeedColor" ); +static ThemeMetric FAKE_COLOR ("NoteField", "FakeColor" ); static ThemeMetric BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" ); static ThemeMetric STOP_IS_LEFT_SIDE ( "NoteField", "StopIsLeftSide" ); static ThemeMetric DELAY_IS_LEFT_SIDE ( "NoteField", "DelayIsLeftSide" ); @@ -464,6 +465,7 @@ static ThemeMetric TICKCOUNT_IS_LEFT_SIDE ( "NoteField", "TickcountIsLeftS static ThemeMetric COMBO_IS_LEFT_SIDE ( "NoteField", "ComboIsLeftSide" ); static ThemeMetric LABEL_IS_LEFT_SIDE ( "NoteField", "LabelIsLeftSide" ); static ThemeMetric SPEED_IS_LEFT_SIDE ( "NoteField", "SpeedIsLeftSide" ); +static ThemeMetric FAKE_IS_LEFT_SIDE ( "NoteField", "FakeIsLeftSide" ); static ThemeMetric BPM_OFFSETX ( "NoteField", "BPMOffsetX" ); static ThemeMetric STOP_OFFSETX ( "NoteField", "StopOffsetX" ); static ThemeMetric DELAY_OFFSETX ( "NoteField", "DelayOffsetX" ); @@ -473,6 +475,7 @@ static ThemeMetric TICKCOUNT_OFFSETX ( "NoteField", "TickcountOffsetX" ); static ThemeMetric COMBO_OFFSETX ( "NoteField", "ComboOffsetX" ); static ThemeMetric LABEL_OFFSETX ( "NoteField", "LabelOffsetX" ); static ThemeMetric SPEED_OFFSETX ( "NoteField", "SpeedOffsetX" ); +static ThemeMetric FAKE_OFFSETX ( "NoteField", "FakeOffsetX" ); void NoteField::DrawBPMText( const float fBeat, const float fBPM ) { @@ -619,6 +622,23 @@ void NoteField::DrawSpeedText( const float fBeat, float fPercent, float fWait, u m_textMeasureNumber.Draw(); } +void NoteField::DrawFakeText( const float fBeat, const float fNewBeat ) +{ + const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat ); + const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels ); + const float fZoom = ArrowEffects::GetZoom( m_pPlayerState ); + const float xBase = GetWidth()/2.f; + const float xOffset = FAKE_OFFSETX * fZoom; + + m_textMeasureNumber.SetZoom( fZoom ); + m_textMeasureNumber.SetHorizAlign( FAKE_IS_LEFT_SIDE ? align_right : align_left ); + m_textMeasureNumber.SetDiffuse( FAKE_COLOR ); + m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) ); + m_textMeasureNumber.SetText( ssprintf("%.3f", fNewBeat) ); + m_textMeasureNumber.SetXY( (FAKE_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos ); + m_textMeasureNumber.Draw(); +} + void NoteField::DrawAttackText( const float fBeat, const Attack &attack ) { const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat ); @@ -948,6 +968,20 @@ void NoteField::DrawPrimitives() } } } + + // Speed text + if( GAMESTATE->m_bIsEditorStepTiming ) + { + FOREACH_CONST( FakeSegment, timing.m_FakeSegments, seg ) + { + if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + { + float fBeat = NoteRowToBeat(seg->m_iStartRow); + if( IS_ON_SCREEN(fBeat) ) + DrawFakeText( fBeat, seg->m_fLengthBeats ); + } + } + } // Course mods text const Course *pCourse = GAMESTATE->m_pCurCourse; diff --git a/src/NoteField.h b/src/NoteField.h index b3993fd6f6..a4193f41a5 100644 --- a/src/NoteField.h +++ b/src/NoteField.h @@ -65,6 +65,7 @@ protected: void DrawComboText( const float fBeat, int iCombo ); void DrawLabelText( const float fBeat, RString sLabel ); void DrawSpeedText( const float fBeat, float fPercent, float fWait, unsigned short usMode ); + void DrawFakeText( const float fBeat, const float fNewBeat ); void DrawAttackText( const float fBeat, const Attack &attack ); void DrawBGChangeText( const float fBeat, const RString sNewBGName ); float GetWidth() const; From a933492f8a5f3e0956d7a28b14f25ec33a923521 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 23:05:51 +0700 Subject: [PATCH 168/197] [splittiming] allow entering both numerator and denominator of time signature at the same time (not working) --- src/ScreenEdit.cpp | 44 ++++++++++++-------------------------------- src/ScreenEdit.h | 4 +--- 2 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index cce5f82bf4..947bb54ee9 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -77,8 +77,7 @@ AutoScreenMessage( SM_BackFromDifficultyMeterChange ); AutoScreenMessage( SM_BackFromBPMChange ); AutoScreenMessage( SM_BackFromStopChange ); AutoScreenMessage( SM_BackFromDelayChange ); -AutoScreenMessage( SM_BackFromTimeSignatureNumeratorChange ); -AutoScreenMessage( SM_BackFromTimeSignatureDenominatorChange ); +AutoScreenMessage( SM_BackFromTimeSignatureChange ); AutoScreenMessage( SM_BackFromTickcountChange ); AutoScreenMessage( SM_BackFromComboChange ); AutoScreenMessage( SM_BackFromLabelChange ); @@ -574,8 +573,7 @@ static MenuDef g_TimingDataInformation( MenuRowDef( ScreenEdit::bpm, "Edit BPM change", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::stop, "Edit stop", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::delay, "Edit delay", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::time_signature_numerator, "Edit time signature (top)", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::time_signature_denominator, "Edit time signature (bottom)", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef( ScreenEdit::time_signature, "Edit time signature", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::label, "Edit label", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::combo, "Edit combo", true, EditMode_Full, true, true, 0, NULL ), @@ -2715,20 +2713,12 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) GetAppropriateTiming().SetStopAtBeat( GetBeat(), fDelay, true ); SetDirty( true ); } - else if( SM == SM_BackFromTimeSignatureNumeratorChange ) + else if( SM == SM_BackFromTimeSignatureChange ) { - int iNum = StringToInt( ScreenTextEntry::s_sLastAnswer ); - if( iNum > 0 ) + int iNum, iDen; + if( sscanf( " %d / %d ", ScreenTextEntry::s_sLastAnswer.c_str(), &iNum, &iDen ) == 2 ) { GetAppropriateTiming().SetTimeSignatureNumeratorAtBeat( GetBeat(), iNum ); - } - SetDirty( true ); - } - else if ( SM == SM_BackFromTimeSignatureDenominatorChange ) - { - int iDen = StringToInt( ScreenTextEntry::s_sLastAnswer ); - if( iDen > 0) - { GetAppropriateTiming().SetTimeSignatureDenominatorAtBeat( GetBeat(), iDen ); } SetDirty( true ); @@ -3227,8 +3217,7 @@ void ScreenEdit::DisplayTimingMenu() g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetStopAtBeat( fBeat ) ) ) ; g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetDelayAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[time_signature_numerator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[time_signature_denominator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) ); + g_TimingDataInformation.rows[time_signature].SetOneUnthemedChoice( ssprintf("%d / %d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ), pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[label].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() ); g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) ); g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) ); @@ -3920,8 +3909,7 @@ static LocalizedString ENTER_BEAT_0_OFFSET ( "ScreenEdit", "Enter the offset f static LocalizedString ENTER_BPM_VALUE ( "ScreenEdit", "Enter a new BPM value." ); static LocalizedString ENTER_STOP_VALUE ( "ScreenEdit", "Enter a new Stop value." ); static LocalizedString ENTER_DELAY_VALUE ( "ScreenEdit", "Enter a new Delay value." ); -static LocalizedString ENTER_TIME_SIGNATURE_NUMERATOR_VALUE ( "ScreenEdit", "Enter a new Time Signature numerator value." ); -static LocalizedString ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE ( "ScreenEdit", "Enter a new Time Signature denominator value." ); +static LocalizedString ENTER_TIME_SIGNATURE_VALUE ( "ScreenEdit", "Enter a new Time Signature." ); static LocalizedString ENTER_TICKCOUNT_VALUE ( "ScreenEdit", "Enter a new Tickcount value." ); static LocalizedString ENTER_COMBO_VALUE ( "ScreenEdit", "Enter a new Combo value." ); static LocalizedString ENTER_LABEL_VALUE ( "ScreenEdit", "Enter a new Label value." ); @@ -3965,20 +3953,12 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice 10 ); break; - case time_signature_numerator: + case time_signature: ScreenTextEntry::TextEntry( - SM_BackFromTimeSignatureNumeratorChange, - ENTER_TIME_SIGNATURE_NUMERATOR_VALUE, - ssprintf( "%d", GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iNumerator ), - 3 - ); - break; - case time_signature_denominator: - ScreenTextEntry::TextEntry( - SM_BackFromTimeSignatureDenominatorChange, - ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE, - ssprintf( "%d", GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iDenominator ), - 3 + SM_BackFromTimeSignatureChange, + ENTER_TIME_SIGNATURE_VALUE, + ssprintf( "%d/%d", GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iNumerator, GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iDenominator ), + 8 ); break; case tickcount: diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 4336517238..5bb5f6fbda 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -489,9 +489,7 @@ public: bpm, stop, delay, -// time_signature, - time_signature_numerator, - time_signature_denominator, + time_signature, label, tickcount, combo, From 59c54a563eab0097213a4d635f6c6948d015d7f8 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 12:08:01 -0400 Subject: [PATCH 169/197] [splittiming] Changelogs, doc cleanup. --- Docs/Changelog_SSCformat.txt | 2 ++ Docs/Changelog_sm5.txt | 8 ++++++++ Docs/SimfileFormats/ssc_msd5.txt | 16 ++++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Docs/Changelog_SSCformat.txt b/Docs/Changelog_SSCformat.txt index baa1f8ecc7..e5bcf25049 100644 --- a/Docs/Changelog_SSCformat.txt +++ b/Docs/Changelog_SSCformat.txt @@ -12,6 +12,8 @@ ________________________________________________________________________________ [v0.7] - theDtTvB, Wolfman2000 * Split Timing officially implemented. * #SPEEDS tag for modified scroll speeds. +* #FAKES tag for ignoring judgments within a range. +* #WARPS modified so that second parameter is now relative to the start. [v0.59] - Wolfman2000 * Typo fix: #RADARVALUES needed a semicolon at the end, not a colon. diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index fccd9d9425..64f0bacbd3 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -8,6 +8,14 @@ ________________________________________________________________________________ StepMania 5.0 $NEXT | 20110xyy -------------------------------------------------------------------------------- +2011/05/16 +---------- +* Added #FAKES to the SSC format. Similar to the fake arrows, these blocks + prevent all judgments within the range. [Wolfman2000] +* Changed the syntax of #WARPS slightly. Now the second value is the relative + distance that is skipped, not the absolute value when you start hitting + arrows again. [Wolfman2000] + 2011/05/15 ---------- * Added #SPEEDS to the SSC format. This multiplies your scrolling speed during diff --git a/Docs/SimfileFormats/ssc_msd5.txt b/Docs/SimfileFormats/ssc_msd5.txt index d3b7d092c1..64bad9126e 100644 --- a/Docs/SimfileFormats/ssc_msd5.txt +++ b/Docs/SimfileFormats/ssc_msd5.txt @@ -16,9 +16,10 @@ #INSTRUMENTTRACK:; #MUSICLENGTH:; #OFFSET:; +#BPMS:; #STOPS:; #DELAYS:; -#BPMS:; +#LABELS:; #TIMESIGNATURES:; #LASTBEATHINT:; #SAMPLESTART:; @@ -43,17 +44,24 @@ // information from #NOTES moved here #STEPSTYPE:; #DESCRIPTION:; +#CHARTSTYLE:; #DIFFICULTY:; #METER:; #RADARVALUES:; #CREDIT:; // steps-based timingdata +#BPMS:; #STOPS:; #DELAYS:; -#BPMS:; #TIMESIGNATURES:; -#LASTBEATHINT:; +#TICKCOUNTS:; +#COMBOS:; +#SPEEDS:; +#FAKES:; +#LABELS:; +#ATTACKS:; // Not yet in use. +#OFFSET:; // actual step data -#NOTES:; \ No newline at end of file +#NOTES:; From e902adcb13aae3e373b6eebcd3ce9967b625d59a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 12:12:19 -0400 Subject: [PATCH 170/197] [splittiming] FORCE clean up the cache early. --- src/Song.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Song.cpp b/src/Song.cpp index 8bf3c72fd0..c85c7eb864 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -41,7 +41,7 @@ * @brief The internal version of the cache for StepMania. * * Increment this value to invalidate the current cache. */ -const int FILE_CACHE_VERSION = 172; +const int FILE_CACHE_VERSION = 173; /** @brief How long does a song sample last by default? */ const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f; From 0584c490a2ccd7df7ee7b97830416e82bf0238cc Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 12:19:42 -0400 Subject: [PATCH 171/197] [splittiming] Shrink lines. We need some way to move the ScreenTextEntry text entry down. --- Themes/_fallback/Languages/en.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 9b9fbf2f51..f06698ea5b 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1233,7 +1233,7 @@ Enter a new Tickcount value.=Enter a new Tickcount value.\n\nEnter the previous Enter a new Combo value.=Enter a new Combo value.\n\nEnter the previous value to remove. Enter a new Label value.=Enter a name for this section of the chart.\n\nEnter a previously used label to remove. Enter a new Warp value.=Enter the number of beats you will warp over.\n\nType "0" to remove this segment. -Enter a new Speed percent value.=Enter the ratio for speed scrolling.\n\nEnter the previous value to remove.\n\n1 is the default scroll. +Enter a new Speed percent value.=Enter the ratio for speed scrolling.\nEnter the previous value to remove.\n1 is the default scroll. Enter a new Speed wait value.=Enter how long in seconds/beats it takes to change.\n\n0 is instant. Enter a new Speed mode value.=Enter how this segment is handled.\n\nType "0" for beats, "1" for seconds. Enter a new Fake value.=Enter the number of beats that won't be judged.\n\nType "0" to remove this. From 399fabbf3c6be649bed4782cd815c9cdef18f3d8 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 12:28:18 -0400 Subject: [PATCH 172/197] [splittiming] Write only default #SPEEDS value. --- src/NotesWriterSSC.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index fcc88c39ba..fefce24b10 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -134,13 +134,14 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Write( cs->m_iStartRow, cs->m_iCombo ); w.Finish(); + // Song Timing should only have the initial value. + w.Init( "SPEEDS" ); + FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss ) + w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait, ss->m_usMode ); + w.Finish(); + if( !bIsSong ) - { - w.Init( "SPEEDS" ); - FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss ) - w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait, ss->m_usMode ); - w.Finish(); - + { w.Init( "FAKES" ); FOREACH_CONST( FakeSegment, timing.m_FakeSegments, fs ) w.Write( fs->m_iStartRow, fs->m_fLengthBeats ); From e73824cad971cb13028503384bfe4f2ec161f865 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Mon, 16 May 2011 23:35:40 +0700 Subject: [PATCH 173/197] [splittiming] it works (by swapping arguments) --- src/ScreenEdit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 947bb54ee9..8929e4d2cd 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2716,7 +2716,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) else if( SM == SM_BackFromTimeSignatureChange ) { int iNum, iDen; - if( sscanf( " %d / %d ", ScreenTextEntry::s_sLastAnswer.c_str(), &iNum, &iDen ) == 2 ) + if( sscanf( ScreenTextEntry::s_sLastAnswer.c_str(), " %d / %d ", &iNum, &iDen ) == 2 ) { GetAppropriateTiming().SetTimeSignatureNumeratorAtBeat( GetBeat(), iNum ); GetAppropriateTiming().SetTimeSignatureDenominatorAtBeat( GetBeat(), iDen ); From 5a66df400fbf9bed28299dd0f14b089ff2312b60 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 12:43:44 -0400 Subject: [PATCH 174/197] [splittiming] It's working. Also, lang cleanup. --- Themes/_fallback/Languages/en.ini | 7 ++----- src/ScreenEdit.cpp | 3 +-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index f06698ea5b..818a5bb456 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -847,9 +847,7 @@ Exit Edit Mode=Exit Edit Mode Edit stop=Edit stop Edit delay=Edit delay Edit Timing Data=Edit Timing Data -Edit time signature=Edit time signature (not working yet) -Edit time signature (top)=Edit time signature (beats per measure) -Edit time signature (bottom)=Edit time signature (single beat note value) +Edit time signature=Edit time signature Edit tickcount=Edit tickcount Edit combo=Edit combo Edit label=Edit label @@ -1227,8 +1225,7 @@ Do you want to save changes before exiting?=Do you want to save changes before e Enter a new BPM value.=Enter a new BPM value.\n\nEnter the previous value to remove. Enter a new Stop value.=Enter a new Stop value.\n\nType "0" to remove. Enter a new Delay value.=Enter a new Delay value.\n\nType "0" to remove. -Enter a new Time Signature numerator value.=Enter the number of beats per measure. -Enter a new Time Signature denominator value.=Enter the note value that represents one beat. +Enter a new Time Signature.=Enter a new time signature.\nUse the format "x/y".\nEnter the previous value to remove. Enter a new Tickcount value.=Enter a new Tickcount value.\n\nEnter the previous value to remove. Enter a new Combo value.=Enter a new Combo value.\n\nEnter the previous value to remove. Enter a new Label value.=Enter a name for this section of the chart.\n\nEnter a previously used label to remove. diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 8929e4d2cd..36e1d9febf 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2718,8 +2718,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) int iNum, iDen; if( sscanf( ScreenTextEntry::s_sLastAnswer.c_str(), " %d / %d ", &iNum, &iDen ) == 2 ) { - GetAppropriateTiming().SetTimeSignatureNumeratorAtBeat( GetBeat(), iNum ); - GetAppropriateTiming().SetTimeSignatureDenominatorAtBeat( GetBeat(), iDen ); + GetAppropriateTiming().SetTimeSignatureAtBeat( GetBeat(), iNum, iDen ); } SetDirty( true ); } From c1b72c17218b0bedc7472dfcec9d152f6f2444d9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 12:48:36 -0400 Subject: [PATCH 175/197] [splittiming] Sorry vinil! --- src/ScreenEdit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 36e1d9febf..0552e967bb 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -4027,6 +4027,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ssprintf("%.5f", GetAppropriateTiming().GetFakeAtBeat( GetBeat() ) ), 10 ); + break; } case erase_step_timing: ScreenPrompt::Prompt( SM_DoEraseStepTiming, CONFIRM_TIMING_ERASE , PROMPT_YES_NO, ANSWER_NO ); From 5deed76e37fabc82197e187c933f1572b7a73a79 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 17 May 2011 00:02:15 +0700 Subject: [PATCH 176/197] [splittiming] add a special case for lengthed speed change at beat 0. --- src/ArrowEffects.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 318bd75e01..a12ff397af 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -233,7 +233,11 @@ float GetSpeedMultiplier( float fSongBeat, float fMusicSeconds, const TimingData fEndTime = tim.GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ) - tim.GetDelayAtBeat( fStartBeat + seg.m_fWait ); } - if( fEndTime >= fCurTime && ( index > 0 || tim.m_SpeedSegments[0].m_fWait > 0.0 ) ) + if( ( index == 0 && tim.m_SpeedSegments[0].m_fWait > 0.0 ) && fCurTime < fStartTime ) + { + return 1.0; + } + else if( fEndTime >= fCurTime && ( index > 0 || tim.m_SpeedSegments[0].m_fWait > 0.0 ) ) { const float fPriorSpeed = ( index == 0 ? 1 : tim.m_SpeedSegments[index - 1].m_fPercent ); float fTimeUsed = fCurTime - fStartTime; From f00c59fd2c4b4d8b01a0d3be292117608190f2a3 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 13:05:37 -0400 Subject: [PATCH 177/197] [splittiming] Allow songs to start with 0+ SPEED. Somehow, this just screams gimmickry. --- src/NotesLoaderSMA.cpp | 2 +- src/NotesLoaderSSC.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index ca2ff66c84..6a723201ab 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -321,7 +321,7 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS vector vs2; split( *s1, "=", vs2 ); - if( RowToBeat(vs2[0], iRowsPerBeat) == 0 ) // First one always seems to have 2. + if( RowToBeat(vs2[0], iRowsPerBeat) == 0 && vs2.size() == 2 ) // First one always seems to have 2. { vs2.push_back("0"); } diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 5e7a9bcc68..c4f379c57e 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -140,12 +140,12 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) vector vs2; split( *s1, "=", vs2 ); - if( vs2[0] == 0 ) // First one always seems to have 2. + if( vs2[0] == 0 && vs2.size() == 2 ) // First one always seems to have 2. { vs2.push_back("0"); } - if( vs2.size() == 3 ) + if( vs2.size() == 3 ) // use beats by default. { vs2.push_back("0"); } From d039c5c2fb702cb9e34810dd925e2202aba8f5cb Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 16:17:34 -0400 Subject: [PATCH 178/197] [splittiming] Carryover from old #WARPS code. --- src/TimingData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TimingData.cpp b/src/TimingData.cpp index d2fe29d203..9e7f064cf1 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -296,7 +296,7 @@ void TimingData::SetFakeAtRow( int iRow, float fNew ) for( i=0; i 0 && NoteRowToBeat(iRow) < fNew; + bool valid = iRow > 0 && fNew > 0; if( i == m_FakeSegments.size() ) { if( valid ) From 430de65cefa887c3d6d602d4f33d02ab85a31103 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 16:54:30 -0400 Subject: [PATCH 179/197] [splittiming] Stop repeating lua errors. Get fewer in exchange. Huh... --- NoteSkins/pump/default/UpLeft Receptor.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NoteSkins/pump/default/UpLeft Receptor.lua b/NoteSkins/pump/default/UpLeft Receptor.lua index 3380a0b8ff..f6738e3c27 100644 --- a/NoteSkins/pump/default/UpLeft Receptor.lua +++ b/NoteSkins/pump/default/UpLeft Receptor.lua @@ -6,7 +6,7 @@ local function Beat(self) local part = beat%1 part = clamp(part,0,0.5) local eff = scale(part,0,0.5,1,0) - if (GAMESTATE:GetSongDelay() or false) and part == 0 then eff = 0 end + if (GAMESTATE:GetSongPosition:GetDelay() or false) and part == 0 then eff = 0 end if beat < 0 then eff = 0 end From da7226ed0a3e75f56e5bd3aa07e09279afb48ff4 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 17:24:35 -0400 Subject: [PATCH 180/197] [splittiming] Revert silly mistake. --- src/global.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/global.h b/src/global.h index b90f6c86c7..e8d3c1e493 100644 --- a/src/global.h +++ b/src/global.h @@ -190,6 +190,13 @@ template struct CompileAssertDecl { }; /** @brief Use RStrings throughout the program. */ typedef StdString::CStdString RString; +#if !defined(WIN32) +/** @brief Define stricmp to be strcasecmp. */ +#define stricmp strcasecmp +/** @brief Define strnicmp to be strncasecmp. */ +#define strnicmp strncasecmp +#endif + #include "RageException.h" /* Define a few functions if necessary */ From 5bfc05c13af7e78218fd8935e23dee0308590cb9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 17:32:00 -0400 Subject: [PATCH 181/197] [splittiming] Fix #TICKCOUNTS saving improperly. --- src/NotesLoaderKSF.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index 862c4bd485..3933dbbf81 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -168,7 +168,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, LOG->UserLog( "Song file", sPath, "has an invalid tick count: %d.", iTickCount ); return false; } - out.m_Timing.AddTickcountSegment(TickcountSegment(0, iTickCount)); + stepsTiming.AddTickcountSegment(TickcountSegment(0, iTickCount)); } else if( sValueName=="DIFFICULTY" ) From a7bc1a01fe99a2ba7744d4021dbecf7f90edd33a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 18:37:20 -0400 Subject: [PATCH 182/197] [splittiming] Try using the LAST file, not first. Global timing can get funky if Crazy has lots of changes. Normal, on the other hand, is usally sane. Of course, if there are fewer files, it's a moot point. --- src/NotesLoaderKSF.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index 3933dbbf81..385a5152fa 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -682,14 +682,16 @@ bool KSFLoader::LoadFromDir( const RString &sDir, Song &out ) bool bKIUCompliant = false; /* With Split Timing, there has to be a backup Song Timing in case - * anything goes wrong. Use the first file found to determine said - * timing, while also establishing whether this file respects the - * Kick It Up syntax. */ - if( !LoadGlobalData(out.GetSongDir() + arrayKSFFileNames[0], out, bKIUCompliant) ) + * anything goes wrong. As these files are kept in alphabetical + * order (hopefully), it is best to use the LAST file for timing + * purposes, for that is the "normal", or easiest difficulty. + * Usually. */ + unsigned files = arrayKSFFileNames.size(); + if( !LoadGlobalData(out.GetSongDir() + arrayKSFFileNames[files - 1], out, bKIUCompliant) ) return false; // load the Steps from the rest of the KSF files - for( unsigned i=0; i Date: Mon, 16 May 2011 23:44:06 -0400 Subject: [PATCH 183/197] [splittiming] Force tidying up of the song. This will force tidying up of the timing, thus stopping the SpeedSegment crashes. --- src/NotesLoaderDWI.cpp | 2 +- src/NotesLoaderKSF.cpp | 1 + src/NotesLoaderMidi.cpp | 3 ++- src/NotesLoaderPMS.cpp | 2 +- src/NotesLoaderSM.cpp | 3 ++- src/NotesLoaderSMA.cpp | 3 ++- src/NotesLoaderSSC.cpp | 1 + 7 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/NotesLoaderDWI.cpp b/src/NotesLoaderDWI.cpp index bd4e2314fe..1c50103288 100644 --- a/src/NotesLoaderDWI.cpp +++ b/src/NotesLoaderDWI.cpp @@ -656,7 +656,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set &Bla // do nothing. We don't care about this value name } } - + out.TidyUpData(); return true; } diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index 385a5152fa..276f0c1e49 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -702,6 +702,7 @@ bool KSFLoader::LoadFromDir( const RString &sDir, Song &out ) out.AddSteps( pNewNotes ); } + out.TidyUpData(); return true; } diff --git a/src/NotesLoaderMidi.cpp b/src/NotesLoaderMidi.cpp index ef354d7bfe..9673cdb14d 100644 --- a/src/NotesLoaderMidi.cpp +++ b/src/NotesLoaderMidi.cpp @@ -883,7 +883,7 @@ skip_track: pSteps->SetNoteData( noteData ); songOut.AddSteps( pSteps ); } - + return true; } @@ -956,6 +956,7 @@ bool MidiLoader::LoadFromDir( const RString &sDir, Song &out ) if( !LoadFromMidi(sDir+vsFiles[0], out) ) return false; + out.TidyUpData(); return true; } diff --git a/src/NotesLoaderPMS.cpp b/src/NotesLoaderPMS.cpp index 44578f6504..f9ef5bf1cc 100644 --- a/src/NotesLoaderPMS.cpp +++ b/src/NotesLoaderPMS.cpp @@ -940,7 +940,7 @@ bool PMSLoader::LoadFromDir( const RString &sDir, Song &out ) ConvertString( out.m_sArtist, "utf-8,japanese" ); ConvertString( out.m_sGenre, "utf-8,japanese" ); - + out.TidyUpData(); return true; } diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index cd1fc8d52e..a456a6fab1 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -753,7 +753,7 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache else LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() ); } - + TidyUpData( out, bFromCache ); return true; } @@ -946,6 +946,7 @@ void SMLoader::TidyUpData( Song &song, bool bFromCache ) bg.push_back( BackgroundChange(song.m_fLastBeat,song.m_sBackgroundFile) ); } while(0); } + song.TidyUpData(); } /* diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 6a723201ab..8caba0a62b 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -711,7 +711,8 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) else LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() ); } - + TidyUpData(out, false); + out.TidyUpData(); return true; } diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index c4f379c57e..81969e336e 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -625,6 +625,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach } } out.m_fVersion = STEPFILE_VERSION_NUMBER; + TidyUpData(out, bFromCache); return true; } From b280e775c677a53c91a9b7e9ebb5e7cf29d96572 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 16 May 2011 23:48:50 -0400 Subject: [PATCH 184/197] [splittiming] Fix order of Timing Menus. --- src/ScreenEdit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 5bb5f6fbda..d4ac2af111 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -498,8 +498,8 @@ public: speed_percent, speed_wait, speed_mode, - erase_step_timing, fake, + erase_step_timing, NUM_TIMING_DATA_INFORMATION_CHOICES }; From 1a41c32dd90d3f1a40ecd96003ba5be98a39dcd6 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 00:07:43 -0400 Subject: [PATCH 185/197] [splittiming] Better variable name. ArrowEffects had a minor change, but the intent isn't up yet. It needs to be so that when you go from the editor to the chart for playing in Song Timing, it doesn't use the Step Timing. --- src/ArrowEffects.cpp | 4 ++-- src/GameState.cpp | 2 +- src/GameState.h | 4 ++-- src/NoteField.cpp | 18 +++++++++--------- src/ScreenEdit.cpp | 34 +++++++++++++++++----------------- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index a12ff397af..9f6da4ac97 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -85,7 +85,7 @@ void ArrowEffects::Update() FOREACH_PlayerNumber( pn ) { const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn]; - const SongPosition &position = (!GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsEditorStepTiming) + const SongPosition &position = (GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsUsingStepTiming) ? GAMESTATE->m_pPlayerState[pn]->m_Position : GAMESTATE->m_Position; PerPlayerData &data = g_EffectData[pn]; @@ -264,7 +264,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float bIsPastPeakOut = true; float fYOffset = 0; - const SongPosition &position = (!GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsEditorStepTiming) + const SongPosition &position = (!GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsUsingStepTiming) ? pPlayerState->m_Position : GAMESTATE->m_Position; float fSongBeat = position.m_fSongBeatVisible; diff --git a/src/GameState.cpp b/src/GameState.cpp index 76bd07acd5..dbca4fc9a3 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -128,7 +128,7 @@ GameState::GameState() : m_stEditSource( Message_EditSourceStepsTypeChanged ), m_iEditCourseEntryIndex( Message_EditCourseEntryIndexChanged ), m_sEditLocalProfileID( Message_EditLocalProfileIDChanged ), - m_bIsEditorStepTiming( true ), + m_bIsUsingStepTiming( true ), m_bInStepEditor( false ) { g_pImpl = new GameStateImpl; diff --git a/src/GameState.h b/src/GameState.h index 0a6efc0e25..5e925e05ff 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -333,10 +333,10 @@ public: // Edit stuff /** - * @brief Is the editor making changes to Song timing or Steps timing? + * @brief Is the game right now using Song timing or Steps timing? * * Different options are available depending on this setting. */ - bool m_bIsEditorStepTiming; + bool m_bIsUsingStepTiming; /** * @brief Are we presently in the Step Editor, where some rules apply differently? * diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 24dfddf6e4..cdf67941c8 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -42,7 +42,7 @@ inline const TimingData *GetRealTiming(const PlayerState *pPlayerState) inline const TimingData *GetDisplayedTiming(const PlayerState *pPlayerState) { - if( !GAMESTATE->m_bIsEditorStepTiming ) + if( !GAMESTATE->m_bIsUsingStepTiming ) return &GAMESTATE->m_pCurSong->m_SongTiming; return GetRealTiming(pPlayerState); } @@ -54,7 +54,7 @@ inline const SongPosition *GetRealPosition(const PlayerState *pPlayerState) inline const SongPosition *GetDisplayedPosition(const PlayerState *pPlayerState) { - if( !GAMESTATE->m_bIsEditorStepTiming ) + if( !GAMESTATE->m_bIsUsingStepTiming ) return &GAMESTATE->m_Position; return GetRealPosition(pPlayerState); } @@ -739,7 +739,7 @@ float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceB inline float NoteRowToVisibleBeat( const PlayerState *pPlayerState, int iRow ) { /* - if( GAMESTATE->m_bIsEditorStepTiming ) + if( GAMESTATE->m_bIsUsingStepTiming ) { */ return NoteRowToBeat(iRow); @@ -893,7 +893,7 @@ void NoteField::DrawPrimitives() } // Warp text - if( GAMESTATE->m_bIsEditorStepTiming ) + if( GAMESTATE->m_bIsUsingStepTiming ) { FOREACH_CONST( WarpSegment, timing.m_WarpSegments, seg ) { @@ -917,7 +917,7 @@ void NoteField::DrawPrimitives() } } - if( GAMESTATE->m_bIsEditorStepTiming ) + if( GAMESTATE->m_bIsUsingStepTiming ) { // Tickcount text FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, seg ) @@ -931,7 +931,7 @@ void NoteField::DrawPrimitives() } } - if( GAMESTATE->m_bIsEditorStepTiming ) + if( GAMESTATE->m_bIsUsingStepTiming ) { // Combo text FOREACH_CONST( ComboSegment, timing.m_ComboSegments, seg ) @@ -956,7 +956,7 @@ void NoteField::DrawPrimitives() } } - if( GAMESTATE->m_bIsEditorStepTiming ) + if( GAMESTATE->m_bIsUsingStepTiming ) { FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, seg ) { @@ -970,7 +970,7 @@ void NoteField::DrawPrimitives() } // Speed text - if( GAMESTATE->m_bIsEditorStepTiming ) + if( GAMESTATE->m_bIsUsingStepTiming ) { FOREACH_CONST( FakeSegment, timing.m_FakeSegments, seg ) { @@ -1004,7 +1004,7 @@ void NoteField::DrawPrimitives() } } - if( !GAMESTATE->m_bIsEditorStepTiming ) + if( !GAMESTATE->m_bIsUsingStepTiming ) { // BGChange text switch( GAMESTATE->m_EditMode ) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 0552e967bb..4b0f056f8c 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -705,7 +705,7 @@ void ScreenEdit::Init() { m_pSoundMusic = NULL; - GAMESTATE->m_bIsEditorStepTiming = true; + GAMESTATE->m_bIsUsingStepTiming = true; GAMESTATE->m_bInStepEditor = true; SubscribeToMessage( "Judgment" ); @@ -865,8 +865,8 @@ ScreenEdit::~ScreenEdit() LOG->Trace( "ScreenEdit::~ScreenEdit()" ); m_pSoundMusic->StopPlaying(); - // Reset the GameState variable in case it's needed elsewhere. - GAMESTATE->m_bIsEditorStepTiming = false; + // Go back to Step Timing on leave. + GAMESTATE->m_bIsUsingStepTiming = true; // DEFINITELY reset the InStepEditor variable. GAMESTATE->m_bInStepEditor = false; } @@ -1163,7 +1163,7 @@ void ScreenEdit::UpdateTextInfo() case EditMode_Full: sText += ssprintf( TIMING_MODE_FORMAT.GetValue(), TIMING_MODE.GetValue().c_str(), - ( GAMESTATE->m_bIsEditorStepTiming ? + ( GAMESTATE->m_bIsUsingStepTiming ? STEP_TIMING.GetValue().c_str() : SONG_TIMING.GetValue().c_str() ) ); sText += ssprintf( BEAT_0_OFFSET_FORMAT.GetValue(), @@ -1825,7 +1825,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU: case EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU: - if( !GAMESTATE->m_bIsEditorStepTiming ) + if( !GAMESTATE->m_bIsUsingStepTiming ) { switch( EditB ) { @@ -2148,7 +2148,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) break; case EDIT_BUTTON_SWITCH_TIMINGS: - GAMESTATE->m_bIsEditorStepTiming = !GAMESTATE->m_bIsEditorStepTiming; + GAMESTATE->m_bIsUsingStepTiming = !GAMESTATE->m_bIsUsingStepTiming; m_soundSwitchTiming.Play(); break; } @@ -3147,7 +3147,7 @@ static void ChangeArtistTranslit( const RString &sNew ) static void ChangeBeat0Offset( const RString &sNew ) { - TimingData &timing = GAMESTATE->m_bIsEditorStepTiming ? GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing : GAMESTATE->m_pCurSong->m_SongTiming; + TimingData &timing = GAMESTATE->m_bIsUsingStepTiming ? GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing : GAMESTATE->m_pCurSong->m_SongTiming; timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew ); } @@ -3178,7 +3178,7 @@ static void ChangeMaxBPM( const RString &sNew ) TimingData & ScreenEdit::GetAppropriateTiming() const { - if( GAMESTATE->m_bIsEditorStepTiming ) + if( GAMESTATE->m_bIsUsingStepTiming ) { return m_pSteps->m_Timing; } @@ -3187,7 +3187,7 @@ TimingData & ScreenEdit::GetAppropriateTiming() const inline void ScreenEdit::SetBeat(float fBeat) { - if( !GAMESTATE->m_bIsEditorStepTiming ) + if( !GAMESTATE->m_bIsUsingStepTiming ) { GAMESTATE->m_Position.m_fSongBeat = fBeat; GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat = m_pSteps->m_Timing.GetBeatFromElapsedTime(m_pSong->m_SongTiming.GetElapsedTimeFromBeat(fBeat)); @@ -3201,7 +3201,7 @@ inline void ScreenEdit::SetBeat(float fBeat) inline float ScreenEdit::GetBeat() { - if( !GAMESTATE->m_bIsEditorStepTiming ) + if( !GAMESTATE->m_bIsUsingStepTiming ) { return GAMESTATE->m_Position.m_fSongBeat; } @@ -3229,13 +3229,13 @@ void ScreenEdit::DisplayTimingMenu() g_TimingDataInformation.rows[fake].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetFakeAtBeat( fBeat ) ) ); - g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsEditorStepTiming; - g_TimingDataInformation.rows[combo].bEnabled = GAMESTATE->m_bIsEditorStepTiming; - g_TimingDataInformation.rows[warp].bEnabled = GAMESTATE->m_bIsEditorStepTiming; - g_TimingDataInformation.rows[speed_percent].bEnabled = GAMESTATE->m_bIsEditorStepTiming; - g_TimingDataInformation.rows[speed_wait].bEnabled = GAMESTATE->m_bIsEditorStepTiming; - g_TimingDataInformation.rows[speed_mode].bEnabled = GAMESTATE->m_bIsEditorStepTiming; - g_TimingDataInformation.rows[fake].bEnabled = GAMESTATE->m_bIsEditorStepTiming; + g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsUsingStepTiming; + g_TimingDataInformation.rows[combo].bEnabled = GAMESTATE->m_bIsUsingStepTiming; + g_TimingDataInformation.rows[warp].bEnabled = GAMESTATE->m_bIsUsingStepTiming; + g_TimingDataInformation.rows[speed_percent].bEnabled = GAMESTATE->m_bIsUsingStepTiming; + g_TimingDataInformation.rows[speed_wait].bEnabled = GAMESTATE->m_bIsUsingStepTiming; + g_TimingDataInformation.rows[speed_mode].bEnabled = GAMESTATE->m_bIsUsingStepTiming; + g_TimingDataInformation.rows[fake].bEnabled = GAMESTATE->m_bIsUsingStepTiming; EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation ); } From c26da983e4c7d0e3db34c9f3a0778459dc0a79f0 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 14:16:58 -0400 Subject: [PATCH 186/197] [splittiming] Right idea, wrong place. Song Timing respected when needed, included SpeedSegments. --- src/ArrowEffects.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 9f6da4ac97..e408967789 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -85,7 +85,7 @@ void ArrowEffects::Update() FOREACH_PlayerNumber( pn ) { const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn]; - const SongPosition &position = (GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsUsingStepTiming) + const SongPosition &position = GAMESTATE->m_bIsUsingStepTiming ? GAMESTATE->m_pPlayerState[pn]->m_Position : GAMESTATE->m_Position; PerPlayerData &data = g_EffectData[pn]; @@ -264,7 +264,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float bIsPastPeakOut = true; float fYOffset = 0; - const SongPosition &position = (!GAMESTATE->m_bInStepEditor || GAMESTATE->m_bIsUsingStepTiming) + const SongPosition &position = GAMESTATE->m_bIsUsingStepTiming ? pPlayerState->m_Position : GAMESTATE->m_Position; float fSongBeat = position.m_fSongBeatVisible; @@ -277,7 +277,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float { float fBeatsUntilStep = fNoteBeat - fSongBeat; float fYOffsetBeatSpacing = fBeatsUntilStep; - float fSpeedMultiplier = GAMESTATE->m_bInStepEditor ? 1.0 : GetSpeedMultiplier( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible, pCurSteps->m_Timing ); + float fSpeedMultiplier = ( GAMESTATE->m_bInStepEditor || !GAMESTATE->m_bIsUsingStepTiming ) ? 1.0 : GetSpeedMultiplier( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible, pCurSteps->m_Timing ); fYOffset += fSpeedMultiplier * fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing); } From d72a54b6512562d2b8025449ae6926e5b668017e Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 14:52:07 -0400 Subject: [PATCH 187/197] [splittiming] Clean out .sm cruft. Least we can do is make sure SongTiming settings work with OpenITG. --- src/NotesWriterSM.cpp | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index cada1268d6..8261c174d6 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -134,19 +134,6 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) } } f.PutLine( ";" ); - - f.Write( "#ATTACKS:" ); - for( unsigned j = 0; j < out.m_Attacks.size(); j++ ) - { - const Attack &a = out.m_Attacks[j]; - f.Write( ssprintf( "TIME=%.2f:LEN=%.2f:MODS=%s", - a.fStartSecond, a.fSecsRemaining, a.sModifiers.c_str() ) ); - - if( j+1 < out.m_Attacks.size() ) - f.Write( ":" ); - f.PutLine( "" ); - } - f.PutLine( ";" ); f.Write( "#DELAYS:" ); for( unsigned i=0; im_iStartRow), - iter->m_iNumerator, iter->m_iDenominator ) ); - vector::const_iterator iter2 = iter; - iter2++; - if( iter2 != out.m_SongTiming.m_vTimeSignatureSegments.end() ) - f.Write( "," ); - } - f.PutLine( ";" ); - - ASSERT( !out.m_SongTiming.m_TickcountSegments.empty() ); - f.Write( "#TICKCOUNTS:" ); - for( unsigned i=0; i Date: Tue, 17 May 2011 14:55:50 -0400 Subject: [PATCH 188/197] [splittiming] Delays -> Stops at previous beat. --- src/NotesWriterSM.cpp | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index 8261c174d6..cdd27c8657 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -63,19 +63,6 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) f.PutLine( ssprintf( "#LYRICSPATH:%s;", SmEscape(out.m_sLyricsFile).c_str() ) ); f.PutLine( ssprintf( "#CDTITLE:%s;", SmEscape(out.m_sCDTitleFile).c_str() ) ); f.PutLine( ssprintf( "#MUSIC:%s;", SmEscape(out.m_sMusicFile).c_str() ) ); - - { - vector vs; - FOREACH_ENUM( InstrumentTrack, it ) - if( out.HasInstrumentTrack(it) ) - vs.push_back( InstrumentTrackToString(it) + - "=" + out.m_sInstrumentTrackFile[it] ); - if( !vs.empty() ) - { - RString s = join( ",", vs ); - f.PutLine( "#INSTRUMENTTRACK:" + s + ";\n" ); - } - } f.PutLine( ssprintf( "#OFFSET:%.3f;", out.m_SongTiming.m_fBeat0OffsetInSeconds ) ); f.PutLine( ssprintf( "#SAMPLESTART:%.3f;", out.m_fMusicSampleStartSeconds ) ); f.PutLine( ssprintf( "#SAMPLELENGTH:%.3f;", out.m_fMusicSampleLengthSeconds ) ); @@ -125,30 +112,17 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) for( unsigned i=0; i Date: Tue, 17 May 2011 15:15:59 -0400 Subject: [PATCH 189/197] [splittiming] Use OpenITG settings here. --- src/NotesWriterSM.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index cdd27c8657..af224d0a2b 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -214,8 +214,8 @@ static RString GetSMNotesTag( const Song &song, const Steps &in ) lines.push_back( ssprintf( " %d:", in.GetMeter() ) ); vector asRadarValues; - // SM files don't use fakes for radar data. Keep it that way. - int categories = NUM_RadarCategory - 1; + // OpenITG simfiles use 11 radar categories. + int categories = 11; FOREACH_PlayerNumber( pn ) { const RadarValues &rv = in.GetRadarValues( pn ); From 65ac4b18500f5938dcd6388750280146b4e63199 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 15:24:34 -0400 Subject: [PATCH 190/197] [splittiming] Allow Warps to be editable always. This should be the only stopping point. --- src/NotesWriterSSC.cpp | 11 ++++------- src/ScreenEdit.cpp | 1 - 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index fefce24b10..77578908f8 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -108,13 +108,10 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Write( ss->m_iStartRow, ss->m_fStopSeconds ); w.Finish(); - if( !bIsSong ) - { - w.Init( "WARPS" ); - FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws ) - w.Write( ws->m_iStartRow, ws->m_fLengthBeats ); - w.Finish(); - } + w.Init( "WARPS" ); + FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws ) + w.Write( ws->m_iStartRow, ws->m_fLengthBeats ); + w.Finish(); ASSERT( !timing.m_vTimeSignatureSegments.empty() ); w.Init( "TIMESIGNATURES" ); diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 4b0f056f8c..cc800e43cb 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3231,7 +3231,6 @@ void ScreenEdit::DisplayTimingMenu() g_TimingDataInformation.rows[tickcount].bEnabled = GAMESTATE->m_bIsUsingStepTiming; g_TimingDataInformation.rows[combo].bEnabled = GAMESTATE->m_bIsUsingStepTiming; - g_TimingDataInformation.rows[warp].bEnabled = GAMESTATE->m_bIsUsingStepTiming; g_TimingDataInformation.rows[speed_percent].bEnabled = GAMESTATE->m_bIsUsingStepTiming; g_TimingDataInformation.rows[speed_wait].bEnabled = GAMESTATE->m_bIsUsingStepTiming; g_TimingDataInformation.rows[speed_mode].bEnabled = GAMESTATE->m_bIsUsingStepTiming; From 390776ddc76686b9e7a100d017b5204be540a5f7 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 15:33:05 -0400 Subject: [PATCH 191/197] [splittiming] Relative warps in .SM, remember? --- src/NotesLoaderSM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index a456a6fab1..9237885259 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -290,7 +290,7 @@ void SMLoader::ProcessStops( TimingData &out, const RString sParam ) if( negBeat + fSkipBeats > fFreezeBeat ) fSkipBeats = fFreezeBeat - negBeat; - WarpSegment ws( negBeat, negBeat + fSkipBeats); + WarpSegment ws( negBeat, fSkipBeats); out.AddWarpSegment( ws ); negBeat = -1; From e3e16ee2e038683d1d7b329c62dbf83da9eb8182 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 16:00:05 -0400 Subject: [PATCH 192/197] [splittiming] Warps to Negs to Gone again. We're almost ready to bring this branch to default. --- src/NotesWriterSM.cpp | 27 +++++++++++++++++++++++++-- src/NotesWriterSM.h | 2 +- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index af224d0a2b..55bbeeb65c 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -48,7 +48,7 @@ static RString BackgroundChangeToString( const BackgroundChange &bgc ) * @brief Write out the common tags for .SM files. * @param f the file in question. * @param out the Song in question. */ -static void WriteGlobalTags( RageFile &f, const Song &out ) +static void WriteGlobalTags( RageFile &f, Song &out ) { f.PutLine( ssprintf( "#TITLE:%s;", SmEscape(out.m_sMainTitle).c_str() ) ); f.PutLine( ssprintf( "#SUBTITLE:%s;", SmEscape(out.m_sSubTitle).c_str() ) ); @@ -107,6 +107,22 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) f.Write( "," ); } f.PutLine( ";" ); + + unsigned wSize = out.m_SongTiming.m_WarpSegments.size(); + if( wSize > 0 ) + { + for( unsigned i=0; i < wSize; i++ ) + { + int iRow = out.m_SongTiming.m_WarpSegments[i].m_iStartRow; + float fBPS = 60 / out.m_SongTiming.GetBPMAtRow(iRow); + float fSkip = fBPS * out.m_SongTiming.m_WarpSegments[i].m_fLengthBeats; + StopSegment ss; + ss.m_iStartRow = iRow; + ss.m_fStopSeconds = -fSkip; + ss.m_bDelay = false; // Best to be sure. + out.m_SongTiming.AddStopSegment( ss ); + } + } f.Write( "#STOPS:" ); for( unsigned i=0; i& vpStepsToSave ) +bool NotesWriterSM::Write( RString sPath, Song &out, const vector& vpStepsToSave ) { int flags = RageFile::WRITE; diff --git a/src/NotesWriterSM.h b/src/NotesWriterSM.h index ee0ed26441..580953cdac 100644 --- a/src/NotesWriterSM.h +++ b/src/NotesWriterSM.h @@ -11,7 +11,7 @@ namespace NotesWriterSM * @param sPath the path to write the file. * @param out the Song to be written out. * @return its success or failure. */ - bool Write( RString sPath, const Song &out, const vector& vpStepsToSave ); + bool Write( RString sPath, Song &out, const vector& vpStepsToSave ); /** * @brief Get some contents about the edit file first. * @param pSong the Song in question. From 18256844e9b361dd92044b1644fc662f4be9c4ee Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 16:05:08 -0400 Subject: [PATCH 193/197] [splittiming] May as well doc this. --- Docs/Changelog_sm5.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index e244fe11f2..8a3a998b7e 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -8,6 +8,13 @@ ________________________________________________________________________________ StepMania 5.0 $NEXT | 20110xyy -------------------------------------------------------------------------------- +2011/05/17 +---------- +* [NotesWriterSM] Write out OpenITG compatible SM files from here on out. + This includes turning Warps into Negative Stops. For those that wanted + negative BPMs specifically, my apologies, but stops are easier on math. + [Wolfman2000] + 2011/05/16 ---------- * [ProfileManager] Added ProfileWasLoadedFromMemoryCard(PlayerNumber) From d25b0752699dbfda8c54cf9e907544f5561481cf Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 21:32:15 -0400 Subject: [PATCH 194/197] [splittiming] See if this builds for you FSX! --- src/NotesLoader.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/NotesLoader.cpp b/src/NotesLoader.cpp index 6ed491df63..05112c51e0 100644 --- a/src/NotesLoader.cpp +++ b/src/NotesLoader.cpp @@ -43,11 +43,9 @@ bool NotesLoader::LoadFromDir( const RString &sPath, Song &out, set &Bl SMLoader::GetApplicableFiles( sPath, list ); if (!list.empty() ) return SMLoader::LoadFromDir( sPath, out ); -#if defined(_MSC_VER) || defined(MACOSX) SMALoader::GetApplicableFiles( sPath, list ); if (!list.empty() ) return SMALoader::LoadFromDir( sPath, out ); -#endif DWILoader::GetApplicableFiles( sPath, list ); if( !list.empty() ) return DWILoader::LoadFromDir( sPath, out, BlacklistedImages ); From 8e775daadaab5b96f8324de8affe46b3de8a4049 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 17 May 2011 23:49:18 -0400 Subject: [PATCH 195/197] [splittiming] Stopped Centered Recording. About to transfer to default branch. --- src/ScreenEdit.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index cc800e43cb..d3680ffe05 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -2418,14 +2418,6 @@ void ScreenEdit::TransitionEditState( EditState em ) // Load the player's default PlayerOptions. GAMESTATE->m_pPlayerState[PLAYER_1]->RebuildPlayerOptionsFromActiveAttacks(); - switch( em ) - { - case STATE_RECORDING: - case STATE_RECORDING_PAUSED: - PO_GROUP_ASSIGN_N( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions, ModsLevel_Stage, m_fScrolls, PlayerOptions::SCROLL_CENTERED, 1.0f ); - break; - } - // Snap to current options. GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.SetCurrentToLevel( ModsLevel_Stage ); } From 68d86194a8ede791fec9b2d1fc09dcaac3ce8002 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 18 May 2011 00:50:39 -0400 Subject: [PATCH 196/197] [splittiming] Don't force this file. Each individual user should have their choice. --- .hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgignore b/.hgignore index 7bb444fb3c..4d6915b892 100644 --- a/.hgignore +++ b/.hgignore @@ -64,6 +64,7 @@ lib*_link.a Data/UserPrefs Data/uPrefs Data/GamePrefs/*.cfg +Data/Static.ini PBProject/Hardware.plist Themes/pump Themes/optical-release From 791cd3a28f7e6d9fc9b7b8a774cac01d4301969c Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 18 May 2011 21:22:44 -0400 Subject: [PATCH 197/197] [splittiming] Prepare the cache for merging. --- src/Song.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Song.cpp b/src/Song.cpp index c85c7eb864..cca7a65b38 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -41,7 +41,7 @@ * @brief The internal version of the cache for StepMania. * * Increment this value to invalidate the current cache. */ -const int FILE_CACHE_VERSION = 173; +const int FILE_CACHE_VERSION = 174; /** @brief How long does a song sample last by default? */ const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;