diff --git a/stepmania/Themes/default/BGAnimations/_shared background fade in.lua b/stepmania/Themes/default/BGAnimations/_shared background fade in.lua index c1ac737d88..69105e9f80 100644 --- a/stepmania/Themes/default/BGAnimations/_shared background fade in.lua +++ b/stepmania/Themes/default/BGAnimations/_shared background fade in.lua @@ -1,6 +1,6 @@ local children = { - LoadActor( "_shared background normal" ); - LoadActor( "_fade in normal" ) .. { + LoadActor( THEME:GetPathB("","_shared background normal") ); + LoadActor( THEME:GetPathB("","_fade in normal") ) .. { OnCommand=cmd(playcommand,"StartTransitioning"); }; }; diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 68bd18a129..e3a99631a5 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -513,6 +513,7 @@ ModeMenuAvailable=ModeMenuAvailable() ScreenBeginCommand=setupmusicstagemods PreviousSongButton="MenuLeft" NextSongButton="MenuRight" +UseOptionsList=false [ScreenSelectCourse] Class="ScreenSelectMusic" diff --git a/stepmania/src/OptionsList.cpp b/stepmania/src/OptionsList.cpp new file mode 100644 index 0000000000..f1185ec0b5 --- /dev/null +++ b/stepmania/src/OptionsList.cpp @@ -0,0 +1,493 @@ +#include "global.h" +#include "OptionsList.h" +#include "GameState.h" +#include "RageLog.h" +#include "Course.h" +#include "SongUtil.h" +#include "StepsUtil.h" +#include "Style.h" +#include "InputEventPlus.h" +#include "CodeDetector.h" +#include "InputMapper.h" + +#define LINE(sLineName) THEME->GetMetric (m_sName,ssprintf("Line%s",sLineName.c_str())) +#define MAX_ITEMS_BEFORE_SPLIT THEME->GetMetricI(m_sName,"MaxItemsBeforeSplit") +#define ITEMS_SPLIT_WIDTH THEME->GetMetricF(m_sName,"ItemsSplitWidth") + +void OptionListRow::Load( const RString &sType ) +{ + ITEMS_SPACING_Y .Load(sType,"ItemsSpacingY"); + + m_Text.resize( 1 ); + m_Text[0].SetName( "Text" ); + m_Text[0].LoadFromFont( THEME->GetPathF(sType, "normal") ); + ActorUtil::LoadAllCommands( m_Text[0], sType ); + + m_Underlines.resize( 1 ); + m_Underlines[0].Load( THEME->GetPathG(sType, "underline") ); + m_Underlines[0]->SetName( "Underline" ); + ActorUtil::LoadAllCommands( *m_Underlines[0], sType ); + + m_Text[0].PlayCommand( "On" ); + m_Underlines[0]->PlayCommand( "On" ); +} + +// GetTitleForHandler +// can always use the title +// can have special speed row titles, note skin, or any SELECT_ONE + +void OptionListRow::SetFromHandler( const OptionRowHandler *pHandler ) +{ + this->RemoveAllChildren(); + + if( pHandler == NULL ) + return; + + int iNum = max( pHandler->m_Def.m_vsChoices.size(), m_Text.size() )+1; + m_Text.resize( iNum, m_Text[0] ); + m_Underlines.resize( iNum, m_Underlines[0] ); + + for( unsigned i = 0; i < pHandler->m_Def.m_vsChoices.size(); ++i ) + { + // init underlines + this->AddChild( m_Underlines[i] ); + + // init text + RString sText = pHandler->GetThemedItemText( i ); + m_Text[i].SetText( sText ); + this->AddChild( &m_Text[i] ); + } + + const unsigned iCnt = pHandler->m_Def.m_vsChoices.size(); + m_bItemsInTwoRows = (int) iCnt > MAX_ITEMS_BEFORE_SPLIT; + const float fWidth = ITEMS_SPLIT_WIDTH; + float fY = 0; + for( unsigned i = 0; i < iCnt; ++i ) + { + float fX = 0; + if( m_bItemsInTwoRows ) + { + if( (i % 2) == 0 ) + fX = -fWidth/2; + else + fX = +fWidth/2; + } + + // set the Y position of each item in the line + m_Text[i].SetXY( fX, fY ); + m_Underlines[i]->SetXY( fX, fY ); + + if( m_bItemsInTwoRows ) + m_Underlines[i]->PlayCommand( "SetTwoRows" ); + else + m_Underlines[i]->PlayCommand( "SetOneRow" ); + + if( !m_bItemsInTwoRows || (i % 2) == 1 || i+1 == iCnt ) + fY += ITEMS_SPACING_Y; + } + + int iExit = pHandler->m_Def.m_vsChoices.size(); + m_Text[iExit].SetText( "Exit" ); // XXX localize + m_Text[iExit].SetXY( 0, fY ); + this->AddChild( &m_Text[iExit] ); +} + +void OptionListRow::SetUnderlines( const vector &aSelections ) +{ + for( unsigned i = 0; i < aSelections.size(); ++i ) + { + Actor *pActor = m_Underlines[i]; + pActor->PlayCommand( aSelections[i]?"Show":"Hide" ); + } +} + +void OptionListRow::PositionCursor( Actor *pCursor, int iSelection ) +{ + float fX = m_Text[iSelection].GetDestX(); + float fY = m_Text[iSelection].GetDestY(); + if( m_bItemsInTwoRows ) + pCursor->PlayCommand( "PositionTwoRows" ); + else + pCursor->PlayCommand( "PositionOneRow" ); + pCursor->SetXY( fX, fY ); +} + +OptionsList::OptionsList() +{ + m_iCurrentRow = 0; +} + +OptionsList::~OptionsList() +{ + FOREACHM( RString, OptionRowHandler *, m_Rows, hand ) + delete hand->second; +} + +void OptionsList::Load( RString sType ) +{ + m_Cursor.Load( THEME->GetPathG(sType, "cursor") ); + m_Cursor->SetName( "Cursor" ); + ActorUtil::LoadAllCommands( *m_Cursor, sType ); + this->AddChild( m_Cursor ); + + set setToLoad; + setToLoad.insert( "Main" ); + + while( !setToLoad.empty() ) + { + RString sLineName = *setToLoad.begin(); + setToLoad.erase( setToLoad.begin() ); + + if( m_Rows.find(sLineName) != m_Rows.end() ) + continue; + + RString sRowCommands = LINE(sLineName); + Commands cmds; + ParseCommands( sRowCommands, cmds ); + + OptionRowHandler *pHand = OptionRowHandlerUtil::Make( cmds ); + if( pHand == NULL ) + RageException::Throw( "Invalid OptionRowHandler '%s' in %s::Line%s", cmds.GetOriginalCommandString().c_str(), m_sName.c_str(), sLineName.c_str() ); + + m_Rows[sLineName] = pHand; + m_asLoadedRows.push_back( sLineName ); + + for( size_t i = 0; i < pHand->m_Def.m_vsChoices.size(); ++i ) + { + RString sScreen = pHand->GetScreen(i); + if( !sScreen.empty() ) + setToLoad.insert( sScreen ); + } + } + + for( int i = 0; i < 2; ++i ) + { + m_Row[i].SetName( "OptionsList" ); + m_Row[i].Load( "OptionsList" ); + ActorUtil::LoadAllCommands( m_Row[i], sType ); + this->AddChild( &m_Row[i] ); + } + + this->PlayCommand( "TweenOff" ); + this->FinishTweening(); + + /* Import options. */ + FOREACHM( RString, OptionRowHandler *, m_Rows, hand ) + { + RString sLineName = hand->first; + ImportRow( sLineName ); + } +} + +void OptionsList::Open() +{ + this->PlayCommand( "Reset" ); + + /* Push the initial menu. */ + ASSERT( m_asMenuStack.size() == 0 ); + Push( "Main" ); + + this->FinishTweening(); + m_Row[!m_iCurrentRow].SetFromHandler( NULL ); + this->PlayCommand( "TweenOn" ); +} + +void OptionsList::Close() +{ + m_asMenuStack.clear(); + this->PlayCommand( "TweenOff" ); +} + +const OptionRowHandler *OptionsList::GetCurrentHandler() +{ + ASSERT( !m_asMenuStack.empty() ); // called while the menu was closed + const RString &sCurrentRow = m_asMenuStack.back(); + return m_Rows[sCurrentRow]; +} + + +void OptionsList::PositionCursor() +{ + m_Row[m_iCurrentRow].PositionCursor( m_Cursor, m_iMenuStackSelection ); +} + +bool OptionsList::RowIsMenusOnly( RString sRow ) const +{ + map::const_iterator it = m_Rows.find( sRow ); + ASSERT( it != m_Rows.end() ); + const OptionRowHandler *pHandler = it->second; + + for( size_t i = 0; i < pHandler->m_Def.m_vsChoices.size(); ++i ) + { + if( pHandler->GetScreen(i).empty() ) + return false; + } + + return true; +} + +/* Toggle to the next menu. This is used to switch quickly through option submenus, + * to choose many options or to find the one you're looking for. For that goal, + * it's not helpful to switch only through the options listed in the current parent + * menu; always toggle through the whole set. Skip menus that only contain other + * menus. */ +void OptionsList::SwitchMenu( int iDir ) +{ + int iCurrentRow = 0; + for( size_t i = 0; i < m_asLoadedRows.size(); ++i ) + if( m_asLoadedRows[i] == m_asMenuStack.back() ) + iCurrentRow = i; + + const int iCurrentRowStart = iCurrentRow; + RString sDest; + do + { + iCurrentRow += iDir; + wrap( iCurrentRow, m_asLoadedRows.size() ); + sDest = m_asLoadedRows[iCurrentRow]; + } + while( RowIsMenusOnly(sDest) && iCurrentRow != iCurrentRowStart ); + + ASSERT( !sDest.empty() ); + if( m_asMenuStack.size() == 1 ) + m_asMenuStack.push_back( sDest ); + else + m_asMenuStack.back() = sDest; + + SetDefaultCurrentRow(); + SwitchToCurrentRow(); + TweenOnCurrentRow( iDir > 0 ); +} + +void OptionsList::Input( const InputEventPlus &input ) +{ + if( input.type == IET_RELEASE ) + return; + + const OptionRowHandler *pHandler = GetCurrentHandler(); + + PlayerNumber pn = input.pn; + if( input.MenuI == MENU_BUTTON_LEFT ) + { + if( INPUTMAPPER->IsBeingPressed(MENU_BUTTON_RIGHT, pn) ) + { + LOG->Trace( "X1" ); + SwitchMenu( -1 ); + return; + } + + LOG->Trace( "X2" ); + --m_iMenuStackSelection; + wrap( m_iMenuStackSelection, pHandler->m_Def.m_vsChoices.size()+1 ); // +1 for exit row + PositionCursor(); + } + else if( input.MenuI == MENU_BUTTON_RIGHT ) + { + if( INPUTMAPPER->IsBeingPressed(MENU_BUTTON_LEFT, pn) ) + { + LOG->Trace( "X3" ); + SwitchMenu( +1 ); + return; + } + + LOG->Trace( "X4" ); + ++m_iMenuStackSelection; + wrap( m_iMenuStackSelection, pHandler->m_Def.m_vsChoices.size()+1 ); // +1 for exit row + PositionCursor(); + } + else if( input.MenuI == MENU_BUTTON_START ) + { + LOG->Trace( "X5" ); + Start(); + } +} + +void OptionsList::SwitchToCurrentRow() +{ + m_iCurrentRow = !m_iCurrentRow; + + /* Set up the new row. */ + m_Row[m_iCurrentRow].SetFromHandler( GetCurrentHandler() ); + m_Row[m_iCurrentRow].SetUnderlines( m_bSelections[m_asMenuStack.back()] ); + PositionCursor(); +} + +/* After setting up a new row, tween it on. */ +void OptionsList::TweenOnCurrentRow( bool bForward ) +{ + OptionListRow &OldRow = m_Row[!m_iCurrentRow]; + OptionListRow &NewRow = m_Row[m_iCurrentRow]; + + /* Tween out the old row. */ + if( bForward ) + OldRow.PlayCommand( "TweenOutForward" ); + else + OldRow.PlayCommand( "TweenOutBackward" ); + + /* Tween in the old row. */ + if( bForward ) + NewRow.PlayCommand( "TweenInForward" ); + else + NewRow.PlayCommand( "TweenInBackward" ); +} + +void OptionsList::ImportRow( RString sRow ) +{ + vector aSelections[NUM_PLAYERS]; + vector vpns; + vpns.push_back(PLAYER_1); // XXX + OptionRowHandler *pHandler = m_Rows[sRow]; + aSelections[PLAYER_1].resize( pHandler->m_Def.m_vsChoices.size() ); + pHandler->ImportOption( vpns, aSelections ); + m_bSelections[sRow] = aSelections[PLAYER_1]; + + if( RowIsMenusOnly(sRow) ) + fill( m_bSelections[sRow].begin(), m_bSelections[sRow].end(), false ); +} + +void OptionsList::ExportRow( RString sRow ) +{ + if( RowIsMenusOnly(sRow) ) + return; + + vector aSelections[NUM_PLAYERS]; + aSelections[PLAYER_1] = m_bSelections[sRow]; + + vector vpns; + vpns.push_back(PLAYER_1); // XXX + + m_Rows[sRow]->ExportOption( vpns, aSelections ); +} + +void OptionsList::SetDefaultCurrentRow() +{ + const OptionRowHandler *pHandler = GetCurrentHandler(); + const RString &sCurrentRow = m_asMenuStack.back(); + const vector &bSelections = m_bSelections[sCurrentRow]; + + /* Choose the default cursor position, based on the selection and the contents + * of the row. If */ + /* If all items on the row just point to other menus, default to 0. */ + + if( pHandler->m_Def.m_selectType == SELECT_ONE ) + { + /* One item is selected, so position the cursor on it. */ + } + + m_iMenuStackSelection = 0; // XXX +} + +void OptionsList::Pop() +{ + if( m_asMenuStack.size() == 1 ) + { + Close(); + return; + } + + RString sLastMenu = m_asMenuStack.back(); + + m_asMenuStack.pop_back(); + + /* Choose the default option. */ + SetDefaultCurrentRow(); + + /* If the old menu exists as a target from the new menu, switch to it. */ + const OptionRowHandler *pHandler = GetCurrentHandler(); + RString sDest; + for( size_t i = 0; i < pHandler->m_Def.m_vsChoices.size(); ++i ) + { + if( pHandler->GetScreen(i) == sLastMenu ) + { + m_iMenuStackSelection = i; + break; + } + } + + SwitchToCurrentRow(); + TweenOnCurrentRow( false ); +} + +void OptionsList::Push( RString sDest ) +{ + m_asMenuStack.push_back( sDest ); + SetDefaultCurrentRow(); + SwitchToCurrentRow(); +} + +bool OptionsList::Start() +{ + const OptionRowHandler *pHandler = GetCurrentHandler(); + const RString &sCurrentRow = m_asMenuStack.back(); + vector &bSelections = m_bSelections[sCurrentRow]; + if( m_iMenuStackSelection == (int)bSelections.size() ) + { + Pop(); + return m_asMenuStack.empty(); + } + + RString sDest = pHandler->GetScreen( m_iMenuStackSelection ); + if( sDest.size() ) + { + Push( sDest ); + TweenOnCurrentRow( true ); + return false; + } + + if( pHandler->m_Def.m_selectType == SELECT_MULTIPLE ) + { + bool bSelected = !bSelections[m_iMenuStackSelection]; + bSelections[m_iMenuStackSelection] = bSelected; + +// if( bSelected ) +// m_SoundToggleOn.Play(); +// else +// m_SoundToggleOff.Play(); + } + else // data.selectType != SELECT_MULTIPLE + { + fill( bSelections.begin(), bSelections.end(), false ); + bSelections[m_iMenuStackSelection] = true; + } + + ExportRow( sCurrentRow ); + + m_Row[m_iCurrentRow].SetUnderlines( m_bSelections[m_asMenuStack.back()] ); + + if( pHandler->m_Def.m_selectType == SELECT_ONE ) + { + /* Move to the exit row. Don't exit, so different entries don't have widely + * different types, with some exiting the menu level and some not; this also + * makes selection using L+R and R+L faster. */ + m_iMenuStackSelection = (int)bSelections.size(); + PositionCursor(); + } + + return false; +} + +/* + * Copyright (c) 2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + diff --git a/stepmania/src/OptionsList.h b/stepmania/src/OptionsList.h new file mode 100644 index 0000000000..cdbaf12534 --- /dev/null +++ b/stepmania/src/OptionsList.h @@ -0,0 +1,106 @@ +#ifndef SCREEN_OPTIONS_LIST_H +#define SCREEN_OPTIONS_LIST_H + +#include "ScreenWithMenuElements.h" +#include "RageSound.h" +#include "Steps.h" +#include "Trail.h" +#include "OptionRowHandler.h" +#include "BitmapText.h" +#include "OptionsCursor.h" + +class OptionListRow: public ActorFrame +{ +public: + void Load( const RString &sType ); + void SetFromHandler( const OptionRowHandler *pHandler ); + void SetUnderlines( const vector &aSelections ); + + void PositionCursor( Actor *pCursor, int iSelection ); + + void Up(); + void Down(); + void Start(); + +private: + vector m_Text; + // underline for each ("self or child has selection") + vector m_Underlines; + + bool m_bItemsInTwoRows; + + ThemeMetric ITEMS_SPACING_Y; +}; + +class OptionsList: public ActorFrame +{ +public: + OptionsList(); + ~OptionsList(); + + void Load( RString sType ); + + /* Show the top-level menu. */ + void Open(); + + /* Close all menus (for menu timer). */ + void Close(); + + void Input( const InputEventPlus &input ); + bool IsOpened() const { return m_asMenuStack.size() > 0; } + + bool Start(); /* return true if the last menu was popped in response to this press */ + +private: + void SwitchMenu( int iDir ); + void PositionCursor(); + const OptionRowHandler *GetCurrentHandler(); + void SwitchToCurrentRow(); + void TweenOnCurrentRow( bool bForward ); + void SetDefaultCurrentRow(); + void Push( RString sDest ); + void Pop(); + void ImportRow( RString sRow ); + void ExportRow( RString sRow ); + bool RowIsMenusOnly( RString sRow ) const; + + vector m_asLoadedRows; + map m_Rows; + map > m_bSelections; + + AutoActor m_Cursor; + OptionListRow m_Row[2]; + int m_iCurrentRow; + + vector m_asMenuStack; + int m_iMenuStackSelection; +}; + + +#endif + +/* + * Copyright (c) 2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + diff --git a/stepmania/src/ScreenSelectMusic.cpp b/stepmania/src/ScreenSelectMusic.cpp index c048dfd601..79a373c86e 100644 --- a/stepmania/src/ScreenSelectMusic.cpp +++ b/stepmania/src/ScreenSelectMusic.cpp @@ -28,6 +28,7 @@ #include "BannerCache.h" #include "song.h" #include "InputEventPlus.h" +#include "OptionsList.h" const int NUM_SCORE_DIGITS = 9; @@ -68,6 +69,7 @@ void ScreenSelectMusic::Init() MUSIC_WHEEL_TYPE.Load( m_sName, "MusicWheelType" ); SELECT_MENU_AVAILABLE.Load( m_sName, "SelectMenuAvailable" ); MODE_MENU_AVAILABLE.Load( m_sName, "ModeMenuAvailable" ); + USE_OPTIONS_LIST.Load( m_sName, "UseOptionsList" ); m_GameButtonPreviousSong = INPUTMAPPER->GetInputScheme()->ButtonNameToIndex( THEME->GetMetric(m_sName,"PreviousSongButton") ); m_GameButtonNextSong = INPUTMAPPER->GetInputScheme()->ButtonNameToIndex( THEME->GetMetric(m_sName,"NextSongButton") ); @@ -116,6 +118,18 @@ void ScreenSelectMusic::Init() LOAD_ALL_COMMANDS_AND_SET_XY( m_MusicWheel ); this->AddChild( &m_MusicWheel ); + if( USE_OPTIONS_LIST ) + { + FOREACH_PlayerNumber(p) + { + m_OptionsList[p].SetName( "OptionsList" + PlayerNumberToString(p) ); + m_OptionsList[p].Load( "OptionsList" ); + m_OptionsList[p].SetDrawOrder( 100 ); + ActorUtil::LoadAllCommands( m_OptionsList[p], m_sName ); + this->AddChild( &m_OptionsList[p] ); + } + } + // this is loaded SetSong and TweenToSong m_Banner.SetName( "Banner" ); LOAD_ALL_COMMANDS_AND_SET_XY( m_Banner ); @@ -281,6 +295,48 @@ void ScreenSelectMusic::Input( const InputEventPlus &input ) MESSAGEMAN->Broadcast("SongChosen"); } + if( USE_OPTIONS_LIST ) + { + PlayerNumber pn = input.pn; + if( pn != PLAYER_INVALID ) + { + if( m_OptionsList[pn].IsOpened() ) + { + if( input.type == IET_FIRST_PRESS ) + { + switch( input.MenuI ) + { + case GAME_BUTTON_SELECT: + this->PlayCommand( ssprintf("OptionsClosedP%i", pn+1) ); + m_OptionsList[pn].Close(); + break; + case GAME_BUTTON_START: + if( m_OptionsList[pn].Start() ) + { + this->PlayCommand( ssprintf("OptionsClosedP%i", pn+1) ); + m_OptionsList[pn].Close(); + } + break; + default: + m_OptionsList[pn].Input( input ); + break; + } + } + return; + } + else + { + if( input.type == IET_FIRST_PRESS && input.MenuI == GAME_BUTTON_SELECT ) + { + this->PlayCommand( ssprintf("OptionsOpenedP%i", pn+1) ); + m_OptionsList[pn].Open(); + return; + } + } + } + } + + // debugging? // I just like being able to see untransliterated titles occasionally. if( input.DeviceI.device == DEVICE_KEYBOARD && input.DeviceI.button == KEY_F9 ) diff --git a/stepmania/src/ScreenSelectMusic.h b/stepmania/src/ScreenSelectMusic.h index b001bddac6..90a5836d78 100644 --- a/stepmania/src/ScreenSelectMusic.h +++ b/stepmania/src/ScreenSelectMusic.h @@ -14,6 +14,7 @@ #include "RageTexturePreloader.h" #include "TimingData.h" #include "GameInput.h" +#include "OptionsList.h" class ScreenSelectMusic : public ScreenWithMenuElements { @@ -66,6 +67,7 @@ protected: ThemeMetric OPTIONS_MENU_AVAILABLE; DynamicThemeMetric SELECT_MENU_AVAILABLE; DynamicThemeMetric MODE_MENU_AVAILABLE; + ThemeMetric USE_OPTIONS_LIST; GameButton m_GameButtonPreviousSong; GameButton m_GameButtonNextSong; @@ -82,6 +84,8 @@ protected: Sprite m_sprHighScoreFrame[NUM_PLAYERS]; BitmapText m_textHighScore[NUM_PLAYERS]; MusicWheel m_MusicWheel; + OptionsList m_OptionsList[NUM_PLAYERS]; + bool m_bMadeChoice; bool m_bGoToOptions; diff --git a/stepmania/src/StepMania-net2003.vcproj b/stepmania/src/StepMania-net2003.vcproj index e20ea4ac7d..8eabfc05a7 100644 --- a/stepmania/src/StepMania-net2003.vcproj +++ b/stepmania/src/StepMania-net2003.vcproj @@ -1478,6 +1478,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + @@ -2981,6 +2987,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + +