diff --git a/src/GameCommand.cpp b/src/GameCommand.cpp index d2fc35a7bc..e3b60582d2 100644 --- a/src/GameCommand.cpp +++ b/src/GameCommand.cpp @@ -529,7 +529,7 @@ bool GameCommand::IsPlayable( RString *why ) const /* If both sides are joined, disallow singles modes, since easy to select * them accidentally, instead of versus mode. */ if( m_pStyle->m_StyleType == StyleType_OnePlayerOneSide && - GAMESTATE->GetNumSidesJoined() > 1 ) + GAMESTATE->GetNumPlayersEnabled() > 1 ) { if( why ) *why = "too many players joined for ONE_PLAYER_ONE_CREDIT"; @@ -669,9 +669,9 @@ void GameCommand::ApplySelf( const vector &vpns ) const switch( m_pStyle->m_StyleType ) { case StyleType_OnePlayerOneSide: + case StyleType_OnePlayerTwoSides: break; case StyleType_TwoPlayersTwoSides: - case StyleType_OnePlayerTwoSides: case StyleType_TwoPlayersSharedSides: { FOREACH_PlayerNumber( p ) diff --git a/src/GameState.cpp b/src/GameState.cpp index b08b07ce67..ed1782b047 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -411,18 +411,29 @@ void GameState::JoinPlayer( PlayerNumber pn ) void GameState::UnjoinPlayer( PlayerNumber pn ) { + /* Unjoin STATSMAN first, so steps used by this player are released + * and can be released by PROFILEMAN. */ + STATSMAN->UnjoinPlayer( pn ); m_bSideIsJoined[pn] = false; m_iPlayerStageTokens[pn] = 0; ResetPlayer( pn ); if( this->GetMasterPlayerNumber() == pn ) - this->SetMasterPlayerNumber(GetFirstHumanPlayer()); - - /* Unjoin STATSMAN first, so steps used by this player are released - * and can be released by PROFILEMAN. */ - STATSMAN->UnjoinPlayer( pn ); - PROFILEMAN->UnloadProfile( pn ); + { + // We can't use GetFirstHumanPlayer() because if both players were joined, GetFirstHumanPlayer() will always return PLAYER_1, even when PLAYER_1 is the player we're unjoining. + FOREACH_HumanPlayer( hp ) + { + if( pn != hp ) + { + this->SetMasterPlayerNumber(hp); + } + } + if( this->GetMasterPlayerNumber() == pn ) + { + this->SetMasterPlayerNumber(PLAYER_INVALID); + } + } Message msg( MessageIDToString(Message_PlayerUnjoined) ); msg.SetParam( "Player", pn ); diff --git a/src/ProfileManager.cpp b/src/ProfileManager.cpp index 9ef64ecf3a..9bca938ed4 100644 --- a/src/ProfileManager.cpp +++ b/src/ProfileManager.cpp @@ -349,6 +349,12 @@ bool ProfileManager::SaveLocalProfile( RString sProfileID ) void ProfileManager::UnloadProfile( PlayerNumber pn ) { + if( m_sProfileDir[pn].empty() ) + { + // Don't bother unloading a profile that wasn't loaded in the first place. + // Saves us an expensive and pointless trip through all the songs. + return; + } m_sProfileDir[pn] = ""; m_sProfileDirImportedFrom[pn] = ""; m_bWasLoadedFromMemoryCard[pn] = false; diff --git a/src/ScreenSelectProfile.cpp b/src/ScreenSelectProfile.cpp index 301a549e87..a21d6013e0 100644 --- a/src/ScreenSelectProfile.cpp +++ b/src/ScreenSelectProfile.cpp @@ -134,7 +134,7 @@ bool ScreenSelectProfile::SetProfileIndex( PlayerNumber pn, int iProfileIndex ) // unload player if( iProfileIndex == -2 ) { - PROFILEMAN->UnloadProfile( pn ); + // GAMESTATE->UnjoinPlayer takes care of unloading the profile. GAMESTATE->UnjoinPlayer( pn ); MEMCARDMAN->UnlockCard( pn ); MEMCARDMAN->UnmountCard( pn );