diff --git a/stepmania/src/ArrowEffects.cpp b/stepmania/src/ArrowEffects.cpp index e506a20c1d..09f19d8d02 100644 --- a/stepmania/src/ArrowEffects.cpp +++ b/stepmania/src/ArrowEffects.cpp @@ -28,7 +28,7 @@ float g_fExpandSeconds = 0; float ArrowGetYOffset( PlayerNumber pn, float fNoteBeat ) { float fYOffset; - if( GAMESTATE->m_PlayerOptions->m_bTimeSpacing ) + if( !GAMESTATE->m_PlayerOptions->m_bTimeSpacing ) { float fSongBeat = GAMESTATE->m_fSongBeat; float fBeatsUntilStep = fNoteBeat - fSongBeat; diff --git a/stepmania/src/ArrowEffects.h b/stepmania/src/ArrowEffects.h index 1a8fc84353..595cbf0059 100644 --- a/stepmania/src/ArrowEffects.h +++ b/stepmania/src/ArrowEffects.h @@ -17,7 +17,7 @@ #include "StyleDef.h" const int ARROW_SIZE = 64; -const float ARROW_GAP = ARROW_SIZE;// + 2; +const float ARROW_SPACING = ARROW_SIZE;// + 2; // fYOffset is a vertical position in pixels relative to the center. diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index d826c2c991..57c2e43a24 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -114,6 +114,33 @@ void GameState::Update( float fDelta ) if( m_bActiveAttackEndedThisUpdate[p] ) RebuildPlayerOptionsFromActiveAttacks( (PlayerNumber)p ); + +/* if( m_PlayerOptions[p].m_bUseScrollBPM && m_pCurSong ) + { + float fTargetBPM = m_PlayerOptions[p].m_fScrollBPM; + float fConstBPS = fTargetBPM/60.f; + + // Optimization opportunity: take fewer samples where the weight is less + + const int iNumBPSSamples = 100; + const float fSampleStep = 0.08f; // sample over the next 8 beats + float fSumBPS = 0; + int iSumWeight = 0; + for( int i=0; iGetBPMAtBeat( m_fSongBeat+fBeatsAheadToSample )/60.f; + // Don't allow super low bps values, or else the scroll speed goes crazy at a stop + CLAMP( fBPS, 60.f/60.f, 10000 ); + fSumBPS += fBPS * iWeight; + iSumWeight += iWeight; + } + float fAvgBPS = fSumBPS / iSumWeight; + + m_PlayerOptions[p].m_fScrollSpeed = fConstBPS / fAvgBPS; + } +*/ } } diff --git a/stepmania/src/PlayerOptions.cpp b/stepmania/src/PlayerOptions.cpp index f1c48a0e05..8deeb62c71 100644 --- a/stepmania/src/PlayerOptions.cpp +++ b/stepmania/src/PlayerOptions.cpp @@ -17,7 +17,9 @@ void PlayerOptions::Init() { +// m_bUseScrollBPM = false; m_fScrollSpeed = 1.0f; +// m_fScrollBPM = 200; ZERO( m_fAccels ); ZERO( m_fEffects ); ZERO( m_fAppearances ); @@ -28,55 +30,52 @@ void PlayerOptions::Init() m_bHoldNotes = true; m_bTimingAssist = false; m_fPerspectiveTilt = 0; + m_bTimeSpacing = false; m_sPositioning = ""; } -void FLOAT_APPROACH( float& val, float other_val, float deltaPercent ) -{ - if( val == other_val ) - return; - float fDelta = other_val - val; - float fSign = fDelta / fabsf( fDelta ); - float fToMove = fSign*deltaPercent; - if( fabsf(fToMove) > fabsf(fDelta) ) - fToMove = fDelta; // snap - val += fToMove; -} - void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds ) { int i; - FLOAT_APPROACH( m_fScrollSpeed, other.m_fScrollSpeed, fDeltaSeconds*max(m_fScrollSpeed,other.m_fScrollSpeed) ); // make big jumps in scroll speed move faster + fapproach( m_fScrollSpeed, other.m_fScrollSpeed, fDeltaSeconds*(0.2f+fabsf(m_fScrollSpeed-other.m_fScrollSpeed)) ); // make big jumps in scroll speed move faster for( i=0; i 1.00 */ - CString s = ssprintf( "%2.2f", m_fScrollSpeed ); - if( s[s.GetLength()-1] == '0' ) { - /* -> 1.0 */ - s.erase(s.GetLength()-1); // delete last char +// if( !m_bUseScrollBPM ) +// { + if( m_fScrollSpeed != 1 ) + { + /* -> 1.00 */ + CString s = ssprintf( "%2.2f", m_fScrollSpeed ); if( s[s.GetLength()-1] == '0' ) { - /* -> 1 */ - s.erase(s.GetLength()-2); // delete last 2 chars + /* -> 1.0 */ + s.erase(s.GetLength()-1); // delete last char + if( s[s.GetLength()-1] == '0' ) { + /* -> 1 */ + s.erase(s.GetLength()-2); // delete last 2 chars + } } + sReturn += s + "X, "; } - sReturn += s + "X, "; - } +// } +// else +// { +// CString s = ssprintf( "%.0f", m_fScrollBPM ); +// sReturn += s + "V, "; +// } if( m_fAccels[ACCEL_BOOST]==1 ) sReturn += "Boost, "; if( m_fAccels[ACCEL_BRAKE]==1 ) sReturn += "Brake, "; @@ -99,6 +98,8 @@ CString PlayerOptions::GetString() if( m_fDark == 1) sReturn += "Dark, "; + if( m_bTimeSpacing ) sReturn += "TimeSpacing, "; + switch( m_Turn ) { case TURN_NONE: break; @@ -150,15 +151,18 @@ void PlayerOptions::FromString( CString sOptions ) TrimLeft(sBit); TrimRight(sBit); - if( sBit == "0.25x" ) m_fScrollSpeed = 0.25f; - else if( sBit == "0.5x" ) m_fScrollSpeed = 0.5f; - else if( sBit == "0.75x" ) m_fScrollSpeed = 0.75f; - else if( sBit == "1.5x" ) m_fScrollSpeed = 1.5f; - else if( sBit == "2.0x" ) m_fScrollSpeed = 2.0f; - else if( sBit == "3.0x" ) m_fScrollSpeed = 3.0f; - else if( sBit == "4.0x" ) m_fScrollSpeed = 4.0f; - else if( sBit == "5.0x" ) m_fScrollSpeed = 5.0f; - else if( sBit == "8.0x" ) m_fScrollSpeed = 8.0f; + if( sBit == "0.25x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 0.25f; } + else if( sBit == "0.5x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 0.50f; } + else if( sBit == "1.5x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 1.00f; } + else if( sBit == "2.0x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 2.00f; } + else if( sBit == "3.0x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 3.00f; } + else if( sBit == "4.0x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 4.00f; } + else if( sBit == "5.0x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 5.00f; } + else if( sBit == "8.0x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 8.00f; } + else if( sBit == "12.0x" ) { /*m_bUseScrollBPM=false;*/ m_fScrollSpeed = 12.00f; } +// else if( sBit == "200v" ) { m_bUseScrollBPM=true; m_fScrollBPM = 200; } +// else if( sBit == "300v" ) { m_bUseScrollBPM=true; m_fScrollBPM = 300; } +// else if( sBit == "450v" ) { m_bUseScrollBPM=true; m_fScrollBPM = 450; } else if( sBit == "boost" ) m_fAccels[ACCEL_BOOST] = 1; else if( sBit == "brake" ) m_fAccels[ACCEL_BRAKE] = 1; else if( sBit == "wave" ) m_fAccels[ACCEL_WAVE] = 1; diff --git a/stepmania/src/PlayerOptions.h b/stepmania/src/PlayerOptions.h index c93954b0b3..eced1e8dbb 100644 --- a/stepmania/src/PlayerOptions.h +++ b/stepmania/src/PlayerOptions.h @@ -63,7 +63,9 @@ struct PlayerOptions NUM_TRANSFORMS }; +// bool m_bUseScrollBPM; float m_fScrollSpeed; +// float m_fScrollBPM; float m_fAccels[NUM_ACCELS]; float m_fEffects[NUM_EFFECTS]; float m_fAppearances[NUM_APPEARANCES]; @@ -74,6 +76,7 @@ struct PlayerOptions bool m_bHoldNotes; bool m_bTimingAssist; float m_fPerspectiveTilt; // -1 = near, 0 = overhead, +1 = space + bool m_bTimeSpacing; // instead of Beat spacing /* The current positioning mode, or empty to use the normal positions. */ CString m_sPositioning; diff --git a/stepmania/src/RageUtil.cpp b/stepmania/src/RageUtil.cpp index 940cc463a7..96eb77a749 100644 --- a/stepmania/src/RageUtil.cpp +++ b/stepmania/src/RageUtil.cpp @@ -29,6 +29,19 @@ unsigned long randseed = time(NULL); +void fapproach( float& val, float other_val, float to_move ) +{ + ASSERT( to_move >= 0 ); + if( val == other_val ) + return; + float fDelta = other_val - val; + float fSign = fDelta / fabsf( fDelta ); + float fToMove = fSign*to_move; + if( fabsf(fToMove) > fabsf(fDelta) ) + fToMove = fDelta; // snap + val += fToMove; +} + /* Return a positive x mod y. */ float fmodfp(float x, float y) { diff --git a/stepmania/src/RageUtil.h b/stepmania/src/RageUtil.h index 88a517d66a..49bcd6bd85 100644 --- a/stepmania/src/RageUtil.h +++ b/stepmania/src/RageUtil.h @@ -117,6 +117,9 @@ inline float froundf( const float f, const float fRoundInterval ) return int( (f + fRoundInterval/2)/fRoundInterval ) * fRoundInterval; } +// Move val toward other_val by to_move. +void fapproach( float& val, float other_val, float to_move ); + /* Return a positive x mod y. */ float fmodfp(float x, float y); diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index d7fdfc27f0..2e68a41215 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -1513,7 +1513,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) if( PREFSMAN->m_iCoinMode==COIN_EVENT ) HandleScreenMessage( SM_GoToScreenAfterBack ); else if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() ) - SCREENMAN->SetNewScreen( "ScreenEvaluationSummary" ); + SCREENMAN->SetNewScreen( "ScreenEvaluationStage" ); else SCREENMAN->SetNewScreen( "ScreenGameOver" ); break; diff --git a/stepmania/src/ScreenPlayerOptions.cpp b/stepmania/src/ScreenPlayerOptions.cpp index 706dae6a4d..fc0a4a04ea 100644 --- a/stepmania/src/ScreenPlayerOptions.cpp +++ b/stepmania/src/ScreenPlayerOptions.cpp @@ -19,7 +19,8 @@ #include "AnnouncerManager.h" #include "NoteSkinManager.h" -#define SONGSEL_SCREEN THEME->GetMetric("ScreenGameplay","SongSelectScreen") +#define PREV_SCREEN( play_mode ) THEME->GetMetric ("ScreenPlayerOptions","PrevScreen"+Capitalize(PlayModeToString(play_mode))) +#define NEXT_SCREEN( play_mode ) THEME->GetMetric ("ScreenPlayerOptions","NextScreen"+Capitalize(PlayModeToString(play_mode))) enum { PO_SPEED = 0, @@ -31,12 +32,12 @@ enum { PO_SCROLL, PO_NOTE_SKIN, PO_HOLD_NOTES, - PO_DARK, + PO_OTHER, PO_PERSPECTIVE, NUM_PLAYER_OPTIONS_LINES }; OptionRow g_PlayerOptionsLines[NUM_PLAYER_OPTIONS_LINES] = { - OptionRow( "Speed", "x0.25","x0.5","x0.75","x1","x1.5","x2","x3","x4","x5","x8", "x12" ), + OptionRow( "Speed", "x0.25","x0.5","x0.75","x1","x1.5","x2","x3","x4","x5","x8","x12" ), OptionRow( "Acceler\n-ation", "OFF","BOOST","BRAKE","WAVE","EXPAND","BOOMERANG" ), OptionRow( "Effect", "OFF","DRUNK","DIZZY","MINI","FLIP","TORNADO" ), OptionRow( "Appear\n-ance", "VISIBLE","HIDDEN","SUDDEN","STEALTH","BLINK" ), @@ -45,7 +46,7 @@ OptionRow g_PlayerOptionsLines[NUM_PLAYER_OPTIONS_LINES] = { OptionRow( "Scroll", "STANDARD","REVERSE" ), OptionRow( "Note\nSkin", "" ), OptionRow( "Holds", "OFF","ON" ), - OptionRow( "Dark", "OFF","ON" ), + OptionRow( "Other", "DARK","TIME SPACING" ), OptionRow( "Perspec\n-tive", "INCOMING","OVERHEAD","SPACE" ), }; @@ -86,17 +87,20 @@ void ScreenPlayerOptions::ImportOptions() { PlayerOptions &po = GAMESTATE->m_PlayerOptions[p]; - if( po.m_fScrollSpeed == 0.25f ) m_iSelectedOption[p][PO_SPEED] = 0; - else if( po.m_fScrollSpeed == 0.5f ) m_iSelectedOption[p][PO_SPEED] = 1; - else if( po.m_fScrollSpeed == 0.75f) m_iSelectedOption[p][PO_SPEED] = 2; - else if( po.m_fScrollSpeed == 1.0f ) m_iSelectedOption[p][PO_SPEED] = 3; - else if( po.m_fScrollSpeed == 1.5f ) m_iSelectedOption[p][PO_SPEED] = 4; - else if( po.m_fScrollSpeed == 2.0f ) m_iSelectedOption[p][PO_SPEED] = 5; - else if( po.m_fScrollSpeed == 3.0f ) m_iSelectedOption[p][PO_SPEED] = 6; - else if( po.m_fScrollSpeed == 4.0f ) m_iSelectedOption[p][PO_SPEED] = 7; - else if( po.m_fScrollSpeed == 5.0f ) m_iSelectedOption[p][PO_SPEED] = 8; - else if( po.m_fScrollSpeed == 8.0f ) m_iSelectedOption[p][PO_SPEED] = 9; - else if( po.m_fScrollSpeed == 12.0f) m_iSelectedOption[p][PO_SPEED] = 10; + if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 0.25f ) m_iSelectedOption[p][PO_SPEED] = 0; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 0.5f ) m_iSelectedOption[p][PO_SPEED] = 1; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 0.75f ) m_iSelectedOption[p][PO_SPEED] = 2; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 1.0f ) m_iSelectedOption[p][PO_SPEED] = 3; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 1.5f ) m_iSelectedOption[p][PO_SPEED] = 4; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 2.0f ) m_iSelectedOption[p][PO_SPEED] = 5; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 3.0f ) m_iSelectedOption[p][PO_SPEED] = 6; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 5.0f ) m_iSelectedOption[p][PO_SPEED] = 7; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 4.0f ) m_iSelectedOption[p][PO_SPEED] = 8; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 8.0f ) m_iSelectedOption[p][PO_SPEED] = 9; + else if( /*!po.m_bUseScrollBPM &&*/ po.m_fScrollSpeed == 12.0f ) m_iSelectedOption[p][PO_SPEED] = 10; +// else if( po.m_bUseScrollBPM && po.m_fScrollBPM == 200 ) m_iSelectedOption[p][PO_SPEED] = 8; +// else if( po.m_bUseScrollBPM && po.m_fScrollBPM == 300 ) m_iSelectedOption[p][PO_SPEED] = 9; +// else if( po.m_bUseScrollBPM && po.m_fScrollBPM == 450 ) m_iSelectedOption[p][PO_SPEED] = 10; else m_iSelectedOption[p][PO_SPEED] = 3; m_iSelectedOption[p][PO_ACCEL] = po.GetFirstAccel()+1; @@ -122,7 +126,14 @@ void ScreenPlayerOptions::ImportOptions() m_iSelectedOption[p][PO_HOLD_NOTES] = po.m_bHoldNotes ? 1 : 0; - m_iSelectedOption[p][PO_DARK] = po.m_fDark==1 ? 1 : 0; + + if( po.m_fDark==1 ) + m_iSelectedOption[p][PO_OTHER] = 1; + else if( po.m_bTimeSpacing ) + m_iSelectedOption[p][PO_OTHER] = 2; + else + m_iSelectedOption[p][PO_OTHER] = 0; + m_iSelectedOption[p][PO_PERSPECTIVE]= (int)po.m_fPerspectiveTilt + 1; @@ -139,17 +150,21 @@ void ScreenPlayerOptions::ExportOptions() switch( m_iSelectedOption[p][PO_SPEED] ) { - case 0: po.m_fScrollSpeed = 0.25f; break; - case 1: po.m_fScrollSpeed = 0.5f; break; - case 2: po.m_fScrollSpeed = 0.75f; break; - case 3: po.m_fScrollSpeed = 1.0f; break; - case 4: po.m_fScrollSpeed = 1.5f; break; - case 5: po.m_fScrollSpeed = 2.0f; break; - case 6: po.m_fScrollSpeed = 3.0f; break; - case 7: po.m_fScrollSpeed = 4.0f; break; - case 8: po.m_fScrollSpeed = 5.0f; break; - case 9: po.m_fScrollSpeed = 8.0f; break; - case 10: po.m_fScrollSpeed = 12.0f; break; + case 0: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 0.25f; break; + case 1: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 0.5f; break; + case 2: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 0.75f; break; + case 3: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 1.0f; break; + case 4: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 1.5f; break; + case 5: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 2.0f; break; + case 6: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 3.0f; break; + case 7: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 4.0f; break; + case 8: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 5.0f; break; + case 9: /*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 8.0f; break; + case 10:/*po.m_bUseScrollBPM = false;*/ po.m_fScrollSpeed = 12.0f; break; +// case 9: po.m_bUseScrollBPM = true; po.m_fScrollBPM = 200; break; +// case 10: po.m_bUseScrollBPM = true; po.m_fScrollBPM = 300; break; +// case 11:po.m_bUseScrollBPM = true; po.m_fScrollBPM = 450; break; + default: ASSERT(0); } if( m_iSelectedOption[p][PO_ACCEL] != 0 ) @@ -170,7 +185,8 @@ void ScreenPlayerOptions::ExportOptions() po.m_bHoldNotes = (m_iSelectedOption[p][PO_HOLD_NOTES] == 1); - po.m_fDark = (m_iSelectedOption[p][PO_DARK] == 1) ? 1.f : 0.f; + po.m_fDark = (m_iSelectedOption[p][PO_OTHER] == 1) ? 1.f : 0.f; + po.m_bTimeSpacing = (m_iSelectedOption[p][PO_OTHER] == 2); po.m_fPerspectiveTilt = (float)m_iSelectedOption[p][PO_PERSPECTIVE] - 1; } } @@ -179,12 +195,8 @@ void ScreenPlayerOptions::GoToPrevState() { if( GAMESTATE->m_bEditing ) SCREENMAN->PopTopScreen(); - else if( GAMESTATE->m_PlayMode == PLAY_MODE_NONSTOP || - GAMESTATE->m_PlayMode == PLAY_MODE_ONI || - GAMESTATE->m_PlayMode == PLAY_MODE_ENDLESS) - SCREENMAN->SetNewScreen( "ScreenSelectCourse" ); else - SCREENMAN->SetNewScreen( SONGSEL_SCREEN ); + SCREENMAN->SetNewScreen( PREV_SCREEN(GAMESTATE->m_PlayMode) ); } void ScreenPlayerOptions::GoToNextState() diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index dc3875dd4e..8e86611b6e 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -1292,3 +1292,27 @@ void Song::RemoveNotes( Notes* pNotes ) AddAutoGenNotes(); } + +float Song::GetDominantBPM() +{ + // Get the average BPM. + // TODO: Make this return the most-used BPM in the song. + // This is tricky though because many songs with BPM changes + // have tweaked BPMs (e.g. 160BPM at first, then 160.05BPM later). + float fSumBPM = 0; + float fSumWeights = 0; + for( unsigned i=0; i 0 ); + fSumBPM += fBPM * fLength; + fSumWeights += fLength; + } + return fSumBPM / fSumWeights; +} \ No newline at end of file diff --git a/stepmania/src/song.h b/stepmania/src/song.h index a5b7443e44..10df5fc629 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -193,6 +193,7 @@ public: break; return m_BPMSegments[i].m_fBPM; }; + float GetDominantBPM(); BPMSegment& GetBPMSegmentAtBeat( float fBeat ) { unsigned i;