diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index d9c79eeab1..5f0de07bd4 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -2699,6 +2699,11 @@ + + + + + diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index 19ee01c14f..72c55222ce 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -4747,7 +4747,8 @@ prev_note_name, succeeded = options:NoteSkin("cel") Returns the number of trails with the specified StepsType and Difficulty that you've scored a certain Grade g on. - Returns the type of the profile. The type of the profile is only used to determine where the profile shows up in the list of profiles, and that problem is already handled by ProfileManager, so if you're reading this, this function only exists so you can make your theme color this profile's list entry based on the type or something like that. + Returns the type of the profile. The StepMania engine uses ProfileType to sort the list of profiles, with Guest profiles appearing first, then Normal, then Test.
+ Additional subsorting can be configured with .
Returns the user table for this Profile. @@ -6858,6 +6859,13 @@ end Horizontal alignment. See .
+ + + Possible values for the ProfileSortOrder preference. The engine initially sorts profiles based on their , showing Guest profiles first, then Normal, then Test. ProfileSortOrder allows additional subsorts to be configured.
+ Priority allows users to manually sort profiles using the Priority= key in each profile's Type.ini file. New profiles are created with Priority=0. A profile with Priority=0 will appear before any profiles with Priority=1 which will appear before any profiles with Priority=2 and so on.
+ Recent automatically sorts profiles in the order they are used, with the most recently used profile appearing first. +
+
Vertical alignment. See . diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index c08409154b..f82ab2b563 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -691,6 +691,7 @@ x2.5=2.5x 1000000=1000000 Actual=Actual Add=Additive +Alphabetical=Alphabetical All Music=All Music AllDifficulties=All Difficulties AllGroups=All Groups @@ -839,6 +840,7 @@ On (recommended)=On (recommended) Only Dedicated Buttons=Only Dedicated Buttons Overhead=Overhead Pay=Pay +Priority=Priority Percent=Percent Planted=Planted Press Start=Press Start @@ -851,6 +853,7 @@ Random Movies=Random Movies Ranking=Ranking Ranking Songs=Ranking Songs Really Fast=Really Fast +Recent=Recently Used RegularCourses=Regular Remove=Remove RemoveCombinations=Remove diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 7bac0aa31a..e94758af70 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -3096,7 +3096,7 @@ Line21="conf,RateModPreservesPitch" Fallback="ScreenOptionsServiceChild" NextScreen="ScreenOptionsService" PrevScreen="ScreenOptionsService" -LineNames="3,4,8,SI,SM,HN,11,13,14,15,16,28,29,30,31,32,ECPT" +LineNames="3,4,8,SI,SM,HN,11,13,14,15,16,28,29,30,31,32,33,ECPT" #LineScore="lua,UserPrefScoringMode()" Line3="conf,TimingWindowScale" Line4="conf,LifeDifficulty" @@ -3113,6 +3113,8 @@ Line28="conf,AutogenSteps" Line29="conf,AutogenGroupCourses" Line30="conf,FastLoad" Line32="conf,AllowSongDeletion" +Line33="conf,ProfileSortOrder" +Line33="conf,ProfileSortOrderAscending" LineECPT="conf,EditClearPromptThreshold" # unused options diff --git a/src/GameState.cpp b/src/GameState.cpp index 14e5b5c26c..98ff476107 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -834,6 +834,20 @@ void GameState::FinishStage() { Profile* pProfile = PROFILEMAN->GetProfile(p); pProfile->m_iCurrentCombo = STATSMAN->m_CurStageStats.m_player[p].m_iCurCombo; + //If the sort order is Recent, move the profile to the top of the list. + if (PREFSMAN->m_ProfileSortOrder == ProfileSortOrder_Recent && PROFILEMAN->IsPersistentProfile(p)) + { + int numLocalProfiles = PROFILEMAN->GetNumLocalProfiles(); + for (int i = 0; i < numLocalProfiles; i++) + { + Profile *profile = PROFILEMAN->GetLocalProfileFromIndex(i); + if (profile->m_sGuid == pProfile->m_sGuid) + { + PROFILEMAN->MoveProfileTopBottom(i, PREFSMAN->m_bProfileSortOrderAscending); + break; + } + } + } } if( m_bDemonstrationOrJukebox ) diff --git a/src/PrefsManager.cpp b/src/PrefsManager.cpp index 5367cc8317..779c9780fa 100644 --- a/src/PrefsManager.cpp +++ b/src/PrefsManager.cpp @@ -125,6 +125,15 @@ XToString( BackgroundFitMode ); StringToX( BackgroundFitMode ); LuaXType( BackgroundFitMode ); +static const char* ProfileSortOrderNames[] = { + "Priority", + "Recent", + "Alphabetical" +}; +XToString(ProfileSortOrder); +StringToX(ProfileSortOrder); +LuaXType(ProfileSortOrder); + bool g_bAutoRestart = false; #ifdef DEBUG # define TRUE_IF_DEBUG true @@ -258,6 +267,8 @@ PrefsManager::PrefsManager() : m_bAnisotropicFiltering ( "AnisotropicFiltering", false ), m_bSignProfileData ( "SignProfileData", false ), + m_ProfileSortOrder ( "ProfileSortOrder", ProfileSortOrder_Priority ), + m_bProfileSortOrderAscending ( "ProfileSortOrderAscending", true ), m_CourseSortOrder ( "CourseSortOrder", COURSE_SORT_SONGS ), m_bSubSortByNumSteps ( "SubSortByNumSteps", false ), m_GetRankingName ( "GetRankingName", RANKING_ON ), diff --git a/src/PrefsManager.h b/src/PrefsManager.h index e993e1ff20..7f5d0b4e43 100644 --- a/src/PrefsManager.h +++ b/src/PrefsManager.h @@ -112,6 +112,18 @@ enum BackgroundFitMode BackgroundFitMode_Invalid }; +// Profile sort orders exist for sorting the list of profiles. +// Regardless of sort order, Guest profiles are always at the top of the list +// and Test profiles are always at the bottom of the list. +enum ProfileSortOrder +{ + ProfileSortOrder_Priority, // Sort based on the Priority defined in a profile's Type.ini + ProfileSortOrder_Recent, // Sorts profiles by most recently used. + ProfileSortOrder_Alphabetical, // Sorts profiles alphabetically. + NUM_ProfileSortOrder, + ProfileSortOrder_Invalid +}; + /** @brief Holds user-chosen preferences that are saved between sessions. */ class PrefsManager { @@ -271,6 +283,13 @@ public: // profile's data will be discarded. Preference m_bSignProfileData; + // Used to control the ordering of the player profiles. + // See the the definition of ProfileSortOrder above about the available sort options. + Preference m_ProfileSortOrder; + + // Determines whether the ProfileSortOrder is in ascending order (true) or descending order (false). + Preference m_bProfileSortOrderAscending; + // course ranking Preference m_CourseSortOrder; Preference m_bSubSortByNumSteps; diff --git a/src/Profile.cpp b/src/Profile.cpp index ab8694dfaa..de7b088ab6 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -1331,6 +1331,11 @@ void Profile::LoadTypeFromDir(RString dir) } } data->GetAttrValue("Priority", m_ListPriority); + RString date_str; + if (data->GetAttrValue("LastPlayedDate", date_str)) + { + m_LastPlayedDate.FromString(date_str); + } } } } @@ -1501,6 +1506,7 @@ void Profile::SaveTypeToDir(RString dir) const IniFile ini; ini.SetValue("ListPosition", "Type", ProfileTypeToString(m_Type)); ini.SetValue("ListPosition", "Priority", m_ListPriority); + ini.SetValue("ListPosition", "LastPlayedDate", DateTime::GetNowDateTime().GetString()); ini.WriteFile(dir + TYPE_INI); } diff --git a/src/Profile.h b/src/Profile.h index 412d09c9d8..4e16aaca87 100644 --- a/src/Profile.h +++ b/src/Profile.h @@ -62,7 +62,7 @@ class Steps; class Course; struct Game; -// Profile types exist for sorting the list of profiles. +// Profile types exist for distinguishing profiles and facilitating sorting. // Guest profiles at the top, test at the bottom. enum ProfileType { diff --git a/src/ProfileManager.cpp b/src/ProfileManager.cpp index 5f4c4a44a1..71f3f2684e 100644 --- a/src/ProfileManager.cpp +++ b/src/ProfileManager.cpp @@ -439,6 +439,22 @@ void ProfileManager::RefreshLocalProfilesFromDisk() { UnloadAllLocalProfiles(); + switch(PREFSMAN->m_ProfileSortOrder) + { + case ProfileSortOrder_Alphabetical: + LoadLocalProfilesByName(); + break; + case ProfileSortOrder_Recent: + LoadLocalProfilesByRecent(); + break; + default: + LoadLocalProfilesByPriority(); + break; + } +} + +void ProfileManager::LoadLocalProfilesByPriority() +{ std::vector profile_ids; GetDirListing(USER_PROFILES_DIR + "*", profile_ids, true, true); // Profiles have 3 types: @@ -490,7 +506,136 @@ void ProfileManager::RefreshLocalProfilesFromDisk() { curr.profile.LoadAllFromDir(curr.sDir, PREFSMAN->m_bSignProfileData); } - } +} + +void ProfileManager::LoadLocalProfilesByName() +{ + std::vector profile_ids; + GetDirListing(USER_PROFILES_DIR + "*", profile_ids, true, true); + + // Create separate vectors for each profile type + std::vector guestProfiles; + std::vector normalProfiles; + std::vector testProfiles; + + for (RString const &id : profile_ids) + { + DirAndProfile derp; + derp.sDir= id + "/"; + derp.profile.LoadEditableDataFromDir(derp.sDir); + derp.profile.LoadTypeFromDir(derp.sDir); + // insert profile into the appropriate vector based on profile type + switch(derp.profile.m_Type) + { + case ProfileType_Guest: + guestProfiles.push_back(derp); + break; + case ProfileType_Normal: + normalProfiles.push_back(derp); + break; + case ProfileType_Test: + testProfiles.push_back(derp); + break; + default: + break; + } + } + + // Sort each vector by display name + if (PREFSMAN->m_bProfileSortOrderAscending) { + auto displayNameAscending = [](const DirAndProfile &a, const DirAndProfile &b) + { + return a.profile.m_sDisplayName.CompareNoCase(b.profile.m_sDisplayName) < 0; + }; + std::sort(guestProfiles.begin(), guestProfiles.end(), displayNameAscending); + std::sort(normalProfiles.begin(), normalProfiles.end(), displayNameAscending); + std::sort(testProfiles.begin(), testProfiles.end(), displayNameAscending); + } else { + auto displayNameDescending = [](const DirAndProfile &a, const DirAndProfile &b) + { + return a.profile.m_sDisplayName.CompareNoCase(b.profile.m_sDisplayName) > 0; + }; + std::sort(guestProfiles.begin(), guestProfiles.end(), displayNameDescending); + std::sort(normalProfiles.begin(), normalProfiles.end(), displayNameDescending); + std::sort(testProfiles.begin(), testProfiles.end(), displayNameDescending); + } + + add_category_to_global_list(guestProfiles); + add_category_to_global_list(normalProfiles); + add_category_to_global_list(testProfiles); + + for (DirAndProfile &curr : g_vLocalProfile) + { + curr.profile.LoadAllFromDir(curr.sDir, PREFSMAN->m_bSignProfileData); + } + +} + +// This function is used within RefreshLocalProfilesFromDisk() to sort the profiles by date. +void ProfileManager::LoadLocalProfilesByRecent() +{ + + std::vector profile_ids; + GetDirListing(USER_PROFILES_DIR + "*", profile_ids, true, true); + + // Create separate vectors for each profile type + std::vector guestProfiles; + std::vector normalProfiles; + std::vector testProfiles; + + // The type data for a profile is in its own file so that loading isn't + // slowed down by copying temporary profiles around to make sure the list + // is sorted. The profiles are loaded at the end. -Kyz + for (RString const &id : profile_ids) + { + DirAndProfile derp; + derp.sDir= id + "/"; + derp.profile.LoadTypeFromDir(derp.sDir); + // insert profile into the appropriate vector based on profile type + switch(derp.profile.m_Type) + { + case ProfileType_Guest: + guestProfiles.push_back(derp); + break; + case ProfileType_Normal: + normalProfiles.push_back(derp); + break; + case ProfileType_Test: + testProfiles.push_back(derp); + break; + default: + break; + } + } + + // Sort each vector by date + if (PREFSMAN->m_bProfileSortOrderAscending) { + auto lastPlayedAscending = [](const DirAndProfile &a, const DirAndProfile &b) + { + return a.profile.m_LastPlayedDate > b.profile.m_LastPlayedDate; + }; + std::sort(guestProfiles.begin(), guestProfiles.end(), lastPlayedAscending); + std::sort(normalProfiles.begin(), normalProfiles.end(), lastPlayedAscending); + std::sort(testProfiles.begin(), testProfiles.end(), lastPlayedAscending); + } else { + auto lastPlayedDescending = [](const DirAndProfile &a, const DirAndProfile &b) + { + return a.profile.m_LastPlayedDate < b.profile.m_LastPlayedDate; + }; + std::sort(guestProfiles.begin(), guestProfiles.end(), lastPlayedDescending); + std::sort(normalProfiles.begin(), normalProfiles.end(), lastPlayedDescending); + std::sort(testProfiles.begin(), testProfiles.end(), lastPlayedDescending); + } + + add_category_to_global_list(guestProfiles); + add_category_to_global_list(normalProfiles); + add_category_to_global_list(testProfiles); + + for (DirAndProfile &curr : g_vLocalProfile) + { + curr.profile.LoadAllFromDir(curr.sDir, PREFSMAN->m_bSignProfileData); + } +} const Profile *ProfileManager::GetLocalProfile( const RString &sProfileID ) const { @@ -572,15 +717,17 @@ bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut ) static void InsertProfileIntoList(DirAndProfile& derp) { - bool inserted= false; - derp.profile.m_ListPriority= 0; + bool inserted = false; + derp.profile.m_ListPriority = 0; + int index = -1; for (auto curr = g_vLocalProfile.begin(); curr != g_vLocalProfile.end(); ++curr) { + ++index; if(curr->profile.m_Type > derp.profile.m_Type) { derp.profile.SaveTypeToDir(derp.sDir); g_vLocalProfile.insert(curr, derp); - inserted= true; + inserted = true; break; } else if(curr->profile.m_Type == derp.profile.m_Type) @@ -588,11 +735,26 @@ static void InsertProfileIntoList(DirAndProfile& derp) ++derp.profile.m_ListPriority; } } + if(!inserted) { derp.profile.SaveTypeToDir(derp.sDir); g_vLocalProfile.push_back(derp); } + + // The above should run regardless of profile sort in case the user decides to change + // back to priority sorting. If we're using Recent sorting, move the new profile to + // the top, if we're using alphabetical find where it belongs. + switch (PREFSMAN->m_ProfileSortOrder) { + case ProfileSortOrder_Recent: + PROFILEMAN->MoveProfileTopBottom(index, PREFSMAN->m_bProfileSortOrderAscending); + break; + case ProfileSortOrder_Alphabetical: + PROFILEMAN->MoveProfileSorted(index, PREFSMAN->m_bProfileSortOrderAscending); + break; + default: + break; + } } void ProfileManager::AddLocalProfileByID( Profile *pProfile, RString sProfileID ) @@ -648,7 +810,7 @@ bool ProfileManager::DeleteLocalProfile( RString sProfileID ) else { LOG->Warn("[ProfileManager::DeleteLocalProfile] DeleteRecursive(%s) failed", - sProfileID.c_str() ); + sProfileID.c_str() ); return false; } } @@ -787,6 +949,90 @@ void ProfileManager::ChangeProfileType(int index, ProfileType new_type) InsertProfileIntoList(derp); } +void ProfileManager::MoveProfileTopBottom(int index, bool top) +{ + if (index < 0 || static_cast(index) >= g_vLocalProfile.size()) + { + return; + } + + int swindex = 0; + // There may be guest profiles at the top of the list, so we need to skip over them if moving to the top. + // If we're moving the profile to the bottom we should stop once we find the first test profile. + for (size_t i= 0; i < g_vLocalProfile.size(); ++i) + { + ProfileType type= g_vLocalProfile[i].profile.m_Type; + if (!top) + { + if (type == ProfileType_Test) + { + break; + } + } + else + { + if (type != ProfileType_Guest) + { + break; + } + } + swindex++; + } + if ((top && index < swindex) || (!top && index > swindex)) + { + return; + } + + // Save the profile to move + DirAndProfile profile = g_vLocalProfile[index]; + // Remove the profile from its current position + g_vLocalProfile.erase(g_vLocalProfile.begin() + index); + // Insert the profile at the beginning of the list + g_vLocalProfile.insert(g_vLocalProfile.begin() + swindex, profile); +} + +void ProfileManager::MoveProfileSorted(int index, bool bAscending) { + + if (index < 0 || static_cast(index) >= g_vLocalProfile.size()) + { + return; + } + + int swindex = 0; + // There may be guest profiles at the top of the list, so we need to skip over them. + for (size_t i= 0; i < g_vLocalProfile.size(); ++i) + { + ProfileType type= g_vLocalProfile[i].profile.m_Type; + if (type != ProfileType_Guest) + { + break; + } + swindex++; + } + + if (index < swindex) + { + return; + } + + // Copy the profile to be moved + DirAndProfile temp = g_vLocalProfile[index]; + + // Remove the profile from the list + g_vLocalProfile.erase(g_vLocalProfile.begin()+index); + + // Find the correct location to insert the profile + auto it = std::lower_bound(g_vLocalProfile.begin()+swindex, g_vLocalProfile.end(), temp, + [bAscending](const DirAndProfile &a, const DirAndProfile &b) + { + if (bAscending) + return a.profile.m_sDisplayName < b.profile.m_sDisplayName; + else + return a.profile.m_sDisplayName > b.profile.m_sDisplayName; + }); + g_vLocalProfile.insert(it, temp); +} + void ProfileManager::MoveProfilePriority(int index, bool up) { if(index < 0 || static_cast(index) >= g_vLocalProfile.size()) diff --git a/src/ProfileManager.h b/src/ProfileManager.h index 10ceb18bd7..4db46ead9c 100644 --- a/src/ProfileManager.h +++ b/src/ProfileManager.h @@ -15,6 +15,7 @@ class Course; class Trail; struct HighScore; struct lua_State; + /** @brief Interface to machine and memory card profiles. */ class ProfileManager { @@ -29,6 +30,10 @@ public: // local profiles void UnloadAllLocalProfiles(); void RefreshLocalProfilesFromDisk(); + void LoadLocalProfilesByPriority(); + void LoadLocalProfilesByRecent(); + void LoadLocalProfilesByName(); + const Profile *GetLocalProfile( const RString &sProfileID ) const; Profile *GetLocalProfile( const RString &sProfileID ) { return (Profile*) ((const ProfileManager *) this)->GetLocalProfile(sProfileID); } Profile *GetLocalProfileFromIndex( int iIndex ); @@ -58,6 +63,8 @@ public: void MergeLocalProfileIntoMachine(RString const& from_id, bool skip_totals); void ChangeProfileType(int index, ProfileType new_type); void MoveProfilePriority(int index, bool up); + void MoveProfileTopBottom(int index, bool top); + void MoveProfileSorted(int index, bool bAscending); // General data void IncrementToastiesCount( PlayerNumber pn ); diff --git a/src/ScreenOptionsManageProfiles.cpp b/src/ScreenOptionsManageProfiles.cpp index ae7d11a2d9..799f32bc48 100644 --- a/src/ScreenOptionsManageProfiles.cpp +++ b/src/ScreenOptionsManageProfiles.cpp @@ -244,7 +244,12 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM ) RString sNewName = ScreenTextEntry::s_sLastAnswer; PROFILEMAN->RenameLocalProfile( GAMESTATE->m_sEditLocalProfileID, sNewName ); - + if (PREFSMAN->m_ProfileSortOrder == ProfileSortOrder_Alphabetical) + { + PROFILEMAN->MoveProfileSorted( + GetLocalProfileIndexWithFocus(), + PREFSMAN->m_bProfileSortOrderAscending); + } SCREENMAN->SetNewScreen( this->m_sName ); // reload } } @@ -449,8 +454,14 @@ void ScreenOptionsManageProfiles::ProcessMenuStart( const InputEventPlus & ) ADD_ACTION( ProfileAction_ChangeToGuest ); ADD_ACTION( ProfileAction_ChangeToNormal ); ADD_ACTION( ProfileAction_ChangeToTest ); - ADD_ACTION( ProfileAction_MoveUp ); - ADD_ACTION( ProfileAction_MoveDown ); + // There technically isn't an issue keeping these enabled for other ProfileSorts, + // but it's not really useful as it would be overwritten. + if (PREFSMAN->m_ProfileSortOrder == ProfileSortOrder_Priority) + { + ADD_ACTION( ProfileAction_MoveUp ); + ADD_ACTION( ProfileAction_MoveDown ); + } + } int iWidth, iX, iY; diff --git a/src/ScreenOptionsMaster.cpp b/src/ScreenOptionsMaster.cpp index 110d6ed816..e3c9b6e417 100644 --- a/src/ScreenOptionsMaster.cpp +++ b/src/ScreenOptionsMaster.cpp @@ -8,6 +8,7 @@ #include "GameState.h" #include "ScreenManager.h" #include "SongManager.h" +#include "ProfileManager.h" #include "PrefsManager.h" #include "StepMania.h" #include "RageSoundManager.h" @@ -111,6 +112,12 @@ void ScreenOptionsMaster::HandleScreenMessage( const ScreenMessage SM ) for( unsigned r=0; rRefreshLocalProfilesFromDisk(); + } + if( m_iChangeMask & OPT_APPLY_ASPECT_RATIO ) { THEME->UpdateLuaGlobals(); // This needs to be done before resetting the projection matrix below diff --git a/src/ScreenOptionsMasterPrefs.cpp b/src/ScreenOptionsMasterPrefs.cpp index 047d54c087..4b38538267 100644 --- a/src/ScreenOptionsMasterPrefs.cpp +++ b/src/ScreenOptionsMasterPrefs.cpp @@ -885,7 +885,11 @@ static void InitializeConfOptions() ADD( ConfOption( "MaxHighScoresPerListForMachine", MaxHighScoresPerListForMachine, "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20") ); ADD( ConfOption( "MaxHighScoresPerListForPlayer", MaxHighScoresPerListForPlayer, "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20") ); ADD( ConfOption( "MinTNSToHideNotes", MovePref, "TNS_None", "TNS_HitMine", "TNS_AvoidMine", "TNS_CheckpointMiss", "TNS_Miss", "TNS_W5", "TNS_W4", "TNS_W3", "TNS_W2", "TNS_W1", "TNS_CheckpointHit")); - + ADD( ConfOption( "ProfileSortOrderAscending", MovePref, "No", "Yes") ); + g_ConfOptions.back().m_iEffects = OPT_APPLY_PROFILES; + ADD( ConfOption( "ProfileSortOrder", MovePref, "Priority", "Recent", "Alphabetical") ); + g_ConfOptions.back().m_sPrefName = "ProfileSortOrder"; + g_ConfOptions.back().m_iEffects = OPT_APPLY_PROFILES; // Graphic options ADD( ConfOption( "Windowed", MovePref, "Full Screen", "Windowed" ) ); @@ -986,7 +990,8 @@ static const char *OptEffectNames[] = { "ChangeGame", "ApplySound", "ApplySong", - "ApplyAspectRatio" + "ApplyAspectRatio", + "ApplyProfiles" }; XToString( OptEffect ); StringToX( OptEffect ); diff --git a/src/ScreenOptionsMasterPrefs.h b/src/ScreenOptionsMasterPrefs.h index 8654fe7318..1080923dfa 100644 --- a/src/ScreenOptionsMasterPrefs.h +++ b/src/ScreenOptionsMasterPrefs.h @@ -13,7 +13,8 @@ enum OptEffect OPT_APPLY_SOUND = (1<<4), OPT_APPLY_SONG = (1<<5), OPT_APPLY_ASPECT_RATIO = (1<<6), - NUM_OptEffect = 7, + OPT_APPLY_PROFILES = (1<<7), + NUM_OptEffect = 8, OptEffect_Invalid = MAX_OPTIONS+1 }; const RString& OptEffectToString( OptEffect e );