diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 5ac9e0edc5..dd2e1f305e 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -2994,6 +2994,8 @@ NumIconParts=0 NumCursorParts=0 NumPreviewParts=0 ShowScroller=0 +WrapScroller=0 +ScrollerFastCatchup=0 # All on page 1 by default. NumChoicesOnPage1=999 SharedPreviewAndCursor=1 @@ -3285,6 +3287,8 @@ NumIconParts=0 NumCursorParts=0 NumPreviewParts=0 ShowScroller=0 +WrapScroller=0 +ScrollerFastCatchup=0 # All on page 1 by default. NumChoicesOnPage1=999 SharedPreviewAndCursor=1 diff --git a/stepmania/src/ActorScroller.cpp b/stepmania/src/ActorScroller.cpp index a322d619cd..aeb164c646 100644 --- a/stepmania/src/ActorScroller.cpp +++ b/stepmania/src/ActorScroller.cpp @@ -127,11 +127,13 @@ void ActorScroller::Load2( void ActorScroller::Load3( float fSecondsPerItem, float fNumItemsToDraw, + bool bFastCatchup, const CString &sExprTransform ) { m_fSecondsPerItem = fSecondsPerItem; m_fNumItemsToDraw = fNumItemsToDraw; + m_bFastCatchup = bFastCatchup; m_exprTransform.SetFromExpression( sExprTransform ); m_fQuantizePixels = 0; m_bLoaded = true; @@ -230,7 +232,17 @@ void ActorScroller::Update( float fDeltaTime ) float fOldItemAtTop = m_fCurrentItem; if( m_fSecondsPerItem > 0 ) - fapproach( m_fCurrentItem, m_fDestinationItem, fDeltaTime/m_fSecondsPerItem ); + { + float fApproachSpeed = fDeltaTime/m_fSecondsPerItem; + if( m_bFastCatchup ) + { + float fDistanceToMove = fabsf(m_fCurrentItem - m_fDestinationItem); + if( fDistanceToMove > 1 ) + fApproachSpeed *= fDistanceToMove*fDistanceToMove; + } + + fapproach( m_fCurrentItem, m_fDestinationItem, fApproachSpeed ); + } // if items changed, then pause if( (int)fOldItemAtTop != (int)m_fCurrentItem ) @@ -294,8 +306,6 @@ void ActorScroller::DrawPrimitives() bool bDelayedDraw = m_bDrawByZPosition && !m_bLoop; vector subs; - if( bDelayedDraw ) - subs = m_SubActors; for( int iItem=(int)truncf(ceilf(fFirstItemToDraw)); iItem<=fLastItemToDraw; iItem++ ) { diff --git a/stepmania/src/ActorScroller.h b/stepmania/src/ActorScroller.h index bed11589c5..255c21da50 100644 --- a/stepmania/src/ActorScroller.h +++ b/stepmania/src/ActorScroller.h @@ -47,6 +47,7 @@ public: void Load3( float fSecondsPerItem, float fNumItemsToDraw, + bool bFastCatchup, const CString &sExprTransform ); virtual void Update( float fDelta ); @@ -56,6 +57,7 @@ public: void SetDestinationItem( float fItemIndex ) { m_fDestinationItem = fItemIndex; } void SetCurrentAndDestinationItem( float fItemIndex ) { m_fCurrentItem = m_fDestinationItem = fItemIndex; } + float GetCurrentItem() { return m_fCurrentItem; } float GetDestinationItem() { return m_fDestinationItem; } void SetPauseCountdownSeconds( float fSecs ) { m_fPauseCountdownSeconds = fSecs; } @@ -76,6 +78,7 @@ protected: float m_fSecondsPauseBetweenItems; float m_fNumItemsToDraw; bool m_bLoop; + bool m_bFastCatchup; float m_fPauseCountdownSeconds; float m_fQuantizePixels; diff --git a/stepmania/src/ScreenSelectMaster.cpp b/stepmania/src/ScreenSelectMaster.cpp index f0f53b0a74..55b0b41922 100644 --- a/stepmania/src/ScreenSelectMaster.cpp +++ b/stepmania/src/ScreenSelectMaster.cpp @@ -38,6 +38,8 @@ ScreenSelectMaster::ScreenSelectMaster( CString sClassName ) : ScreenSelect( sCl SLEEP_AFTER_TWEEN_OFF_SECONDS(m_sName,"SleepAfterTweenOffSeconds"), OPTION_ORDER(m_sName,OPTION_ORDER_NAME,NUM_MENU_DIRS), WRAP_CURSOR(m_sName,"WrapCursor"), + WRAP_SCROLLER(m_sName,"WrapScroller"), + SCROLLER_FAST_CATCHUP(m_sName,"ScrollerFastCatchup"), ALLOW_REPEATING_INPUT(m_sName,"AllowRepeatingInput"), SHOW_SCROLLER(m_sName,"ShowScroller"), SCROLLER_SECONDS_PER_ITEM(m_sName,"ScrollerSecondsPerItem"), @@ -101,6 +103,7 @@ void ScreenSelectMaster::Init() m_Scroller[0].Load3( SCROLLER_SECONDS_PER_ITEM, SCROLLER_NUM_ITEMS_TO_DRAW, + SCROLLER_FAST_CATCHUP, SCROLLER_TRANSFORM ); m_Scroller[0].SetName( "Scroller" ); @@ -122,6 +125,7 @@ void ScreenSelectMaster::Init() m_Scroller[p].Load3( SCROLLER_SECONDS_PER_ITEM, SCROLLER_NUM_ITEMS_TO_DRAW, + SCROLLER_FAST_CATCHUP, SCROLLER_TRANSFORM ); m_Scroller[p].SetName( ssprintf("ScrollerP%d",p+1) ); @@ -384,7 +388,7 @@ bool ScreenSelectMaster::Move( PlayerNumber pn, MenuDir dir ) } while( !m_aGameCommands[iSwitchToIndex].IsPlayable() ); - return ChangeSelection( pn, iSwitchToIndex ); + return ChangeSelection( pn, dir, iSwitchToIndex ); } void ScreenSelectMaster::MenuLeft( PlayerNumber pn, const InputEventType type ) @@ -518,7 +522,7 @@ bool ScreenSelectMaster::ChangePage( int iNewChoice ) return true; } -bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, int iNewChoice ) +bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, MenuDir dir, int iNewChoice ) { if( iNewChoice == m_iChoice[pn] ) return false; // already there @@ -583,6 +587,23 @@ bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, int iNewChoice ) if( SHOW_SCROLLER ) { + if( WRAP_SCROLLER ) + { + // HACK: We can't tell from the option orders whether or not we wrapped. + // For now, assume that the order is increasing left to right. + int iPressedDir = (dir == MENU_DIR_LEFT) ? -1 : +1; + int iActualDir = (iOldChoice < iNewChoice) ? +1 : -1; + + if( iPressedDir != iActualDir ) // wrapped + { + ActorScroller &scroller = SHARED_PREVIEW_AND_CURSOR ? m_Scroller[0] : m_Scroller[p]; + float fItem = scroller.GetCurrentItem(); + int iNumChoices = m_aGameCommands.size(); + fItem += iActualDir * iNumChoices; + scroller.SetCurrentAndDestinationItem( fItem ); + } + } + if( SHARED_PREVIEW_AND_CURSOR ) m_Scroller[0].SetDestinationItem( (float)iNewChoice ); else diff --git a/stepmania/src/ScreenSelectMaster.h b/stepmania/src/ScreenSelectMaster.h index d8f2743d25..7cb7c8bf98 100644 --- a/stepmania/src/ScreenSelectMaster.h +++ b/stepmania/src/ScreenSelectMaster.h @@ -52,6 +52,8 @@ protected: ThemeMetric SLEEP_AFTER_TWEEN_OFF_SECONDS; ThemeMetric1D OPTION_ORDER; ThemeMetric WRAP_CURSOR; + ThemeMetric WRAP_SCROLLER; + ThemeMetric SCROLLER_FAST_CATCHUP; ThemeMetric ALLOW_REPEATING_INPUT; ThemeMetric SHOW_SCROLLER; ThemeMetric SCROLLER_SECONDS_PER_ITEM; @@ -67,7 +69,7 @@ protected: bool Move( PlayerNumber pn, MenuDir dir ); bool ChangePage( int iNewChoice ); - bool ChangeSelection( PlayerNumber pn, int iNewChoice ); + bool ChangeSelection( PlayerNumber pn, MenuDir dir, int iNewChoice ); float DoMenuStart( PlayerNumber pn ); float GetCursorX( PlayerNumber pn, int iPartIndex );