diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 4e78eb92ff..ca91738f17 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -134,7 +134,10 @@ void GameState::Reset() } for( p=0; pSaveProfile( (PlayerNumber)p ); PROFILEMAN->UnloadProfile( (PlayerNumber)p ); + } // save stats info intermitently in case of crash BOOKKEEPER->WriteToDisk(); diff --git a/stepmania/src/ModeChoice.cpp b/stepmania/src/ModeChoice.cpp index e117d1ead5..c2865b1aba 100644 --- a/stepmania/src/ModeChoice.cpp +++ b/stepmania/src/ModeChoice.cpp @@ -251,7 +251,7 @@ void ModeChoice::Apply( PlayerNumber pn ) const // if( m_style != STYLE_INVALID ) { - PROFILEMAN->LoadDefaultProfileFromMachine( pn ); + PROFILEMAN->LoadFirstAvailableProfile( pn ); } } diff --git a/stepmania/src/PrefsManager.cpp b/stepmania/src/PrefsManager.cpp index 82734fdd63..e93efdd926 100644 --- a/stepmania/src/PrefsManager.cpp +++ b/stepmania/src/PrefsManager.cpp @@ -18,6 +18,7 @@ #include "RageUtil.h" #include "arch/arch.h" /* for default driver specs */ #include "RageSoundReader_Resample.h" /* for ResampleQuality */ +#include "RageFile.h" #define STEPMANIA_INI_PATH BASE_PATH "Data" SLASH "StepMania.ini" #define STATIC_INI_PATH BASE_PATH "Data" SLASH "Static.ini" @@ -309,7 +310,11 @@ void PrefsManager::ReadGlobalPrefsFromDisk() ini.GetValue( "Options", "EndlessBreakLength", m_iEndlessBreakLength ); for( int p=0; p &asNamesOut ) } -bool ProfileManager::LoadDefaultProfileFromMachine( PlayerNumber pn ) +bool ProfileManager::LoadProfile( PlayerNumber pn, CString sProfileDir, bool bIsMemCard ) { - m_bUsingMemoryCard[pn] = false; - CString sProfileID = PREFSMAN->m_sDefaultProfile[pn]; - if( sProfileID.empty() ) - { - m_sProfileDir[pn] = ""; - return false; - } + ASSERT( !sProfileDir.empty() ); + ASSERT( sProfileDir.Right(1) == SLASH ); - m_sProfileDir[pn] = PROFILES_DIR + sProfileID + SLASH; + m_sProfileDir[pn] = sProfileDir; + m_bUsingMemoryCard[pn] = bIsMemCard; bool bResult = m_Profile[pn].LoadFromIni( m_sProfileDir[pn]+PROFILE_FILE ); if( !bResult ) { - LOG->Warn( "Default profile '%s' does not exist", sProfileID.c_str() ); + LOG->Warn( "Attempting to load profile from '%s' and does not exist", sProfileDir.c_str() ); UnloadProfile( pn ); return false; } @@ -87,6 +84,94 @@ bool ProfileManager::LoadDefaultProfileFromMachine( PlayerNumber pn ) return true; } +bool ProfileManager::CreateProfile( CString sProfileDir, CString sName ) +{ + bool bResult; + + CreateDirectories( sProfileDir ); + + Profile pro; + pro.m_sName = sName; + bResult = pro.SaveToIni( sProfileDir + PROFILE_FILE ); + if( !bResult ) + return false; + + FlushDirCache(); + return true; +} + +bool ProfileManager::LoadDefaultProfileFromMachine( PlayerNumber pn ) +{ + CString sProfileID = PREFSMAN->m_sDefaultMachineProfileID[pn]; + if( sProfileID.empty() ) + { + m_sProfileDir[pn] = ""; + return false; + } + + CString sDir = PROFILES_DIR + sProfileID + SLASH; + + return LoadProfile( pn, sDir, false ); +} + +bool ProfileManager::IsMemoryCardInserted( PlayerNumber pn ) +{ + CString sDir = PREFSMAN->m_sMemoryCardDir[pn]; + if( sDir.empty() ) + return false; + if( sDir.Right(1) != SLASH ) + sDir += SLASH; + + // + // Test whether a memory card is available by trying to write a file. + // + CString sFile = sDir + "temp"; + FILE* fp = fopen( sFile, "w" ); + if( fp ) + { + fclose( fp ); + remove( sFile ); + return true; + } + else + { + return false; + } +} + +bool ProfileManager::LoadProfileFromMemoryCard( PlayerNumber pn ) +{ + CString sDir = PREFSMAN->m_sMemoryCardDir[pn]; + if( sDir.empty() ) + return false; + if( sDir.Right(1) != SLASH ) + sDir += SLASH; + + m_bUsingMemoryCard[pn] = true; + bool bResult; + bResult = LoadProfile( pn, sDir, false ); + if( bResult ) + { + return true; + } + else + { + // silently create memory card data here + bResult = CreateProfile( sDir, NEW_PROFILE_NAME ); + return bResult; + } +} + +bool ProfileManager::LoadFirstAvailableProfile( PlayerNumber pn ) +{ + if( IsMemoryCardInserted(pn) && LoadProfileFromMemoryCard(pn) ) + return true; + else if( LoadDefaultProfileFromMachine(pn) ) + return true; + else + return false; +} + bool ProfileManager::SaveProfile( PlayerNumber pn ) { if( m_sProfileDir[pn].empty() ) @@ -128,7 +213,7 @@ bool Profile::LoadFromIni( CString sIniPath ) CString sLastDir = asBits.back(); // this is a number name, e.g. "0000001" // Fill in a default value in case ini doesn't have it. - m_sName = "NewProfile"; + m_sName = NEW_PROFILE_NAME; // @@ -154,6 +239,9 @@ bool Profile::SaveToIni( CString sIniPath ) bool ProfileManager::CreateMachineProfile( CString sName ) { + if( sName.empty() ) + sName = NEW_PROFILE_NAME; + // // Find a free directory name in the profiles directory // @@ -168,18 +256,21 @@ bool ProfileManager::CreateMachineProfile( CString sName ) } if( i == MAX_TRIES ) return false; - - CreateDirectories( sProfileDir ); - sProfileDir += SLASH; - + + bool bResult; + bResult = CreateDirectories( sProfileDir ); + if( !bResult ) + return false; + Profile pro; pro.m_sName = sName; - pro.SaveToIni( sProfileDir + PROFILE_FILE ); + bResult = pro.SaveToIni( sProfileDir + PROFILE_FILE ); + if( !bResult ) + return false; FlushDirCache(); return true; - // TODO: Handle error cases } bool ProfileManager::RenameMachineProfile( CString sProfileID, CString sNewName ) diff --git a/stepmania/src/ProfileManager.h b/stepmania/src/ProfileManager.h index 3dabecd171..d1bddbcace 100644 --- a/stepmania/src/ProfileManager.h +++ b/stepmania/src/ProfileManager.h @@ -40,11 +40,13 @@ public: bool RenameMachineProfile( CString sProfileID, CString sNewName ); bool DeleteMachineProfile( CString sProfileID ); + bool CreateMemoryCardProfile( CString sName ); + void GetMachineProfileIDs( vector &asProfileIDsOut ); void GetMachineProfileNames( vector &asNamesOut ); - bool LoadDefaultProfileFromMachine( PlayerNumber pn ); - bool LoadProfileFromMemoryCard( PlayerNumber pn ); + bool LoadFirstAvailableProfile( PlayerNumber pn ); + bool IsMemoryCardInserted( PlayerNumber pn ); bool SaveProfile( PlayerNumber pn ); void UnloadProfile( PlayerNumber pn ); @@ -52,10 +54,14 @@ public: Profile* GetProfile( PlayerNumber pn ); - bool IsMemoryCardInserted( PlayerNumber pn ); bool IsUsingMemoryCard( PlayerNumber pn ) { return m_bUsingMemoryCard[pn]; } private: + bool LoadDefaultProfileFromMachine( PlayerNumber pn ); + bool LoadProfileFromMemoryCard( PlayerNumber pn ); + bool LoadProfile( PlayerNumber pn, CString sProfileDir, bool bIsMemCard ); + bool CreateProfile( CString sProfileDir, CString sName ); + // Directory that contains the profile. Either on local machine or // on a memory card. CString m_sProfileDir[NUM_PLAYERS]; diff --git a/stepmania/src/ScreenProfileOptions.cpp b/stepmania/src/ScreenProfileOptions.cpp index 15b30010a9..da4575f988 100644 --- a/stepmania/src/ScreenProfileOptions.cpp +++ b/stepmania/src/ScreenProfileOptions.cpp @@ -28,6 +28,8 @@ enum { PO_CREATE_NEW, PO_DELETE_, PO_RENAME_, + PO_CARD_DIR_1, + PO_CARD_DIR_2, NUM_PROFILE_OPTIONS_LINES }; @@ -37,6 +39,8 @@ OptionRow g_ProfileOptionsLines[NUM_PROFILE_OPTIONS_LINES] = { OptionRow( "Create\nNew", true, "PRESS START" ), OptionRow( "Delete", true ), OptionRow( "Rename", true ), + OptionRow( "Card Dir\nPlayer1", true, "" ), + OptionRow( "Card Dir\nPlayer2", true, "" ), }; const ScreenMessage SM_DoneCreating = ScreenMessage(SM_User+1); @@ -63,6 +67,16 @@ ScreenProfileOptions::ScreenProfileOptions( CString sClassName ) : ScreenOptions g_ProfileOptionsLines[PO_RENAME_].choices.push_back( "-NONE-" ); PROFILEMAN->GetMachineProfileNames( g_ProfileOptionsLines[PO_RENAME_].choices ); + if( PREFSMAN->m_sMemoryCardDir[PLAYER_1].empty() ) + g_ProfileOptionsLines[PO_CARD_DIR_1].choices[0] = "-NONE. SPECIFY IN INI-"; + else + g_ProfileOptionsLines[PO_CARD_DIR_1].choices[0] = PREFSMAN->m_sMemoryCardDir[PLAYER_1]; + + if( PREFSMAN->m_sMemoryCardDir[PLAYER_2].empty() ) + g_ProfileOptionsLines[PO_CARD_DIR_2].choices[0] = "-NONE. SPECIFY IN INI-"; + else + g_ProfileOptionsLines[PO_CARD_DIR_2].choices[0] = PREFSMAN->m_sMemoryCardDir[PLAYER_2]; + Init( INPUTMODE_TOGETHER, g_ProfileOptionsLines, @@ -83,14 +97,14 @@ void ScreenProfileOptions::ImportOptions() iter = find( vsProfiles.begin(), vsProfiles.end(), - PREFSMAN->m_sDefaultProfile[PLAYER_1] ); + PREFSMAN->m_sDefaultMachineProfileID[PLAYER_1] ); if( iter != vsProfiles.end() ) m_iSelectedOption[0][PO_PLAYER1] = iter - vsProfiles.begin() + 1; iter = find( vsProfiles.begin(), vsProfiles.end(), - PREFSMAN->m_sDefaultProfile[PLAYER_2] ); + PREFSMAN->m_sDefaultMachineProfileID[PLAYER_2] ); if( iter != vsProfiles.end() ) m_iSelectedOption[0][PO_PLAYER2] = iter - vsProfiles.begin() + 1; } @@ -101,14 +115,14 @@ void ScreenProfileOptions::ExportOptions() PROFILEMAN->GetMachineProfileIDs( vsProfiles ); if( m_iSelectedOption[0][PO_PLAYER1] > 0 ) - PREFSMAN->m_sDefaultProfile[PLAYER_1] = vsProfiles[m_iSelectedOption[0][PO_PLAYER1]-1]; + PREFSMAN->m_sDefaultMachineProfileID[PLAYER_1] = vsProfiles[m_iSelectedOption[0][PO_PLAYER1]-1]; else - PREFSMAN->m_sDefaultProfile[PLAYER_1] = ""; + PREFSMAN->m_sDefaultMachineProfileID[PLAYER_1] = ""; if( m_iSelectedOption[0][PO_PLAYER2] > 0 ) - PREFSMAN->m_sDefaultProfile[PLAYER_2] = vsProfiles[m_iSelectedOption[0][PO_PLAYER2]-1]; + PREFSMAN->m_sDefaultMachineProfileID[PLAYER_2] = vsProfiles[m_iSelectedOption[0][PO_PLAYER2]-1]; else - PREFSMAN->m_sDefaultProfile[PLAYER_2] = ""; + PREFSMAN->m_sDefaultMachineProfileID[PLAYER_2] = ""; } void ScreenProfileOptions::GoToPrevState() @@ -132,12 +146,12 @@ void ScreenProfileOptions::HandleScreenMessage( const ScreenMessage SM ) case SM_DoneCreating: if( !ScreenTextEntry::s_bCancelledLast ) { - CString sNewProfileID = ScreenTextEntry::s_sLastAnswer; - bool bResult = PROFILEMAN->CreateMachineProfile( sNewProfileID ); + CString sNewName = ScreenTextEntry::s_sLastAnswer; + bool bResult = PROFILEMAN->CreateMachineProfile( sNewName ); if( bResult ) SCREENMAN->SetNewScreen( "ScreenProfileOptions" ); // reload else - SCREENMAN->Prompt( SM_None, ssprintf("Error creating profile '%s'.", sNewProfileID.c_str()) ); + SCREENMAN->Prompt( SM_None, ssprintf("Error creating profile '%s'.", sNewName.c_str()) ); } break; case SM_DoneRenaming: