diff --git a/stepmania/src/ScreenOptionsMaster.cpp b/stepmania/src/ScreenOptionsMaster.cpp index 4135a45671..c228d8bfa3 100644 --- a/stepmania/src/ScreenOptionsMaster.cpp +++ b/stepmania/src/ScreenOptionsMaster.cpp @@ -150,7 +150,7 @@ void ScreenOptionsMaster::SetConf( OptionRow &row, OptionRowHandler &hand, CStri row.bOneChoiceForAllPlayers = true; hand.type = ROW_CONFIG; - hand.opt = FindConfOption( param ); + hand.opt = ConfOption::Find( param ); if( hand.opt == NULL ) RageException::Throw( "Invalid Conf type \"%s\"", param.c_str() ); @@ -366,7 +366,9 @@ void ScreenOptionsMaster::ImportOptions() } } -void ScreenOptionsMaster::ExportOption( const OptionRow &row, const OptionRowHandler &hand, int pn, int sel ) + +/* Returns an OPT mask. */ +int ScreenOptionsMaster::ExportOption( const OptionRow &row, const OptionRowHandler &hand, int pn, int sel ) { /* Figure out which selection is the default. */ switch( hand.type ) @@ -377,8 +379,24 @@ void ScreenOptionsMaster::ExportOption( const OptionRow &row, const OptionRowHan break; case ROW_CONFIG: + { + /* Get the original choice. */ + int Original = hand.opt->Get( row.choices ); + + /* Apply. */ hand.opt->Put( sel, row.choices ); - break; + + /* Get the new choice. */ + int New = hand.opt->Get( row.choices ); + + /* If it didn't change, don't return any side-effects. */ + LOG->Trace("origin %i, %i %s", Original, New, hand.opt->name.c_str()); + if( Original == New ) + return 0; + LOG->Trace("foo %i", hand.opt->GetEffects()); + + return hand.opt->GetEffects(); + } case ROW_CHARACTER: if( sel == 0 ) @@ -422,11 +440,12 @@ void ScreenOptionsMaster::ExportOption( const OptionRow &row, const OptionRowHan ASSERT(0); break; } + return 0; } void ScreenOptionsMaster::ExportOptions() { - const CString OldTheme = THEME->GetCurThemeName(); + int ChangeMask = 0; unsigned i; for( i = 0; i < OptionRowHandlers.size(); ++i ) @@ -436,7 +455,7 @@ void ScreenOptionsMaster::ExportOptions() if( row.bOneChoiceForAllPlayers ) { - ExportOption( row, hand, 0, m_iSelectedOption[0][i] ); + ChangeMask |= ExportOption( row, hand, 0, m_iSelectedOption[0][i] ); } else for( int pn=0; pnIsHumanPlayer(pn) ) continue; - ExportOption( row, hand, pn, m_iSelectedOption[pn][i] ); + ChangeMask |= ExportOption( row, hand, pn, m_iSelectedOption[pn][i] ); } } @@ -467,24 +486,14 @@ void ScreenOptionsMaster::ExportOptions() if( m_NextScreen == "" ) m_NextScreen = NEXT_SCREEN; - /* If any ROW_CONFIG options were used, save preferences. */ - bool ConfChanged = false; - for( i = 0; i < OptionRowHandlers.size(); ++i ) - if( OptionRowHandlers[i].type == ROW_CONFIG ) - ConfChanged = true; - /* Did the theme change? */ - if( OldTheme != THEME->GetCurThemeName() ) - { - // THEME->SwitchThemeAndLanguage( sNewTheme, THEME->GetCurLanguage() ); - ApplyGraphicOptions(); // reset graphics to apply new window title and icon + if( (ChangeMask & OPT_APPLY_THEME) || + (ChangeMask & OPT_APPLY_GRAPHICS) ) // reset graphics to apply new window title and icon + ApplyGraphicOptions(); - SONGMAN->UpdateRankingCourses(); // update ranking courses - ConfChanged = true; // save it - } - - if( ConfChanged ) + if( ChangeMask & OPT_SAVE_PREFERENCES ) { + /* Save preferences. */ LOG->Trace("ROW_CONFIG used; saving ..."); PREFSMAN->SaveGlobalPrefsToDisk(); PREFSMAN->SaveGamePrefsToDisk(); diff --git a/stepmania/src/ScreenOptionsMaster.h b/stepmania/src/ScreenOptionsMaster.h index b16110105b..57179d9d51 100644 --- a/stepmania/src/ScreenOptionsMaster.h +++ b/stepmania/src/ScreenOptionsMaster.h @@ -42,7 +42,7 @@ private: OptionRow *m_OptionRowAlloc; CString ConvertParamToThemeDifficulty( const CString &in ) const; - void ExportOption( const OptionRow &row, const OptionRowHandler &hand, int pn, int sel ); + int ExportOption( const OptionRow &row, const OptionRowHandler &hand, int pn, int sel ); int ImportOption( const OptionRow &row, const OptionRowHandler &hand, int pn ); void SetList( OptionRow &row, OptionRowHandler &hand, CString param, CString &TitleOut ); void SetStep( OptionRow &row, OptionRowHandler &hand ); diff --git a/stepmania/src/ScreenOptionsMasterPrefs.cpp b/stepmania/src/ScreenOptionsMasterPrefs.cpp index 94956a1b43..91be851351 100644 --- a/stepmania/src/ScreenOptionsMasterPrefs.cpp +++ b/stepmania/src/ScreenOptionsMasterPrefs.cpp @@ -7,6 +7,8 @@ #include "NoteSkinManager.h" #include "PlayerOptions.h" #include "SongOptions.h" +#include "RageDisplay.h" +#include "RageUtil.h" /* "sel" is the selection in the menu. */ template @@ -197,6 +199,77 @@ MOVE( MarvelousTiming, PREFSMAN->m_iMarvelousTiming ); MOVE( PickExtraStage, PREFSMAN->m_bPickExtraStage ); MOVE( UnlockSystem, PREFSMAN->m_bUseUnlockSystem ); +/* Graphic options */ +MOVE( DisplayMode, PREFSMAN->m_bWindowed ); +MOVE( WaitForVsync, PREFSMAN->m_bVsync ); +MOVE( ShowStats, PREFSMAN->m_bShowStats ); +MOVE( KeepTexturesInMemory, PREFSMAN->m_bDelayedTextureDelete ); + +template +static void MoveMap( int &sel, T &opt, bool ToSel, const T *map, unsigned cnt ) +{ + if( ToSel ) + { + /* opt -> sel. Find the closest entry in map. */ + T best_dist = -1; + + for( unsigned i = 0; i < cnt; ++i ) + { + const T val = map[i]; + T dist = opt-val; + if( dist < 0 ) + dist = -dist; + if( best_dist != -1 && dist > best_dist ) + continue; + + best_dist = dist; + + sel = i; + } + } else { + /* sel -> opt */ + opt = map[sel]; + } +} + +static void DisplayResolution( int &sel, bool ToSel, const CStringArray &choices ) +{ + const int map[] = { 320,400,512,640,800,1024,1280 }; + MoveMap( sel, PREFSMAN->m_iDisplayWidth, ToSel, map, ARRAYSIZE(map) ); + if( !ToSel ) + PREFSMAN->m_iDisplayHeight = PREFSMAN->m_iDisplayWidth * 3 / 4; +} + +static void DisplayColor( int &sel, bool ToSel, const CStringArray &choices ) +{ + const int map[] = { 16,32 }; + MoveMap( sel, PREFSMAN->m_iDisplayColorDepth, ToSel, map, ARRAYSIZE(map) ); +} + +static void TextureResolution( int &sel, bool ToSel, const CStringArray &choices ) +{ + const int map[] = { 256,512,1024,2048 }; + MoveMap( sel, PREFSMAN->m_iMaxTextureResolution, ToSel, map, ARRAYSIZE(map) ); +} + +static void TextureColor( int &sel, bool ToSel, const CStringArray &choices ) +{ + const int map[] = { 16,32 }; + MoveMap( sel, PREFSMAN->m_iTextureColorDepth, ToSel, map, ARRAYSIZE(map) ); +} + +static void RefreshRate( int &sel, bool ToSel, const CStringArray &choices ) +{ + const int map[] = { (int) REFRESH_DEFAULT,60,70,72,75,80,85,90,100,120,150 }; + MoveMap( sel, PREFSMAN->m_iRefreshRate, ToSel, map, ARRAYSIZE(map) ); +} + +static void MovieDecode( int &sel, bool ToSel, const CStringArray &choices ) +{ + const int map[] = { 1,2,3,4 }; + MoveMap( sel, PREFSMAN->m_iMovieDecodeMS, ToSel, map, ARRAYSIZE(map) ); +} + /* Sound options */ MOVE( PreloadSounds, PREFSMAN->m_bSoundPreloadAll ); MOVE( ResamplingQuality, PREFSMAN->m_iSoundResampleQuality ); @@ -248,13 +321,51 @@ static const ConfOption g_ConfOptions[] = ConfOption( "Pick Extra\nStage", PickExtraStage, "OFF","ON" ), ConfOption( "Unlock\nSystem", UnlockSystem, "OFF","ON" ), + /* Graphic options */ + ConfOption( "Display\nMode", DisplayMode, "FULLSCREEN", "WINDOWED" ), + ConfOption( "Display\nResolution", DisplayResolution, "320","400","512","640","800","1024","1280" ), + ConfOption( "Display\nColor", DisplayColor, "16BIT","32BIT" ), + ConfOption( "Texture\nResolution", TextureResolution, "256","512","1024","2048" ), + ConfOption( "Texture\nColor", TextureColor, "16BIT","32BIT" ), + ConfOption( "Keep Textures\nIn Memory", KeepTexturesInMemory, "NO","YES" ), + ConfOption( "Refresh\nRate", RefreshRate, "DEFAULT","60","70","72","75","80","85","90","100","120","150" ), + ConfOption( "Movie\nDecode", MovieDecode, "1ms","2ms","3ms","4ms" ), + ConfOption( "Wait For\nVsync", WaitForVsync, "NO", "YES" ), + ConfOption( "Show\nStats", ShowStats, "OFF","ON" ), + /* Sound options */ - ConfOption( "Preload\nSounds", PreloadSounds, "NO","YES" ), - ConfOption( "Resampling\nQuality", ResamplingQuality, "FAST","NORMAL","HIGH QUALITY" ), + ConfOption( "Preload\nSounds", PreloadSounds, "NO","YES" ), + ConfOption( "Resampling\nQuality", ResamplingQuality, "FAST","NORMAL","HIGH QUALITY" ), ConfOption( "", NULL ) }; -const ConfOption *FindConfOption( CString name ) +/* Get a mask of effects to apply if the given option changes. */ +int ConfOption::GetEffects() const +{ + struct opts { + ConfOption::MoveData_t ptr; + int effects; + } opts[] = { + { Language, OPT_APPLY_THEME }, + { Theme, OPT_APPLY_THEME }, + { DisplayMode, OPT_APPLY_GRAPHICS }, + { DisplayResolution, OPT_APPLY_GRAPHICS }, + { DisplayColor, OPT_APPLY_GRAPHICS }, + { TextureResolution, OPT_APPLY_GRAPHICS }, + { KeepTexturesInMemory, OPT_APPLY_GRAPHICS }, + { RefreshRate, OPT_APPLY_GRAPHICS }, + { WaitForVsync, OPT_APPLY_GRAPHICS } + }; + + int ret = OPT_SAVE_PREFERENCES; + for( unsigned i = 0; i < ARRAYSIZE(opts); ++i ) + if( opts[i].ptr == MoveData ) + return ret |= opts[i].effects; + + return ret; +} + +const ConfOption *ConfOption::Find( CString name ) { for( unsigned i = 0; g_ConfOptions[i].name != ""; ++i ) { diff --git a/stepmania/src/ScreenOptionsMasterPrefs.h b/stepmania/src/ScreenOptionsMasterPrefs.h index c65bdb8a81..1064532cdc 100644 --- a/stepmania/src/ScreenOptionsMasterPrefs.h +++ b/stepmania/src/ScreenOptionsMasterPrefs.h @@ -2,12 +2,19 @@ #define SCREEN_OPTIONS_MASTER_PREFS_H static const int MAX_OPTIONS=16; +#define OPT_SAVE_PREFERENCES 0x1 +#define OPT_APPLY_GRAPHICS 0x2 +#define OPT_APPLY_THEME 0x4 + struct ConfOption { + static const ConfOption *Find( CString name ); + /* Name of this option. It's helpful to delimit this with newlines, as it'll * be the default display title. */ CString name; - void (*MoveData)( int &sel, bool ToSel, const CStringArray &choices ); + typedef void (*MoveData_t)( int &sel, bool ToSel, const CStringArray &choices ); + MoveData_t MoveData; /* If MakeOptionsListCB is set, it'll be called by MakeOptionsList; otherwise * the contents of names is returned. */ @@ -15,6 +22,7 @@ struct ConfOption inline int Get( const CStringArray &choices ) const { int sel; MoveData( sel, true, choices ); return sel; } inline void Put( int sel, const CStringArray &choices ) const { MoveData( sel, false, choices ); } + int GetEffects() const; ConfOption( const char *n, void (*m)( int &sel, bool in, const CStringArray &choices ), const char *c0=NULL, const char *c1=NULL, const char *c2=NULL, const char *c3=NULL, const char *c4=NULL, const char *c5=NULL, const char *c6=NULL, const char *c7=NULL, const char *c8=NULL, const char *c9=NULL, const char *c10=NULL, const char *c11=NULL, const char *c12=NULL, const char *c13=NULL, const char *c14=NULL, const char *c15=NULL, const char *c16=NULL, const char *c17=NULL, const char *c18=NULL, const char *c19=NULL ) @@ -41,6 +49,5 @@ private: void (*MakeOptionsListCB)( CStringArray &out ); }; -const ConfOption *FindConfOption( CString name ); #endif