diff --git a/stepmania/src/WheelBase.cpp b/stepmania/src/WheelBase.cpp index 894b2f7938..94e227c11c 100644 --- a/stepmania/src/WheelBase.cpp +++ b/stepmania/src/WheelBase.cpp @@ -18,20 +18,13 @@ const int MAX_WHEEL_SOUND_SPEED = 15; - -WheelBase::WheelBase() -{ -} +AutoScreenMessage( SM_SongChanged ) // TODO: Replace this with a Message and MESSAGEMAN WheelBase::~WheelBase() { FOREACH( WheelItemBase*, m_WheelBaseItems, i ) SAFE_DELETE( *i ); m_WheelBaseItems.clear(); - FOREACH( WheelItemBaseData*, m_WheelBaseItemsData, i ) - SAFE_DELETE( *i ); - m_WheelBaseItems.clear(); - m_WheelBaseItemsData.clear(); m_LastSelection = NULL; } @@ -39,21 +32,30 @@ void WheelBase::Load( RString sType ) { LOG->Trace( "WheelBase::Load('%s')", sType.c_str() ); + m_bEmpty = true; + m_LastSelection = NULL; + m_iSelection = 0; + m_fTimeLeftInState = 0; + m_fPositionOffsetFromSelection = 0; + m_iSwitchesLeftInSpinDown = 0; + m_Moving = 0; + LoadFromMetrics( sType ); - LoadVariables(); FOREACH( WheelItemBase*, m_WheelBaseItems, i ) SAFE_DELETE( *i ); m_WheelBaseItems.clear(); + WheelItemBase *pTempl = MakeItem(); for( int i=0; iCopy() ); // XXX: ugly cast } + SAFE_DELETE( pTempl ); +} +void WheelBase::BeginScreen() +{ m_WheelState = STATE_SELECTING; - - BuildWheelItemsData(m_WheelBaseItemsData); - RebuildWheelItems(); } void WheelBase::LoadFromMetrics( RString sType ) @@ -86,17 +88,6 @@ void WheelBase::LoadFromMetrics( RString sType ) this->AddChild( &m_ScrollBar ); } -void WheelBase::LoadVariables() -{ - m_isEmpty = true; - m_LastSelection = NULL; - m_iSelection = 0; - m_fTimeLeftInState = 0; - m_fPositionOffsetFromSelection = 0; - m_iSwitchesLeftInSpinDown = 0; - m_Moving = 0; -} - void WheelBase::GetItemPosition( float fPosOffsetsFromMiddle, float& fX_out, float& fY_out, float& fZ_out, float& fRotationX_out ) { if( USE_3D ) @@ -156,21 +147,19 @@ void WheelBase::DrawPrimitives() void WheelBase::DrawItem( int i ) { - DrawItem( i, m_WheelBaseItems[i], i - NUM_WHEEL_ITEMS/2 + m_fPositionOffsetFromSelection ); -} - -void WheelBase::DrawItem( int i, WheelItemBase *display, const float fThisBannerPositionOffsetFromSelection) -{ + const float fThisBannerPositionOffsetFromSelection = i - NUM_WHEEL_ITEMS/2 + m_fPositionOffsetFromSelection; if( fabsf(fThisBannerPositionOffsetFromSelection) > NUM_WHEEL_ITEMS_TO_DRAW/2 ) return; + WheelItemBase *display = m_WheelBaseItems[i]; switch( m_WheelState ) { case STATE_SELECTING: case STATE_LOCKED: - { - SetItemPosition( *display, fThisBannerPositionOffsetFromSelection ); - } + case STATE_ROULETTE_SPINNING: + case STATE_ROULETTE_SLOWING_DOWN: + case STATE_RANDOM_SPINNING: + SetItemPosition( *display, fThisBannerPositionOffsetFromSelection ); break; } @@ -182,9 +171,9 @@ void WheelBase::DrawItem( int i, WheelItemBase *display, const float fThisBanner display->Draw(); } -void WheelBase::UpdateScrollbar( unsigned int iSize ) +void WheelBase::UpdateScrollbar() { - int iTotalNumItems = iSize; + int iTotalNumItems = m_CurWheelItemData.size(); float fItemAt = m_iSelection - m_fPositionOffsetFromSelection; if( NUM_WHEEL_ITEMS >= iTotalNumItems ) @@ -356,26 +345,26 @@ void WheelBase::UpdateSwitch() } } -bool WheelBase::Select() // return true if this selection ends the screen +bool WheelBase::Select() // return true if this selection can end the screen { LOG->Trace( "WheelBase::Select()" ); m_Moving = 0; - if( !m_isEmpty ) + if( !m_bEmpty ) { - switch( m_WheelBaseItemsData[m_iSelection]->m_Type ) + switch( m_CurWheelItemData[m_iSelection]->m_Type ) { case TYPE_GENERIC: - m_LastSelection = m_WheelBaseItemsData[m_iSelection]; + m_LastSelection = m_CurWheelItemData[m_iSelection]; return false; case TYPE_SECTION: { - RString sThisItemSectionName = m_WheelBaseItemsData[m_iSelection]->m_sText; + RString sThisItemSectionName = m_CurWheelItemData[m_iSelection]->m_sText; if( m_sExpandedSectionName == sThisItemSectionName ) // already expanded - m_sExpandedSectionName = ""; // collapse it - else // already collapsed - m_sExpandedSectionName = sThisItemSectionName; // expand it + SetOpenGroup( "" ); // collapse it + else // already collapsed + SetOpenGroup( sThisItemSectionName ); // expand it m_soundExpand.Play(); } @@ -391,8 +380,8 @@ bool WheelBase::Select() // return true if this selection ends the screen // return true if this selection ends the screen WheelItemBaseData* WheelBase::GetItem( unsigned int iIndex ) { - if( !m_isEmpty && iIndex < m_WheelBaseItemsData.size() ) - return m_WheelBaseItemsData[iIndex]; + if( !m_bEmpty && iIndex < m_CurWheelItemData.size() ) + return m_CurWheelItemData[iIndex]; return NULL; } @@ -453,7 +442,24 @@ void WheelBase::TweenOnScreenUpdateItems( bool bChangingSort ) display->HurryTweening( 0.25f ); } } - + +void WheelBase::TweenOffScreenUpdateItems( bool bChangingSort ) +{ + for( int i=0; iBeginTweening( delay ); // sleep + COMMAND( display, "FinishOff"); + if( bChangingSort ) + display->HurryTweening( 0.25f ); + } +} + void WheelBase::TweenOffScreen( bool bChangingSort ) { m_WheelState = STATE_TWEENING_OFF_SCREEN; @@ -486,23 +492,6 @@ void WheelBase::TweenOffScreen( bool bChangingSort ) m_fTimeLeftInState = GetTweenTimeLeft() + 0.100f; } -void WheelBase::TweenOffScreenUpdateItems( bool bChangingSort ) -{ - for( int i=0; iBeginTweening( delay ); // sleep - COMMAND( display, "FinishOff"); - if( bChangingSort ) - display->HurryTweening( 0.25f ); - } -} - void WheelBase::ChangeMusicUnlessLocked( int n ) { if( m_WheelState == STATE_LOCKED ) @@ -566,7 +555,7 @@ bool WheelBase::MoveSpecific( int n ) return false; // don't continue } - if(m_Moving != 0 && n == 0 && m_TimeBeforeMovingBegins == 0) + if( m_Moving != 0 && n == 0 && m_TimeBeforeMovingBegins == 0 ) { /* We were moving, and now we're stopping. If we're really close to * the selection, move to the next one, so we have a chance to spin down @@ -576,36 +565,16 @@ bool WheelBase::MoveSpecific( int n ) /* Make sure the user always gets an SM_SongChanged when * Moving() is 0, so the final banner, etc. always gets set. */ -// SCREENMAN->PostMessageToTopScreen( SM_SongChanged, 0 ); + SCREENMAN->PostMessageToTopScreen( SM_SongChanged, 0 ); } return true; } -void WheelBase::AddItem( WheelItemBaseData* pItemData ) -{ - m_WheelBaseItemsData.push_back( pItemData ); - int iVisible = FirstVisibleIndex(); - int iIndex = m_WheelBaseItemsData.size(); - - if( m_isEmpty ) - { - m_isEmpty = false; - // Remove the - Empty - field when we add an object from an empty state. - RemoveItem(0); - } - - // If the item was shown in the wheel, rebuild the wheel - if( 0 <= iIndex - iVisible && iIndex - iVisible < NUM_WHEEL_ITEMS ) - { - RebuildWheelItems(); - } -} - void WheelBase::ChangeMusic( int iDist ) { m_iSelection += iDist; - wrap( m_iSelection, m_WheelBaseItemsData.size() ); + wrap( m_iSelection, m_CurWheelItemData.size() ); RebuildWheelItems( iDist ); @@ -618,17 +587,9 @@ void WheelBase::ChangeMusic( int iDist ) m_soundChangeMusic.Play(); } -void WheelBase::BuildWheelItemsData( vector &arrayWheelItemDatas ) -{ - if( arrayWheelItemDatas.empty() ) - { - arrayWheelItemDatas.push_back( new WheelItemBaseData(TYPE_GENERIC, "- EMPTY -", RageColor(1,0,0,1)) ); - } -} - void WheelBase::RebuildWheelItems( int iDist ) { - const vector &data = m_WheelBaseItemsData; + const vector &data = m_CurWheelItemData; vector &items = m_WheelBaseItems; // rewind to first index that will be displayed; @@ -644,96 +605,51 @@ void WheelBase::RebuildWheelItems( int iDist ) // iIndex is now the index of the lowest WheelItem to draw - if( iDist == INT_MAX ) - { - // Refresh all - for( int i=0; iLoadFromWheelItemBaseData( pData ); - } - } - else + if( iDist != INT_MAX ) { // Shift items and refresh only those that have changed. CircularShift( items, iDist ); if( iDist > 0 ) - { - for( int i=NUM_WHEEL_ITEMS-iDist; iLoadFromWheelItemBaseData( pData ); - } - } + iFirst = NUM_WHEEL_ITEMS-iDist; else if( iDist < 0 ) - { - for( int i=0; i < -iDist; i++ ) - { - int iIndex = iFirstVisibleIndex + i; - wrap( iIndex, data.size() ); + iLast = -iDist-1; + } - WheelItemBaseData *pData = data[iIndex]; - WheelItemBase *pDisplay = items[i]; + for( int i=iFirst; i <= iLast; i++ ) + { + int iIndex = iFirstVisibleIndex + i; + wrap( iIndex, data.size() ); - pDisplay->LoadFromWheelItemBaseData( pData ); - } - } + const WheelItemBaseData *pData = data[iIndex]; + WheelItemBase *pDisplay = items[i]; + + pDisplay->SetExpanded( pData->m_Type == TYPE_SECTION && pData->m_sText == m_sExpandedSectionName ); + pDisplay->LoadFromWheelItemData( pData ); } } WheelItemBaseData* WheelBase::LastSelected( ) { - if (m_isEmpty) + if( m_bEmpty ) return NULL; else return m_LastSelection; } -void WheelBase::RemoveItem( int index ) -{ - if( m_isEmpty || index >= (int)m_WheelBaseItemsData.size() ) - return; - - vector::iterator i = m_WheelBaseItemsData.begin(); - i += index; - - // If this item's data happened to be last selected, make it NULL. - if( m_LastSelection == *i ) - m_LastSelection = NULL; - - SAFE_DELETE( *i ); - m_WheelBaseItemsData.erase(i); - - if( m_WheelBaseItemsData.size() < 1 ) - { - m_isEmpty = true; - BuildWheelItemsData(m_WheelBaseItemsData); - } - - RebuildWheelItems(); -} - int WheelBase::FirstVisibleIndex() { // rewind to first index that will be displayed; int iFirstVisibleIndex = m_iSelection; - if( m_iSelection > int(m_WheelBaseItemsData.size()-1) ) + if( m_iSelection > int(m_CurWheelItemData.size()-1) ) m_iSelection = 0; // find the first wheel item shown iFirstVisibleIndex -= NUM_WHEEL_ITEMS/2; - wrap( iFirstVisibleIndex, m_WheelBaseItemsData.size() ); + wrap( iFirstVisibleIndex, m_CurWheelItemData.size() ); return iFirstVisibleIndex; } diff --git a/stepmania/src/WheelBase.h b/stepmania/src/WheelBase.h index 405560f0dd..ac67f81e0a 100644 --- a/stepmania/src/WheelBase.h +++ b/stepmania/src/WheelBase.h @@ -18,14 +18,13 @@ class WheelBase : public ActorFrame { public: - WheelBase(); virtual ~WheelBase(); virtual void Load( RString sType ); + void BeginScreen(); virtual void Update( float fDeltaTime ); virtual void DrawPrimitives(); - virtual void DrawItem( int i ); - virtual void DrawItem( int i, WheelItemBase *display, const float fThisBannerPositionOffsetFromSelection); + void DrawItem( int i ); void TweenOnScreen(bool changing_sort); void TweenOffScreen(bool changing_sort); @@ -35,10 +34,11 @@ public: virtual void Move(int n); void ChangeMusicUnlessLocked( int n ); /* +1 or -1 */ virtual void ChangeMusic(int dist); /* +1 or -1 */ + virtual void SetOpenGroup( RString group ) { } /* Return true if we're moving fast automatically. */ int IsMoving() const; - virtual bool IsSettled() const; + bool IsSettled() const; void GetItemPosition( float fPosOffsetsFromMiddle, float& fX_out, float& fY_out, float& fZ_out, float& fRotationX_out ); void SetItemPosition( Actor &item, float fPosOffsetsFromMiddle ); @@ -46,35 +46,32 @@ public: virtual bool Select(); // return true if this selection ends the screen bool WheelIsLocked() { return (m_WheelState == STATE_LOCKED ? true : false); } - virtual void RebuildWheelItems( int dist = INT_MAX ); // INT_MAX = refresh all + void RebuildWheelItems( int dist = INT_MAX ); // INT_MAX = refresh all - void AddItem( WheelItemBaseData* itemdata ); - virtual void RemoveItem( int index ); - virtual inline unsigned int GetNumItems() const { return m_WheelBaseItemsData.size(); } - inline bool IsEmpty() { return m_isEmpty; } + virtual unsigned int GetNumItems() const { return m_CurWheelItemData.size(); } + bool IsEmpty() { return m_bEmpty; } WheelItemBaseData* GetItem(unsigned int index); WheelItemBaseData* LastSelected(); protected: - void LoadFromMetrics( RString sType ); - void LoadVariables(); + virtual WheelItemBase *MakeItem() = 0; + virtual void LoadFromMetrics( RString sType ); virtual void UpdateSwitch(); - virtual void UpdateItems(float fDeltaTime); - virtual void TweenOnScreenUpdateItems(bool changing_sort); - virtual void TweenOffScreenUpdateItems(bool changing_sort); + void UpdateItems(float fDeltaTime); + void TweenOnScreenUpdateItems(bool changing_sort); + void TweenOffScreenUpdateItems(bool changing_sort); virtual bool MoveSpecific(int n); - virtual void BuildWheelItemsData( vector &arrayWheelItemDatas ); int FirstVisibleIndex(); ScrollBar m_ScrollBar; AutoActor m_sprHighlight; - vector m_WheelBaseItemsData; + vector m_CurWheelItemData; vector m_WheelBaseItems; WheelItemBaseData* m_LastSelection; - bool m_isEmpty; + bool m_bEmpty; int m_iSelection; // index into m_CurWheelItemBaseData RString m_sExpandedSectionName; @@ -107,8 +104,7 @@ protected: RageSound m_soundLocked; // bool WheelItemIsVisible(int n); - virtual void UpdateScrollbar() { UpdateScrollbar(m_WheelBaseItemsData.size()); } - void UpdateScrollbar(unsigned int size); + void UpdateScrollbar(); ThemeMetric SWITCH_SECONDS; ThemeMetric LOCKED_INITIAL_VELOCITY;