#include "global.h" /* ----------------------------------------------------------------------------- Class: ScreenSelectMaster Desc: See header. Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. Chris Danford ----------------------------------------------------------------------------- */ #include "ScreenSelectMaster.h" #include "ScreenManager.h" #include "PrefsManager.h" #include "GameManager.h" #include "ThemeManager.h" #include "RageSounds.h" #include "GameState.h" #include "AnnouncerManager.h" #include "ModeChoice.h" #include "ActorUtil.h" #define NUM_ICON_PARTS THEME->GetMetricI("ScreenSelectMaster","NumIconParts") #define NUM_PREVIEW_PARTS THEME->GetMetricI("ScreenSelectMaster","NumPreviewParts") #define NUM_CURSOR_PARTS THEME->GetMetricI("ScreenSelectMaster","NumCursorParts") #define SHARED_PREVIEW_AND_CURSOR THEME->GetMetricB("ScreenSelectMaster","SharedPreviewAndCursor") #define NUM_CHOICES_ON_PAGE_1 THEME->GetMetricI("ScreenSelectMaster","NumChoicesOnPage1") #define CURSOR_OFFSET_X_FROM_ICON( p, part ) THEME->GetMetricF("ScreenSelectMaster",ssprintf("CursorPart%dP%dOffsetXFromIcon",part+1,p+1)) #define CURSOR_OFFSET_Y_FROM_ICON( p, part ) THEME->GetMetricF("ScreenSelectMaster",ssprintf("CursorPart%dP%dOffsetYFromIcon",part+1,p+1)) #define DISABLED_COLOR THEME->GetMetricC("ScreenSelectMaster","DisabledColor") #define PRE_SWITCH_PAGE_SECONDS THEME->GetMetricF("ScreenSelectMaster","PreSwitchPageSeconds") #define POST_SWITCH_PAGE_SECONDS THEME->GetMetricF("ScreenSelectMaster","PostSwitchPageSeconds") const ScreenMessage SM_PlayPostSwitchPage = (ScreenMessage)(SM_User+1); ScreenSelectMaster::ScreenSelectMaster() : ScreenSelect( "ScreenSelectMaster" ) { int p, i; for( p=0; pGetPathToG(sFName) ); this->AddChild( &m_sprCursor[i][0] ); } } else { for( i=0; iIsPlayerEnabled(p) ) continue; // skip CString sFName = ssprintf("%s Cursor Part%d P%d", m_sName.c_str(),i+1,p+1); m_sprCursor[i][p].SetName( ssprintf("CursorPart%dP%d",i+1,p+1) ); m_sprCursor[i][p].Load( THEME->GetPathToG(sFName) ); this->AddChild( &m_sprCursor[i][p] ); } } } for( unsigned c=0; cGetPathToG(sFName) ); this->AddChild( &m_sprIcon[i][c] ); } if( SHARED_PREVIEW_AND_CURSOR ) { for( i=0; iGetPathToG(sFName) ); this->AddChild( &m_sprPreview[i][c][0] ); } } else { for( i=0; iIsPlayerEnabled(p) ) continue; // skip CString sFName = ssprintf("%s Preview Part%d Choice%d P%d", m_sName.c_str(),i+1,c+1,p+1); m_sprPreview[i][c][p].SetName( ssprintf("PreviewPart%dP%d",i+1,p+1) ); m_sprPreview[i][c][p].Load( THEME->GetPathToG(sFName) ); this->AddChild( &m_sprPreview[i][c][p] ); } } } } for( int page=0; pageGetPathToG( ssprintf("ScreenSelectMaster more page%d",page+1) ) ); this->AddChild( &m_sprMore[page] ); m_sprExplanation[page].SetName( ssprintf("ExplanationPage%d",page+1) ); m_sprExplanation[page].Load( THEME->GetPathToG( ssprintf("ScreenSelectMaster explanation page%d",page+1) ) ); this->AddChild( &m_sprExplanation[page] ); } for( p=0; pGetPathToS( "ScreenSelectMaster change") ); m_soundSelect.Load( THEME->GetPathToS( "Common start") ); m_soundDifficult.Load( ANNOUNCER->GetPathTo("select difficulty challenge") ); m_fLockInputSecs = TweenOnScreen(); } void ScreenSelectMaster::Update( float fDelta ) { ScreenSelect::Update( fDelta ); m_fLockInputSecs = max( 0, m_fLockInputSecs-fDelta ); } void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM ) { ScreenSelect::HandleScreenMessage( SM ); switch( SM ) { case SM_PlayPostSwitchPage: { float fSecs = 0; if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; iIsPlayerEnabled(p) ) { m_sprCursor[i][p].SetXY( GetCursorX((PlayerNumber)p,i), GetCursorY((PlayerNumber)p,i) ); fSecs = max( fSecs, COMMAND( m_sprCursor[i][p], "PostSwitchPage" ) ); } } if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; iIsPlayerEnabled(p) ) fSecs = max( fSecs, COMMAND( m_sprPreview[i][m_iChoice[p]][p], "PostSwitchPage" ) ); } m_fLockInputSecs = POST_SWITCH_PAGE_SECONDS; } break; case SM_BeginFadingOut: float fSecs = TweenOffScreen(); SCREENMAN->PostMessageToTopScreen( SM_AllDoneChoosing, fSecs ); // nofify parent that we're finished m_Menu.m_MenuTimer.Stop(); break; } } int ScreenSelectMaster::GetSelectionIndex( PlayerNumber pn ) { return m_iChoice[pn]; } void ScreenSelectMaster::UpdateSelectableChoices() { /* XXX: If a player joins during the tween-in, this diffuse change * will be undone by the tween. Hmm. */ for( unsigned c=0; cIsPlayable(m_aModeChoices[c]) ) for( int i=0; iIsHumanPlayer(p) ) { MenuRight( (PlayerNumber)p ); MenuLeft( (PlayerNumber)p ); } } } void ScreenSelectMaster::MenuLeft( PlayerNumber pn ) { if( m_fLockInputSecs > 0 ) return; if( m_bChosen[pn] ) return; if( m_iChoice[pn] == 0 ) // can't go left any more return; if( GetPage(m_iChoice[pn]) != GetPage(m_iChoice[pn]-1) ) ChangePage( GetPage(m_iChoice[pn]-1) ); else ChangeSelection( pn, m_iChoice[pn]-1 ); } void ScreenSelectMaster::MenuRight( PlayerNumber pn ) { if( m_fLockInputSecs > 0 ) return; if( m_bChosen[pn] ) return; if( m_iChoice[pn] == (int)m_aModeChoices.size()-1 ) // can't go right any more return; if( GetPage(m_iChoice[pn]) != GetPage(m_iChoice[pn]+1) ) ChangePage( GetPage(m_iChoice[pn]+1) ); else ChangeSelection( pn, m_iChoice[pn]+1 ); } void ScreenSelectMaster::ChangePage( Page newPage ) { // If anyone has already chosen, don't allow changing of pages int p; for( p=0; pIsHumanPlayer(p) && m_bChosen[p] ) return; float fSecs = 0; if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; iIsHumanPlayer(p) ) fSecs = max( fSecs, COMMAND( m_sprCursor[i][p], "PreSwitchPage" ) ); } const CString sIconAndExplanationCommand = ssprintf( "SwitchToPage%d", newPage+1 ); for( unsigned c=0; cIsPlayerEnabled(p) ) fSecs = max( fSecs, COMMAND( m_sprPreview[i][m_iChoice[p]][p], "PreSwitchPage" ) ); } for( int page=0; pagePostScreenMessage( SM_PlayPostSwitchPage, PRE_SWITCH_PAGE_SECONDS ); } void ScreenSelectMaster::ChangeSelection( PlayerNumber pn, int iNewChoice ) { for( int p=0; pIsHumanPlayer(p) ) continue; // skip if( p!=pn && GetCurrentPage()==PAGE_1 ) continue; // skip const int iOldChoice = m_iChoice[p]; if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; im_MasterPlayerNumber] ); } void ScreenSelectMaster::MenuStart( PlayerNumber pn ) { if( m_fLockInputSecs > 0 ) return; if( m_bChosen[pn] == true ) return; m_bChosen[pn] = true; for( int page=0; pagePlayOnceFromDir( ANNOUNCER->GetPathTo(ssprintf("ScreenSelectMaster comment %s",mc.name)) ); m_soundSelect.Play(); } if( GetCurrentPage() == PAGE_2 ) { // choose this for all the other players too for( p=0; pIsHumanPlayer(p) && !m_bChosen[p] ) MenuStart( (PlayerNumber)p ); } float fSecs = 0; for( int i=0; iIsHumanPlayer((PlayerNumber)p) ) bAllDone &= m_bChosen[p]; if( bAllDone ) this->PostScreenMessage( SM_BeginFadingOut, fSecs );// tell our owner it's time to move on } float ScreenSelectMaster::TweenOnScreen() { float fSecs = 0; for( unsigned c=0; cIsPlayerEnabled(p) ) for( int i=0; iIsPlayerEnabled(p) ) for( int i=0; iIsPlayerEnabled(p) ) { m_sprCursor[i][p].SetXY( GetCursorX((PlayerNumber)p,i), GetCursorY((PlayerNumber)p,i) ); fSecs = max( fSecs, ON_COMMAND( m_sprCursor[i][p] ) ); } } fSecs = max( fSecs, SET_XY_AND_ON_COMMAND( m_sprExplanation[GetCurrentPage()] ) ); fSecs = max( fSecs, SET_XY_AND_ON_COMMAND( m_sprMore[GetCurrentPage()] ) ); this->SortByZ(); return fSecs; } float ScreenSelectMaster::TweenOffScreen() { float fSecs = 0; if( SHARED_PREVIEW_AND_CURSOR ) { for( int i=0; iIsPlayerEnabled(p) ) fSecs = max( fSecs, OFF_COMMAND( m_sprCursor[i][p] ) ); } for( unsigned c=0; cIsPlayerEnabled(p) ) fSecs = max( fSecs, OFF_COMMAND( m_sprPreview[i][c][p] ) ); } } fSecs = max( fSecs, OFF_COMMAND( m_sprExplanation[GetCurrentPage()] ) ); fSecs = max( fSecs, OFF_COMMAND( m_sprMore[GetCurrentPage()] ) ); return fSecs; } float ScreenSelectMaster::GetCursorX( PlayerNumber pn, int iPartIndex ) { return m_sprIcon[0][m_iChoice[pn]].GetX() + CURSOR_OFFSET_X_FROM_ICON(pn, iPartIndex); } float ScreenSelectMaster::GetCursorY( PlayerNumber pn, int iPartIndex ) { return m_sprIcon[0][m_iChoice[pn]].GetY() + CURSOR_OFFSET_Y_FROM_ICON(pn, iPartIndex); }