2003-09-28 02:59:02 +00:00
|
|
|
#include "global.h"
|
|
|
|
|
|
|
|
|
|
#include "ScreenOptionsMaster.h"
|
|
|
|
|
#include "RageException.h"
|
|
|
|
|
#include "RageUtil.h"
|
|
|
|
|
#include "RageLog.h"
|
|
|
|
|
#include "ThemeManager.h"
|
|
|
|
|
#include "GameState.h"
|
|
|
|
|
#include "ScreenManager.h"
|
|
|
|
|
#include "NoteSkinManager.h"
|
|
|
|
|
#include "Course.h"
|
|
|
|
|
#include "Steps.h"
|
|
|
|
|
#include "StyleDef.h"
|
|
|
|
|
#include "song.h"
|
|
|
|
|
#include "SongManager.h"
|
|
|
|
|
#include "Character.h"
|
2003-09-28 05:04:55 +00:00
|
|
|
#include "PrefsManager.h"
|
2003-09-28 02:59:02 +00:00
|
|
|
#include "ScreenOptionsMasterPrefs.h"
|
2003-09-28 05:19:37 +00:00
|
|
|
#include "RageSounds.h"
|
2003-09-28 07:14:07 +00:00
|
|
|
#include "StepMania.h"
|
2003-09-28 02:59:02 +00:00
|
|
|
|
2003-09-28 04:07:53 +00:00
|
|
|
#define OPTION_MENU_FLAGS THEME->GetMetric (m_sName,"OptionMenuFlags")
|
2003-09-28 02:59:02 +00:00
|
|
|
#define ROW_LINE(i) THEME->GetMetric (m_sName,ssprintf("Line%i",(i+1)))
|
|
|
|
|
|
2003-09-28 04:13:40 +00:00
|
|
|
#define ENTRY(s) THEME->GetMetric ("ScreenOptionsMaster",s)
|
|
|
|
|
#define ENTRY_MODE(s,i) THEME->GetMetric ("ScreenOptionsMaster",ssprintf("%s,%i",(s).c_str(),(i+1)))
|
|
|
|
|
#define ENTRY_NAME(s,i) THEME->GetMetric ("ScreenOptionsMaster",ssprintf("%sName,%i",(s).c_str(),(i+1)))
|
|
|
|
|
#define ENTRY_DEFAULT(s) THEME->GetMetric ("ScreenOptionsMaster",(s) + "Default")
|
2003-09-28 02:59:02 +00:00
|
|
|
#define NEXT_SCREEN THEME->GetMetric (m_sName,"NextScreen")
|
2003-09-28 04:07:53 +00:00
|
|
|
|
2003-09-28 02:59:02 +00:00
|
|
|
// #define NEXT_SCREEN( play_mode ) THEME->GetMetric (m_sName,"NextScreen"+Capitalize(PlayModeToString(play_mode)))
|
|
|
|
|
#define PREV_SCREEN THEME->GetMetric (m_sName,"PrevScreen")
|
|
|
|
|
// #define PREV_SCREEN( play_mode ) THEME->GetMetric (m_sName,"PrevScreen"+Capitalize(PlayModeToString(play_mode)))
|
|
|
|
|
|
2003-09-28 04:13:40 +00:00
|
|
|
#define BEGINNER_DESCRIPTION THEME->GetMetric ("ScreenOptionsMaster","Beginner")
|
|
|
|
|
#define EASY_DESCRIPTION THEME->GetMetric ("ScreenOptionsMaster","Easy")
|
|
|
|
|
#define MEDIUM_DESCRIPTION THEME->GetMetric ("ScreenOptionsMaster","Medium")
|
|
|
|
|
#define HARD_DESCRIPTION THEME->GetMetric ("ScreenOptionsMaster","Hard")
|
|
|
|
|
#define CHALLENGE_DESCRIPTION THEME->GetMetric ("ScreenOptionsMaster","Challenge")
|
2003-09-28 02:59:02 +00:00
|
|
|
|
|
|
|
|
CString ScreenOptionsMaster::ConvertParamToThemeDifficulty( const CString &in ) const
|
|
|
|
|
{
|
|
|
|
|
switch( StringToDifficulty(in) )
|
|
|
|
|
{
|
|
|
|
|
case DIFFICULTY_BEGINNER: return BEGINNER_DESCRIPTION;
|
|
|
|
|
case DIFFICULTY_EASY: return EASY_DESCRIPTION;
|
|
|
|
|
case DIFFICULTY_MEDIUM: return MEDIUM_DESCRIPTION;
|
|
|
|
|
case DIFFICULTY_HARD: return HARD_DESCRIPTION;
|
|
|
|
|
case DIFFICULTY_CHALLENGE: return CHALLENGE_DESCRIPTION;
|
|
|
|
|
default: return in; // something else
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add the list named "ListName" to the given row/handler. */
|
|
|
|
|
void ScreenOptionsMaster::SetList( OptionRow &row, OptionRowHandler &hand, CString ListName, CString &TitleOut )
|
|
|
|
|
{
|
|
|
|
|
hand.type = ROW_LIST;
|
|
|
|
|
|
|
|
|
|
TitleOut = ListName;
|
|
|
|
|
if( !ListName.CompareNoCase("noteskins") )
|
|
|
|
|
{
|
|
|
|
|
hand.Default.Init(); /* none */
|
|
|
|
|
row.bOneChoiceForAllPlayers = false;
|
|
|
|
|
|
|
|
|
|
CStringArray arraySkinNames;
|
|
|
|
|
NOTESKIN->GetNoteSkinNames( arraySkinNames );
|
|
|
|
|
for( unsigned skin=0; skin<arraySkinNames.size(); skin++ )
|
|
|
|
|
{
|
|
|
|
|
arraySkinNames[skin].MakeUpper();
|
|
|
|
|
|
|
|
|
|
ModeChoice mc;
|
|
|
|
|
mc.m_sModifiers = arraySkinNames[skin];
|
|
|
|
|
hand.ListEntries.push_back( mc );
|
|
|
|
|
row.choices.push_back( arraySkinNames[skin] );
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hand.Default.Load( -1, ENTRY_DEFAULT(ListName) );
|
|
|
|
|
|
|
|
|
|
/* Parse the basic configuration metric. */
|
|
|
|
|
CStringArray asParts;
|
|
|
|
|
split( ENTRY(ListName), ",", asParts );
|
|
|
|
|
if( asParts.size() < 1 )
|
|
|
|
|
RageException::Throw( "Parse error in ScreenOptionsMasterEntries::ListName%s", ListName.c_str() );
|
|
|
|
|
|
|
|
|
|
row.bOneChoiceForAllPlayers = false;
|
|
|
|
|
const int NumCols = atoi( asParts[0] );
|
|
|
|
|
if( asParts.size() > 1 )
|
|
|
|
|
row.bOneChoiceForAllPlayers = !asParts[1].CompareNoCase("together");
|
|
|
|
|
|
|
|
|
|
for( int col = 0; col < NumCols; ++col )
|
|
|
|
|
{
|
|
|
|
|
ModeChoice mc;
|
|
|
|
|
mc.Load( 0, ENTRY_MODE(ListName, col) );
|
|
|
|
|
|
|
|
|
|
if( !mc.IsPlayable() )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
hand.ListEntries.push_back( mc );
|
|
|
|
|
row.choices.push_back( ENTRY_NAME(ListName, col) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add a list of difficulties/edits to the given row/handler. */
|
|
|
|
|
void ScreenOptionsMaster::SetStep( OptionRow &row, OptionRowHandler &hand )
|
|
|
|
|
{
|
|
|
|
|
hand.type = ROW_STEP;
|
|
|
|
|
row.bOneChoiceForAllPlayers = false;
|
|
|
|
|
|
|
|
|
|
// fill in difficulty names
|
|
|
|
|
if( GAMESTATE->m_bEditing )
|
|
|
|
|
{
|
|
|
|
|
row.choices.push_back( "" );
|
|
|
|
|
}
|
|
|
|
|
else if( GAMESTATE->m_pCurCourse ) // playing a course
|
|
|
|
|
{
|
|
|
|
|
row.bOneChoiceForAllPlayers = true;
|
|
|
|
|
row.choices.push_back( "REGULAR" );
|
|
|
|
|
if( GAMESTATE->m_pCurCourse->HasDifficult( GAMESTATE->GetCurrentStyleDef()->m_StepsType ) )
|
|
|
|
|
row.choices.push_back( "DIFFICULT" );
|
|
|
|
|
}
|
|
|
|
|
else if( GAMESTATE->m_pCurSong ) // playing a song
|
|
|
|
|
{
|
|
|
|
|
vector<Steps*> vNotes;
|
|
|
|
|
GAMESTATE->m_pCurSong->GetSteps( vNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
|
|
|
|
|
SortNotesArrayByDifficulty( vNotes );
|
|
|
|
|
for( unsigned i=0; i<vNotes.size(); i++ )
|
|
|
|
|
{
|
|
|
|
|
CString s = vNotes[i]->GetDescription();
|
|
|
|
|
s.MakeUpper();
|
|
|
|
|
|
|
|
|
|
// convert to theme-defined values
|
|
|
|
|
s = ConvertParamToThemeDifficulty(s);
|
|
|
|
|
|
|
|
|
|
row.choices.push_back( s );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
row.choices.push_back( "N/A" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Add the given configuration value to the given row/handler. */
|
|
|
|
|
void ScreenOptionsMaster::SetConf( OptionRow &row, OptionRowHandler &hand, CString param, CString &TitleOut )
|
|
|
|
|
{
|
|
|
|
|
/* Configuration values are never per-player. */
|
|
|
|
|
row.bOneChoiceForAllPlayers = true;
|
|
|
|
|
hand.type = ROW_CONFIG;
|
|
|
|
|
|
2003-09-29 02:24:53 +00:00
|
|
|
hand.opt = ConfOption::Find( param );
|
2003-09-28 02:59:02 +00:00
|
|
|
if( hand.opt == NULL )
|
|
|
|
|
RageException::Throw( "Invalid Conf type \"%s\"", param.c_str() );
|
|
|
|
|
|
2003-09-28 05:15:27 +00:00
|
|
|
hand.opt->MakeOptionsList( row.choices );
|
2003-09-28 02:59:02 +00:00
|
|
|
|
|
|
|
|
TitleOut = hand.opt->name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add a list of available characters to the given row/handler. */
|
|
|
|
|
void ScreenOptionsMaster::SetCharacter( OptionRow &row, OptionRowHandler &hand )
|
|
|
|
|
{
|
2003-10-01 10:04:23 +00:00
|
|
|
hand.type = ROW_CHARACTER;
|
2003-09-28 02:59:02 +00:00
|
|
|
row.bOneChoiceForAllPlayers = false;
|
|
|
|
|
row.choices.push_back( "OFF" );
|
|
|
|
|
vector<Character*> apCharacters;
|
|
|
|
|
GAMESTATE->GetCharacters( apCharacters );
|
|
|
|
|
for( unsigned i=0; i<apCharacters.size(); i++ )
|
|
|
|
|
{
|
|
|
|
|
CString s = apCharacters[i]->m_sName;
|
|
|
|
|
s.MakeUpper();
|
|
|
|
|
row.choices.push_back( s );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScreenOptionsMaster::ScreenOptionsMaster( CString sClassName ):
|
|
|
|
|
ScreenOptions( sClassName )
|
|
|
|
|
{
|
2003-09-28 04:34:15 +00:00
|
|
|
LOG->Trace("ScreenOptionsMaster::ScreenOptionsMaster(%s)", m_sName.c_str() );
|
2003-09-28 04:07:53 +00:00
|
|
|
|
2003-09-29 06:39:54 +00:00
|
|
|
/* If this file doesn't exist, leave the music alone (eg. ScreenPlayerOptions music sample
|
|
|
|
|
* left over from ScreenSelectMusic). If you really want to play no music, add a redir
|
|
|
|
|
* to _silent. */
|
|
|
|
|
CString MusicPath = THEME->GetPathToS( ssprintf("%s music", m_sName.c_str()), true );
|
|
|
|
|
if( MusicPath != "" )
|
|
|
|
|
SOUND->PlayMusic( MusicPath );
|
2003-09-28 05:19:37 +00:00
|
|
|
|
2003-09-29 00:43:25 +00:00
|
|
|
m_ForceSMOptionsNavigation = false;
|
|
|
|
|
|
2003-09-28 04:07:53 +00:00
|
|
|
CStringArray Flags;
|
|
|
|
|
split( OPTION_MENU_FLAGS, ";", Flags, true );
|
|
|
|
|
InputMode im = INPUTMODE_INDIVIDUAL;
|
|
|
|
|
bool Explanations = false;
|
|
|
|
|
int NumRows = -1;
|
|
|
|
|
|
|
|
|
|
unsigned i;
|
|
|
|
|
for( i = 0; i < Flags.size(); ++i )
|
|
|
|
|
{
|
|
|
|
|
Flags[i].MakeLower();
|
|
|
|
|
|
|
|
|
|
if( sscanf( Flags[i], "rows,%i", &NumRows ) == 1 )
|
|
|
|
|
continue;
|
|
|
|
|
if( Flags[i] == "together" )
|
|
|
|
|
im = INPUTMODE_TOGETHER;
|
|
|
|
|
if( Flags[i] == "explanations" )
|
|
|
|
|
Explanations = true;
|
|
|
|
|
if( Flags[i] == "forceallplayers" )
|
|
|
|
|
{
|
|
|
|
|
for( int pn=0; pn<NUM_PLAYERS; pn++ )
|
|
|
|
|
GAMESTATE->m_bSideIsJoined[pn] = true;
|
|
|
|
|
GAMESTATE->m_MasterPlayerNumber = PlayerNumber(0);
|
|
|
|
|
}
|
2003-09-29 00:43:25 +00:00
|
|
|
if( Flags[i] == "smnavigation" )
|
|
|
|
|
m_ForceSMOptionsNavigation = true;
|
2003-09-28 04:07:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( NumRows == -1 )
|
|
|
|
|
RageException::Throw( "%s::OptionMenuFlags is missing \"rows\" field", m_sName.c_str() );
|
|
|
|
|
|
|
|
|
|
m_OptionRowAlloc = new OptionRow[NumRows];
|
|
|
|
|
for( i = 0; (int) i < NumRows; ++i )
|
2003-09-28 02:59:02 +00:00
|
|
|
{
|
|
|
|
|
OptionRow &row = m_OptionRowAlloc[i];
|
|
|
|
|
|
|
|
|
|
CStringArray asParts;
|
|
|
|
|
split( ROW_LINE(i), ";", asParts );
|
|
|
|
|
if( asParts.size() < 1 )
|
|
|
|
|
RageException::Throw( "Parse error in %s::Line%i", m_sName.c_str(), i+1 );
|
|
|
|
|
|
|
|
|
|
OptionRowHandler hand;
|
2003-09-29 00:06:40 +00:00
|
|
|
bool TitleSetExplicitly = false;
|
2003-09-28 02:59:02 +00:00
|
|
|
for( unsigned part = 0; part < asParts.size(); ++part)
|
|
|
|
|
{
|
|
|
|
|
CStringArray asBits;
|
|
|
|
|
split( asParts[part], ",", asBits );
|
|
|
|
|
|
|
|
|
|
const CString name = asBits[0];
|
|
|
|
|
const CString param = asBits.size() > 1? asBits[1]: "";
|
|
|
|
|
|
|
|
|
|
CString Title = "";
|
|
|
|
|
if( !name.CompareNoCase("title") )
|
2003-09-28 04:07:53 +00:00
|
|
|
{
|
|
|
|
|
TitleSetExplicitly = true;
|
2003-09-28 02:59:02 +00:00
|
|
|
row.name = param;
|
2003-09-28 04:07:53 +00:00
|
|
|
}
|
2003-09-28 02:59:02 +00:00
|
|
|
else if( !name.CompareNoCase("list") )
|
|
|
|
|
{
|
|
|
|
|
SetList( row, hand, param, Title );
|
|
|
|
|
}
|
|
|
|
|
else if( !name.CompareNoCase("steps") )
|
|
|
|
|
{
|
|
|
|
|
SetStep( row, hand );
|
|
|
|
|
Title = "Steps";
|
|
|
|
|
}
|
|
|
|
|
else if( !name.CompareNoCase("conf") )
|
|
|
|
|
{
|
|
|
|
|
SetConf( row, hand, param, Title );
|
|
|
|
|
}
|
|
|
|
|
else if( !name.CompareNoCase("characters") )
|
|
|
|
|
{
|
|
|
|
|
SetCharacter( row, hand );
|
2003-09-28 04:13:40 +00:00
|
|
|
Title = "Characters";
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
RageException::Throw( "Unexpected type '%s' in %s::Line%i", name.c_str(), m_sName.c_str(), i );
|
2003-09-28 04:07:53 +00:00
|
|
|
|
|
|
|
|
if( !TitleSetExplicitly )
|
2003-09-28 02:59:02 +00:00
|
|
|
row.name = Title;
|
|
|
|
|
}
|
|
|
|
|
OptionRowHandlers.push_back( hand );
|
|
|
|
|
}
|
|
|
|
|
|
2003-09-28 04:07:53 +00:00
|
|
|
ASSERT( (int) OptionRowHandlers.size() == NumRows );
|
2003-09-28 02:59:02 +00:00
|
|
|
|
2003-09-28 04:07:53 +00:00
|
|
|
Init( im, m_OptionRowAlloc, NumRows, Explanations );
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScreenOptionsMaster::~ScreenOptionsMaster()
|
|
|
|
|
{
|
2003-09-29 06:56:36 +00:00
|
|
|
delete [] m_OptionRowAlloc;
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ScreenOptionsMaster::ImportOption( const OptionRow &row, const OptionRowHandler &hand, int pn )
|
|
|
|
|
{
|
|
|
|
|
/* Figure out which selection is the default. */
|
|
|
|
|
switch( hand.type )
|
|
|
|
|
{
|
|
|
|
|
case ROW_LIST:
|
|
|
|
|
{
|
2003-09-29 09:00:59 +00:00
|
|
|
int ret = -1;
|
2003-09-28 02:59:02 +00:00
|
|
|
for( unsigned e = 0; e < hand.ListEntries.size(); ++e )
|
|
|
|
|
{
|
|
|
|
|
const ModeChoice &mc = hand.ListEntries[e];
|
2003-09-29 09:00:59 +00:00
|
|
|
|
|
|
|
|
if( mc.IsZero() )
|
|
|
|
|
{
|
|
|
|
|
/* The entry has no effect. This is usually a default "none of the
|
|
|
|
|
* above" entry. It will always return true for DescribesCurrentMode().
|
|
|
|
|
* It's only the selected choice if nothing else matches. */
|
|
|
|
|
ret = e;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2003-09-28 02:59:02 +00:00
|
|
|
if( row.bOneChoiceForAllPlayers )
|
|
|
|
|
{
|
|
|
|
|
if( mc.DescribesCurrentModeForAllPlayers() )
|
|
|
|
|
return e;
|
|
|
|
|
} else {
|
|
|
|
|
if( mc.DescribesCurrentMode( (PlayerNumber) pn) )
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-10-01 07:05:16 +00:00
|
|
|
ASSERT( ret != -1 );
|
2003-09-29 09:00:59 +00:00
|
|
|
return ret;
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
case ROW_STEP:
|
|
|
|
|
if( GAMESTATE->m_bEditing )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if( GAMESTATE->m_pCurCourse ) // playing a course
|
|
|
|
|
{
|
|
|
|
|
if( GAMESTATE->m_bDifficultCourses &&
|
|
|
|
|
GAMESTATE->m_pCurCourse->HasDifficult( GAMESTATE->GetCurrentStyleDef()->m_StepsType ) )
|
|
|
|
|
return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( GAMESTATE->m_pCurSong ) // playing a song
|
|
|
|
|
{
|
|
|
|
|
vector<Steps*> vNotes;
|
|
|
|
|
GAMESTATE->m_pCurSong->GetSteps( vNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
|
|
|
|
|
SortNotesArrayByDifficulty( vNotes );
|
|
|
|
|
for( unsigned i=0; i<vNotes.size(); i++ )
|
|
|
|
|
{
|
|
|
|
|
if( GAMESTATE->m_pCurNotes[pn] == vNotes[i] )
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2003-09-28 04:13:40 +00:00
|
|
|
|
2003-09-28 02:59:02 +00:00
|
|
|
case ROW_CHARACTER:
|
|
|
|
|
{
|
|
|
|
|
vector<Character*> apCharacters;
|
|
|
|
|
GAMESTATE->GetCharacters( apCharacters );
|
|
|
|
|
for( unsigned i=0; i<apCharacters.size(); i++ )
|
|
|
|
|
if( GAMESTATE->m_pCurCharacters[pn] == apCharacters[i] )
|
|
|
|
|
return i+1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ROW_CONFIG:
|
2003-09-28 07:14:07 +00:00
|
|
|
return hand.opt->Get( row.choices );
|
2003-09-28 02:59:02 +00:00
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
ASSERT(0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenOptionsMaster::ImportOptions()
|
|
|
|
|
{
|
|
|
|
|
for( unsigned i = 0; i < OptionRowHandlers.size(); ++i )
|
|
|
|
|
{
|
|
|
|
|
const OptionRowHandler &hand = OptionRowHandlers[i];
|
|
|
|
|
const OptionRow &row = m_OptionRowAlloc[i];
|
|
|
|
|
|
|
|
|
|
if( row.bOneChoiceForAllPlayers )
|
|
|
|
|
{
|
|
|
|
|
int col = ImportOption( row, hand, 0 );
|
|
|
|
|
m_iSelectedOption[0][i] = col;
|
2003-10-01 10:04:23 +00:00
|
|
|
ASSERT( m_iSelectedOption[0][i] < (int)row.choices.size() );
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
for( int pn=0; pn<NUM_PLAYERS; pn++ )
|
|
|
|
|
{
|
|
|
|
|
if( !GAMESTATE->IsHumanPlayer(pn) )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
int col = ImportOption( row, hand, pn );
|
|
|
|
|
m_iSelectedOption[pn][i] = col;
|
2003-10-01 10:04:23 +00:00
|
|
|
ASSERT( m_iSelectedOption[pn][i] < (int)row.choices.size() );
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-09-29 02:24:53 +00:00
|
|
|
|
|
|
|
|
/* Returns an OPT mask. */
|
|
|
|
|
int ScreenOptionsMaster::ExportOption( const OptionRow &row, const OptionRowHandler &hand, int pn, int sel )
|
2003-09-28 02:59:02 +00:00
|
|
|
{
|
|
|
|
|
/* Figure out which selection is the default. */
|
|
|
|
|
switch( hand.type )
|
|
|
|
|
{
|
|
|
|
|
case ROW_LIST:
|
|
|
|
|
hand.Default.Apply( (PlayerNumber)pn );
|
2003-09-28 04:07:53 +00:00
|
|
|
hand.ListEntries[sel].Apply( (PlayerNumber)pn );
|
2003-09-28 02:59:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ROW_CONFIG:
|
2003-09-29 02:24:53 +00:00
|
|
|
{
|
|
|
|
|
/* Get the original choice. */
|
|
|
|
|
int Original = hand.opt->Get( row.choices );
|
|
|
|
|
|
|
|
|
|
/* Apply. */
|
2003-09-28 07:14:07 +00:00
|
|
|
hand.opt->Put( sel, row.choices );
|
2003-09-29 02:24:53 +00:00
|
|
|
|
|
|
|
|
/* Get the new choice. */
|
|
|
|
|
int New = hand.opt->Get( row.choices );
|
|
|
|
|
|
|
|
|
|
/* If it didn't change, don't return any side-effects. */
|
|
|
|
|
if( Original == New )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return hand.opt->GetEffects();
|
|
|
|
|
}
|
2003-09-28 02:59:02 +00:00
|
|
|
|
|
|
|
|
case ROW_CHARACTER:
|
|
|
|
|
if( sel == 0 )
|
|
|
|
|
GAMESTATE->m_pCurCharacters[pn] = NULL;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vector<Character*> apCharacters;
|
|
|
|
|
GAMESTATE->GetCharacters( apCharacters );
|
2003-10-01 10:04:23 +00:00
|
|
|
ASSERT( sel - 1 < (int)apCharacters.size() );
|
2003-09-28 02:59:02 +00:00
|
|
|
GAMESTATE->m_pCurCharacters[pn] = apCharacters[sel - 1];
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ROW_STEP:
|
|
|
|
|
if( GAMESTATE->m_bEditing )
|
|
|
|
|
{
|
|
|
|
|
// do nothing
|
|
|
|
|
}
|
|
|
|
|
else if( GAMESTATE->m_pCurCourse ) // playing a course
|
|
|
|
|
{
|
|
|
|
|
if( sel == 1 )
|
|
|
|
|
{
|
|
|
|
|
GAMESTATE->m_bDifficultCourses = true;
|
|
|
|
|
LOG->Trace("ScreenPlayerOptions: Using difficult course");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GAMESTATE->m_bDifficultCourses = false;
|
|
|
|
|
LOG->Trace("ScreenPlayerOptions: Using normal course");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( GAMESTATE->m_pCurSong ) // playing a song
|
|
|
|
|
{
|
|
|
|
|
vector<Steps*> vNotes;
|
|
|
|
|
GAMESTATE->m_pCurSong->GetSteps( vNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
|
|
|
|
|
SortNotesArrayByDifficulty( vNotes );
|
|
|
|
|
GAMESTATE->m_pCurNotes[pn] = vNotes[ sel ];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ASSERT(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2003-09-29 02:24:53 +00:00
|
|
|
return 0;
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenOptionsMaster::ExportOptions()
|
|
|
|
|
{
|
2003-09-29 02:24:53 +00:00
|
|
|
int ChangeMask = 0;
|
2003-09-28 07:14:07 +00:00
|
|
|
|
2003-09-28 05:04:55 +00:00
|
|
|
unsigned i;
|
|
|
|
|
for( i = 0; i < OptionRowHandlers.size(); ++i )
|
2003-09-28 02:59:02 +00:00
|
|
|
{
|
|
|
|
|
const OptionRowHandler &hand = OptionRowHandlers[i];
|
|
|
|
|
const OptionRow &row = m_OptionRowAlloc[i];
|
|
|
|
|
|
|
|
|
|
if( row.bOneChoiceForAllPlayers )
|
|
|
|
|
{
|
2003-09-29 02:24:53 +00:00
|
|
|
ChangeMask |= ExportOption( row, hand, 0, m_iSelectedOption[0][i] );
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
for( int pn=0; pn<NUM_PLAYERS; pn++ )
|
|
|
|
|
{
|
|
|
|
|
if( !GAMESTATE->IsHumanPlayer(pn) )
|
|
|
|
|
continue;
|
|
|
|
|
|
2003-09-29 02:24:53 +00:00
|
|
|
ChangeMask |= ExportOption( row, hand, pn, m_iSelectedOption[pn][i] );
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-09-28 04:07:53 +00:00
|
|
|
/* If the selection is on a LIST, and the selected LIST option sets the screen,
|
|
|
|
|
* honor it. */
|
|
|
|
|
m_NextScreen = "";
|
|
|
|
|
|
|
|
|
|
const int row = this->GetCurrentRow();
|
2003-09-29 04:22:59 +00:00
|
|
|
if( row < (int) OptionRowHandlers.size() ) /* might be on "exit" */
|
2003-09-28 04:07:53 +00:00
|
|
|
{
|
2003-09-29 04:22:59 +00:00
|
|
|
const OptionRowHandler &hand = OptionRowHandlers[row];
|
|
|
|
|
if( hand.type == ROW_LIST )
|
|
|
|
|
{
|
|
|
|
|
const int sel = m_iSelectedOption[0][row];
|
|
|
|
|
const ModeChoice &mc = hand.ListEntries[sel];
|
|
|
|
|
if( mc.m_sScreen != "" )
|
|
|
|
|
m_NextScreen = mc.m_sScreen;
|
|
|
|
|
}
|
2003-09-28 04:07:53 +00:00
|
|
|
}
|
|
|
|
|
|
2003-09-28 02:59:02 +00:00
|
|
|
// NEXT_SCREEN(GAMESTATE->m_PlayMode) );
|
|
|
|
|
// XXX: handle different destinations based on play mode?
|
|
|
|
|
if( m_NextScreen == "" )
|
|
|
|
|
m_NextScreen = NEXT_SCREEN;
|
2003-09-28 05:04:55 +00:00
|
|
|
|
2003-09-28 07:14:07 +00:00
|
|
|
/* Did the theme change? */
|
2003-09-29 02:24:53 +00:00
|
|
|
if( (ChangeMask & OPT_APPLY_THEME) ||
|
|
|
|
|
(ChangeMask & OPT_APPLY_GRAPHICS) ) // reset graphics to apply new window title and icon
|
|
|
|
|
ApplyGraphicOptions();
|
2003-09-28 05:04:55 +00:00
|
|
|
|
2003-09-29 02:24:53 +00:00
|
|
|
if( ChangeMask & OPT_SAVE_PREFERENCES )
|
2003-09-28 05:04:55 +00:00
|
|
|
{
|
2003-09-29 02:24:53 +00:00
|
|
|
/* Save preferences. */
|
2003-09-28 05:04:55 +00:00
|
|
|
LOG->Trace("ROW_CONFIG used; saving ...");
|
|
|
|
|
PREFSMAN->SaveGlobalPrefsToDisk();
|
|
|
|
|
PREFSMAN->SaveGamePrefsToDisk();
|
|
|
|
|
}
|
2003-09-29 03:22:51 +00:00
|
|
|
|
|
|
|
|
if( ChangeMask & OPT_RESET_GAME )
|
|
|
|
|
{
|
|
|
|
|
ResetGame();
|
|
|
|
|
m_NextScreen = "";
|
|
|
|
|
}
|
2003-09-28 02:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
2003-09-29 00:43:25 +00:00
|
|
|
void ScreenOptionsMaster::MenuStart( PlayerNumber pn )
|
|
|
|
|
{
|
|
|
|
|
if( m_ForceSMOptionsNavigation )
|
|
|
|
|
{
|
|
|
|
|
StartGoToNextState();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ScreenOptions::MenuStart( pn );
|
|
|
|
|
}
|
|
|
|
|
|
2003-09-28 02:59:02 +00:00
|
|
|
void ScreenOptionsMaster::GoToNextState()
|
|
|
|
|
{
|
|
|
|
|
if( GAMESTATE->m_bEditing )
|
|
|
|
|
SCREENMAN->PopTopScreen();
|
2003-09-29 03:22:51 +00:00
|
|
|
else if( m_NextScreen != "" )
|
2003-09-28 02:59:02 +00:00
|
|
|
SCREENMAN->SetNewScreen( m_NextScreen );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenOptionsMaster::GoToPrevState()
|
|
|
|
|
{
|
|
|
|
|
/* XXX: A better way to handle this would be to check if we're a pushed screen. */
|
|
|
|
|
if( GAMESTATE->m_bEditing )
|
|
|
|
|
SCREENMAN->PopTopScreen();
|
|
|
|
|
// XXX: handle different destinations based on play mode?
|
|
|
|
|
else
|
|
|
|
|
SCREENMAN->SetNewScreen( PREV_SCREEN ); // (GAMESTATE->m_PlayMode) );
|
|
|
|
|
}
|
|
|
|
|
|