#include "global.h" /* ----------------------------------------------------------------------------- Class: ScreenOptions Desc: See header. Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. Chris Danford Glenn Maynard ----------------------------------------------------------------------------- */ #include "ScreenOptions.h" #include "RageUtil.h" #include "ScreenManager.h" #include "PrefsManager.h" #include "GameConstantsAndTypes.h" #include "RageLog.h" #include "GameState.h" #include "ThemeManager.h" #include "InputMapper.h" #include "ActorUtil.h" #include "ProfileManager.h" const float ITEM_X[NUM_PLAYERS] = { 260, 420 }; #define ICONS_X( p ) THEME->GetMetricF("ScreenOptions",ssprintf("IconsP%dX",p+1)) #define ARROWS_X THEME->GetMetricF("ScreenOptions","ArrowsX") #define LABELS_X THEME->GetMetricF("ScreenOptions","LabelsX") #define LABELS_ZOOM THEME->GetMetricF("ScreenOptions","LabelsZoom") #define LABELS_H_ALIGN THEME->GetMetricI("ScreenOptions","LabelsHAlign") #define ITEMS_ZOOM THEME->GetMetricF("ScreenOptions","ItemsZoom") #define ITEMS_START_X THEME->GetMetricF("ScreenOptions","ItemsStartX") #define ITEMS_GAP_X THEME->GetMetricF("ScreenOptions","ItemsGapX") #define ITEMS_START_Y THEME->GetMetricF("ScreenOptions","ItemsStartY") #define ITEMS_SPACING_Y THEME->GetMetricF("ScreenOptions","ItemsSpacingY") #define EXPLANATION_X(p) THEME->GetMetricF("ScreenOptions",ssprintf("ExplanationP%dX",p+1)) #define EXPLANATION_Y(p) THEME->GetMetricF("ScreenOptions",ssprintf("ExplanationP%dY",p+1)) #define EXPLANATION_ON_COMMAND(p) THEME->GetMetric ("ScreenOptions",ssprintf("ExplanationP%dOnCommand",p+1)) #define EXPLANATION_TOGETHER_X THEME->GetMetricF("ScreenOptions","ExplanationTogetherX") #define EXPLANATION_TOGETHER_Y THEME->GetMetricF("ScreenOptions","ExplanationTogetherY") #define EXPLANATION_TOGETHER_ON_COMMAND THEME->GetMetric ("ScreenOptions","ExplanationTogetherOnCommand") #define SHOW_SCROLL_BAR THEME->GetMetricB("ScreenOptions","ShowScrollBar") /* Extra parens needed to work around stupid VC6 compiler crash: */ #define SCROLL_BAR_HEIGHT (THEME->GetMetricF("ScreenOptions","ScrollBarHeight")) #define SCROLL_BAR_TIME (THEME->GetMetricF("ScreenOptions","ScrollBarTime")) #define ITEMS_SPACING_Y THEME->GetMetricF("ScreenOptions","ItemsSpacingY") #define EXPLANATION_ZOOM THEME->GetMetricF("ScreenOptions","ExplanationZoom") #define COLOR_SELECTED THEME->GetMetricC("ScreenOptions","ColorSelected") #define COLOR_NOT_SELECTED THEME->GetMetricC("ScreenOptions","ColorNotSelected") #define NUM_SHOWN_ITEMS THEME->GetMetricI("ScreenOptions","NumShownItems") ScreenOptions::ScreenOptions( CString sClassName ) : Screen(sClassName) { LOG->Trace( "ScreenOptions::ScreenOptions()" ); m_SoundChangeCol.Load( THEME->GetPathToS("ScreenOptions change"), true ); m_SoundNextRow.Load( THEME->GetPathToS("ScreenOptions next"), true ); m_SoundPrevRow.Load( THEME->GetPathToS("ScreenOptions prev"), true ); m_SoundStart.Load( THEME->GetPathToS("Common start") ); m_Menu.Load( sClassName ); this->AddChild( &m_Menu ); // add everything to m_framePage so we can animate everything at once this->AddChild( &m_framePage ); for( int p=0; pTrace( "ScreenOptions::Set()" ); m_InputMode = im; m_OptionRow = OptionRows; m_iNumOptionRows = iNumOptionLines; this->ImportOptions(); for( int l=0; lGetPathToG(m_sName+" page") ); m_sprPage->SetName( "Page" ); UtilSetXYAndOnCommand( m_sprPage, "ScreenOptions" ); m_framePage.AddChild( m_sprPage ); // init highlights for( p=0; pIsHumanPlayer(p) ) continue; // skip m_sprLineHighlight[p].Load( THEME->GetPathToG("ScreenOptions line highlight") ); m_sprLineHighlight[p].SetName( "LineHighlight" ); m_sprLineHighlight[p].SetX( CENTER_X ); m_framePage.AddChild( &m_sprLineHighlight[p] ); UtilOnCommand( m_sprLineHighlight[p], "ScreenOptions" ); m_Highlight[p].Load( (PlayerNumber)p, false ); m_framePage.AddChild( &m_Highlight[p] ); } // init underlines for( p=0; pIsHumanPlayer(p) ) continue; // skip for( int l=0; l & textItems = m_textItems[r]; const OptionRow &optline = m_OptionRow[r]; unsigned c; m_framePage.AddChild( &m_sprBullets[r] ); m_framePage.AddChild( &m_textTitles[r] ); float fX = ITEMS_START_X; // indent 70 pixels for( c=0; cLoadFromFont( THEME->GetPathToF("ScreenOptions item") ); bt->SetText( optline.choices[c] ); bt->SetZoom( ITEMS_ZOOM ); bt->EnableShadow( false ); // set the X position of each item in the line const float fItemWidth = bt->GetZoomedWidth(); fX += fItemWidth/2; bt->SetX( fX ); fX += fItemWidth/2 + ITEMS_GAP_X; } if( fX > SCREEN_RIGHT-40 ) { // It goes off the edge of the screen. Re-init with the "long row" style. m_bRowIsLong[r] = true; for( unsigned j=0; jIsHumanPlayer(p) ) continue; BitmapText *bt = new BitmapText; textItems.push_back( bt ); const int iChoiceInRow = m_iSelectedOption[p][r]; bt->LoadFromFont( THEME->GetPathToF("ScreenOptions item") ); bt->SetText( optline.choices[iChoiceInRow] ); bt->SetZoom( ITEMS_ZOOM ); bt->EnableShadow( false ); /* if choices are locked together, center the item. */ if( optline.bOneChoiceForAllPlayers ) bt->SetX( (ITEM_X[0]+ITEM_X[1])/2 ); else bt->SetX( ITEM_X[p] ); /* If bOneChoiceForAllPlayers, then only initialize one text item. */ if( optline.bOneChoiceForAllPlayers ) break; } } for( c=0; cLoadFromFont( THEME->GetPathToF("ScreenOptions item") ); bt->SetText( "EXIT" ); bt->SetZoom( ITEMS_ZOOM ); bt->SetShadowLength( 0 ); float fY = ITEMS_START_Y + ITEMS_SPACING_Y*m_iNumOptionRows; bt->SetXY( CENTER_X, fY ); m_framePage.AddChild( bt ); } // add explanation here so it appears on top for( p=0; pGetPathToF("ScreenOptions explanation") ); m_textExplanation[p].SetZoom( EXPLANATION_ZOOM ); m_textExplanation[p].SetShadowLength( 0 ); m_framePage.AddChild( &m_textExplanation[p] ); } /* Hack: if m_CurStyle is set, we're probably in the player or song options menu, so * the player name is meaningful. Otherwise, we're probably in the system menu. */ if( GAMESTATE->m_CurStyle != STYLE_INVALID ) { for( p=0; pGetPathToF( "ScreenOptions player") ); m_textPlayerName[p].SetName( ssprintf("PlayerNameP%i",p+1) ); m_textPlayerName[p].SetText( PROFILEMAN->GetPlayerName((PlayerNumber)p) ); UtilSetXYAndOnCommand( m_textPlayerName[p], "ScreenOptions" ); m_framePage.AddChild( &m_textPlayerName[p] ); } } if( SHOW_SCROLL_BAR ) { m_ScrollBar.SetName( "DualScrollBar", "ScrollBar" ); m_ScrollBar.SetBarHeight( SCROLL_BAR_HEIGHT ); m_ScrollBar.SetBarTime( SCROLL_BAR_TIME ); for( p=0; pIsHumanPlayer(p) ); m_ScrollBar.Load(); UtilSetXY( m_ScrollBar, "ScreenOptions" ); m_framePage.AddChild( &m_ScrollBar ); } switch( m_InputMode ) { case INPUTMODE_INDIVIDUAL: for( p=0; pGetPathToG( "ScreenOptions frame") ); m_sprFrame->SetXY( CENTER_X, CENTER_Y ); m_framePage.AddChild( m_sprFrame ); // poke once at all the explanation metrics so that we catch missing ones early for( r=0; rFinishTweening(); } for( int p=0; pTrace( "ScreenOptions::~ScreenOptions()" ); for( int i=0; iGetMetric( "OptionExplanations", sLineName+"Help" ); } CString ScreenOptions::GetExplanationTitle( int row ) const { CString sLineName = m_OptionRow[row].name; sLineName.Replace("\n-",""); sLineName.Replace("\n",""); sLineName.Replace(" ",""); return THEME->GetMetric( "OptionExplanations", sLineName+"Title" ); } BitmapText &ScreenOptions::GetTextItemForRow( PlayerNumber pn, int iRow ) { const bool bExitRow = iRow == m_iNumOptionRows; if( bExitRow ) return *m_textItems[iRow][0]; const bool bLotsOfOptions = m_bRowIsLong[iRow]; if( !bLotsOfOptions ) { unsigned iOptionInRow = m_iSelectedOption[pn][iRow]; return *m_textItems[iRow][iOptionInRow]; } const bool bOneChoice = m_OptionRow[iRow].bOneChoiceForAllPlayers; if( bOneChoice ) return *m_textItems[iRow][0]; /* We have lots of options and this isn't a OneChoice row, which means * each player has a separate item displayed. */ int iOptionInRow = min( (unsigned)pn, m_textItems[iRow].size()-1 ); return *m_textItems[iRow][iOptionInRow]; } void ScreenOptions::GetWidthXY( PlayerNumber pn, int iRow, int &iWidthOut, int &iXOut, int &iYOut ) { BitmapText &text = GetTextItemForRow( pn, iRow ); iWidthOut = int(roundf( text.GetZoomedWidth() )); iXOut = int(roundf( text.GetDestX() )); /* We update m_fRowY, change colors and tween items, and then tween rows to * their final positions. (This is so we don't tween colors, too.) m_fRowY * is the actual destination position, even though we may not have set up the * tween yet. */ iYOut = int(roundf( m_fRowY[iRow] )); } void ScreenOptions::InitOptionsText() { for( int i=0; iGetPathToF("ScreenOptions title") ); CString sText = GetExplanationTitle( i ); title.SetText( sText ); title.SetXY( LABELS_X, fY ); title.SetZoom( LABELS_ZOOM ); title.SetHorizAlign( (Actor::HorizAlign)LABELS_H_ALIGN ); title.SetVertAlign( Actor::align_middle ); title.EnableShadow( false ); Sprite &bullet = m_sprBullets[i]; bullet.Load( THEME->GetPathToG("ScreenOptions bullet") ); bullet.SetXY( ARROWS_X, fY ); // set the Y position of each item in the line for( unsigned c=0; cSetY( fY ); } } void ScreenOptions::PositionUnderlines() { // Set the position of the underscores showing the current choice for each option line. for( int p=0; pIsHumanPlayer(p) ) continue; // skip for( int i=0; i