diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index c140d7d9a9..54c5bf8080 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -229,7 +229,8 @@ void GameState::Reset() m_bSideIsJoined[p] = false; FOREACH_MultiPlayer( p ) m_MultiPlayerStatus[p] = MultiPlayerStatus_NotJoined; - MEMCARDMAN->UnlockCards(); + FOREACH_PlayerNumber( pn ) + MEMCARDMAN->UnlockCard( pn ); // m_iCoins = 0; // don't reset coin count! m_MasterPlayerNumber = PLAYER_INVALID; m_bMultiplayer = false; @@ -331,6 +332,12 @@ void GameState::JoinPlayer( PlayerNumber pn ) if( GetNumSidesJoined() == 1 ) BeginGame(); + /* Count each player join as a play. */ + { + Profile* pMachineProfile = PROFILEMAN->GetMachineProfile(); + pMachineProfile->m_iTotalPlays++; + } + // Set the current style to something appropriate for the new number of joined players. if( ALLOW_LATE_JOIN && GAMESTATE->m_pCurStyle != NULL ) { @@ -345,6 +352,8 @@ void GameState::JoinPlayer( PlayerNumber pn ) void GameState::UnjoinPlayer( PlayerNumber pn ) { + PROFILEMAN->UnloadProfile( pn ); + m_bSideIsJoined[pn] = false; m_iPlayerCurrentStageIndexForCurrentCredit[pn] = 0; @@ -399,7 +408,7 @@ int GameState::GetCoinsNeededToJoin() const * * BeginGame() - the first player has joined; the game is starting. * - * PlayersFinalized() - no more players may join (because the style is set) + * PlayersFinalized() - player memory cards are loaded; later joins won't have memory cards this stage * * BeginStage() - gameplay is beginning * @@ -425,30 +434,82 @@ void GameState::BeginGame() // even if attract sounds are set to off. m_iNumTimesThroughAttract = -1; - MEMCARDMAN->UnlockCards(); + FOREACH_PlayerNumber( pn ) + MEMCARDMAN->UnlockCard( pn ); } -void GameState::PlayersFinalized() +void GameState::LoadProfiles() { - // If cards are already locked, this was already called. - if( MEMCARDMAN->GetCardsLocked() ) - return; + /* Unlock any cards that we might want to load. */ + FOREACH_HumanPlayer( pn ) + if( !PROFILEMAN->IsPersistentProfile(pn) ) + MEMCARDMAN->UnlockCard( pn ); - MEMCARDMAN->LockCards(); + MEMCARDMAN->WaitForCheckingToComplete(); + + FOREACH_PlayerNumber( pn ) + MEMCARDMAN->LockCard( pn ); - // apply saved default modifiers if any FOREACH_HumanPlayer( pn ) { + // If a profile is already loaded, this was already called. + if( PROFILEMAN->IsPersistentProfile(pn) ) + continue; + MEMCARDMAN->MountCard( pn ); - PROFILEMAN->LoadFirstAvailableProfile( pn ); // load full profile - MEMCARDMAN->UnmountCard( pn ); LoadCurrentSettingsFromProfile( pn ); + + Profile* pPlayerProfile = PROFILEMAN->GetProfile( pn ); + if( pPlayerProfile ) + pPlayerProfile->m_iTotalPlays++; } } +void GameState::SaveProfiles() +{ + FOREACH_HumanPlayer( pn ) + { + if( !PROFILEMAN->IsPersistentProfile(pn) ) + continue; + + bool bWasMemoryCard = PROFILEMAN->ProfileWasLoadedFromMemoryCard(pn); + if( bWasMemoryCard ) + MEMCARDMAN->MountCard( pn ); + PROFILEMAN->SaveProfile( pn ); + if( bWasMemoryCard ) + MEMCARDMAN->UnmountCard( pn ); + } +} + +bool GameState::HaveProfileToLoad() +{ + FOREACH_HumanPlayer( pn ) + { + /* We won't load this profile if it's already loaded. */ + if( PROFILEMAN->IsPersistentProfile(pn) ) + continue; + + /* If a memory card is inserted, we'l try to load it. */ + if( MEMCARDMAN->CardInserted(pn) ) + return true; + if( !PROFILEMAN->m_sDefaultLocalProfileID[pn].Get().empty() ) + return true; + } + + return false; +} + +bool GameState::HaveProfileToSave() +{ + FOREACH_HumanPlayer( pn ) + if( PROFILEMAN->IsPersistentProfile(pn) ) + return true; + return false; +} + void GameState::EndGame() { LOG->Trace( "GameState::EndGame" ); @@ -463,34 +524,21 @@ void GameState::EndGame() Profile* pMachineProfile = PROFILEMAN->GetMachineProfile(); pMachineProfile->m_iTotalPlaySeconds += iPlaySeconds; - pMachineProfile->m_iTotalPlays++; FOREACH_HumanPlayer( p ) { Profile* pPlayerProfile = PROFILEMAN->GetProfile( p ); if( pPlayerProfile ) - { pPlayerProfile->m_iTotalPlaySeconds += iPlaySeconds; - pPlayerProfile->m_iTotalPlays++; - } } + BOOKKEEPER->WriteToDisk(); + SaveProfiles(); + FOREACH_HumanPlayer( pn ) - { - if( !PROFILEMAN->IsPersistentProfile(pn) ) - continue; - - bool bWasMemoryCard = PROFILEMAN->ProfileWasLoadedFromMemoryCard(pn); - if( bWasMemoryCard ) - MEMCARDMAN->MountCard( pn ); - PROFILEMAN->SaveProfile( pn ); - if( bWasMemoryCard ) - MEMCARDMAN->UnmountCard( pn ); - - PROFILEMAN->UnloadProfile( pn ); - } + UnjoinPlayer( pn ); PROFILEMAN->SaveMachineProfile(); @@ -668,6 +716,7 @@ void GameState::LoadCurrentSettingsFromProfile( PlayerNumber pn ) const Profile *pProfile = PROFILEMAN->GetProfile(pn); + // apply saved default modifiers if any RString sModifiers; if( pProfile->GetDefaultModifiers( m_pCurGame, sModifiers ) ) { diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index 3f4bf8a7ad..4e0a5a5112 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -43,7 +43,10 @@ public: void JoinPlayer( PlayerNumber pn ); void UnjoinPlayer( PlayerNumber pn ); bool JoinInput( PlayerNumber pn ); - void PlayersFinalized(); // called after a style is chosen, which means the number of players is finalized + void LoadProfiles(); + void SaveProfiles(); + bool HaveProfileToLoad(); + bool HaveProfileToSave(); void EndGame(); // called on ScreenGameOver, ScreenMusicScroll, ScreenCredits void LoadCurrentSettingsFromProfile( PlayerNumber pn ); void SaveCurrentSettingsToProfile( PlayerNumber pn ); // called at the beginning of each stage diff --git a/stepmania/src/MemoryCardManager.cpp b/stepmania/src/MemoryCardManager.cpp index a2e82809f9..c6d1704229 100644 --- a/stepmania/src/MemoryCardManager.cpp +++ b/stepmania/src/MemoryCardManager.cpp @@ -270,9 +270,9 @@ MemoryCardManager::MemoryCardManager() g_pWorker = new ThreadedMemoryCardWorker; - m_bCardsLocked = false; FOREACH_PlayerNumber( p ) { + m_bCardLocked[p] = false; m_bMounted[p] = false; m_State[p] = MemoryCardState_NoCard; } @@ -414,7 +414,7 @@ void MemoryCardManager::CheckStateChanges() MemoryCardState state = MemoryCardState_Invalid; RString sError; - if( m_bCardsLocked ) + if( m_bCardLocked[p] ) { if( m_FinalDevice[p].m_State == UsbStorageDevice::STATE_NONE ) { @@ -500,11 +500,8 @@ void MemoryCardManager::CheckStateChanges() SCREENMAN->RefreshCreditsMessages(); } -void MemoryCardManager::LockCards() +void MemoryCardManager::WaitForCheckingToComplete() { - if( m_bCardsLocked ) - return; - g_pWorker->SetTimeout( 5 ); /* If either player's card is in STATE_CHECKING, we need to give it a chance @@ -538,27 +535,36 @@ void MemoryCardManager::LockCards() } g_pWorker->SetTimeout( -1 ); +} + +bool MemoryCardManager::CardInserted( PlayerNumber pn ) +{ + return m_Device[pn].m_State == UsbStorageDevice::STATE_CHECKING || + m_Device[pn].m_State == UsbStorageDevice::STATE_READY; +} + +void MemoryCardManager::LockCard( PlayerNumber pn ) +{ + if( m_bCardLocked[pn] ) + return; /* Set the final state. */ CheckStateChanges(); - FOREACH_PlayerNumber( p ) - { - /* If the card in this player's slot is ready, then use it. If there is - * no card ready when we finalize, clear m_FinalDevice. */ - if( m_Device[p].m_State == UsbStorageDevice::STATE_READY ) - m_FinalDevice[p] = m_Device[p]; - else - m_FinalDevice[p] = UsbStorageDevice(); - } + /* If the card in this player's slot is ready, then use it. If there is + * no card ready when we finalize, clear m_FinalDevice. */ + if( m_Device[pn].m_State == UsbStorageDevice::STATE_READY ) + m_FinalDevice[pn] = m_Device[pn]; + else + m_FinalDevice[pn] = UsbStorageDevice(); /* Set this last, since it changes the behavior of CheckStateChanges. */ - m_bCardsLocked = true; + m_bCardLocked[pn] = true; } -void MemoryCardManager::UnlockCards() +void MemoryCardManager::UnlockCard( PlayerNumber pn ) { - m_bCardsLocked = false; + m_bCardLocked[pn] = false; g_pWorker->SetMountThreadState( ThreadedMemoryCardWorker::detect_and_mount ); diff --git a/stepmania/src/MemoryCardManager.h b/stepmania/src/MemoryCardManager.h index 2301342657..7c988d174f 100644 --- a/stepmania/src/MemoryCardManager.h +++ b/stepmania/src/MemoryCardManager.h @@ -21,8 +21,10 @@ public: MemoryCardState GetCardState( PlayerNumber pn ) const { return m_State[pn]; } RString GetCardError( PlayerNumber pn ) const { return m_sError[pn]; } - void LockCards(); // prevent removing or changing of memory cards - void UnlockCards(); + void WaitForCheckingToComplete(); + bool CardInserted( PlayerNumber pn ); + void LockCard( PlayerNumber pn ); // prevent removing or changing of memory card + void UnlockCard( PlayerNumber pn ); bool MountCard( PlayerNumber pn, int iTimeout = 10 ); bool MountCard( PlayerNumber pn, const UsbStorageDevice &d, int iTimeout = 10 ); void UnmountCard( PlayerNumber pn ); @@ -33,7 +35,7 @@ public: void PauseMountingThread( int iTimeout = 20 ); void UnPauseMountingThread(); - bool GetCardsLocked() const { return m_bCardsLocked; } + bool GetCardLocked( PlayerNumber pn ) const { return m_bCardLocked[pn]; } bool PathIsMemCard( RString sDir ) const; @@ -58,7 +60,7 @@ protected: vector m_vStorageDevices; // all currently connected - bool m_bCardsLocked; + bool m_bCardLocked[NUM_PLAYERS]; bool m_bMounted[NUM_PLAYERS]; // card is currently mounted UsbStorageDevice m_Device[NUM_PLAYERS]; // device in the memory card slot, blank if none diff --git a/stepmania/src/ScreenProfileLoad.cpp b/stepmania/src/ScreenProfileLoad.cpp new file mode 100644 index 0000000000..4b670a06eb --- /dev/null +++ b/stepmania/src/ScreenProfileLoad.cpp @@ -0,0 +1,89 @@ +#include "global.h" +#include "ScreenProfileLoad.h" +#include "GameState.h" +#include "MemoryCardManager.h" +#include "ScreenManager.h" + +REGISTER_SCREEN_CLASS( ScreenProfileLoad ); + +void ScreenProfileLoad::BeginScreen() +{ + m_bHaveProfileToLoad = GAMESTATE->HaveProfileToLoad(); + if( !m_bHaveProfileToLoad ) + { + /* We have nothing to load, so just lock the cards. */ + FOREACH_PlayerNumber( pn ) + MEMCARDMAN->LockCard( pn ); + } + + ScreenWithMenuElements::BeginScreen(); +} + +void ScreenProfileLoad::Input( const InputEventPlus &input ) +{ +} + +void ScreenProfileLoad::Continue() +{ + if( m_bHaveProfileToLoad ) + { + GAMESTATE->LoadProfiles(); + SCREENMAN->ZeroNextUpdate(); + } + + StartTransitioningScreen( SM_GoToNextScreen ); +} + +// lua start +#include "LuaBinding.h" + +class LunaScreenProfileLoad: public Luna +{ +public: + static int Continue( T* p, lua_State *L ) + { + LUA->YieldLua(); + p->Continue(); + LUA->UnyieldLua(); + return 0; + } + static int HaveProfileToLoad( T* p, lua_State *L ) + { + LuaHelpers::Push( L, p->m_bHaveProfileToLoad ); + return 1; + } + + LunaScreenProfileLoad() + { + ADD_METHOD( Continue ); + ADD_METHOD( HaveProfileToLoad ); + } +}; + +LUA_REGISTER_DERIVED_CLASS( ScreenProfileLoad, ScreenWithMenuElements ) +// lua end + +/* + * (c) 2007 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenProfileLoad.h b/stepmania/src/ScreenProfileLoad.h new file mode 100644 index 0000000000..87f39f7668 --- /dev/null +++ b/stepmania/src/ScreenProfileLoad.h @@ -0,0 +1,43 @@ +#ifndef SCREEN_PROFILE_LOAD_H +#define SCREEN_PROFILE_LOAD_H + +#include "ScreenWithMenuElements.h" + +class ScreenProfileLoad: public ScreenWithMenuElements +{ +public: + virtual void BeginScreen(); + virtual void Input( const InputEventPlus &input ); + void Continue(); + + virtual void PushSelf( lua_State *L ); + + bool m_bHaveProfileToLoad; +}; + +#endif + +/* + * (c) 2007 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenProfileSave.cpp b/stepmania/src/ScreenProfileSave.cpp new file mode 100644 index 0000000000..3dd3f3b639 --- /dev/null +++ b/stepmania/src/ScreenProfileSave.cpp @@ -0,0 +1,77 @@ +#include "global.h" +#include "ScreenProfileSave.h" +#include "GameState.h" +#include "ScreenManager.h" + +REGISTER_SCREEN_CLASS( ScreenProfileSave ); + +void ScreenProfileSave::BeginScreen() +{ + ScreenWithMenuElements::BeginScreen(); +} + +void ScreenProfileSave::Input( const InputEventPlus &input ) +{ +} + +void ScreenProfileSave::Continue() +{ + GAMESTATE->SaveProfiles(); + SCREENMAN->ZeroNextUpdate(); + + StartTransitioningScreen( SM_GoToNextScreen ); +} + +// lua start +#include "LuaBinding.h" + +class LunaScreenProfileSave: public Luna +{ +public: + static int Continue( T* p, lua_State *L ) + { + LUA->YieldLua(); + p->Continue(); + LUA->UnyieldLua(); + return 0; + } + static int HaveProfileToSave( T* p, lua_State *L ) + { + LuaHelpers::Push( L, GAMESTATE->HaveProfileToSave() ); + return 1; + } + + LunaScreenProfileSave() + { + ADD_METHOD( Continue ); + ADD_METHOD( HaveProfileToSave ); + } +}; + +LUA_REGISTER_DERIVED_CLASS( ScreenProfileSave, ScreenWithMenuElements ) +// lua end + +/* + * (c) 2007 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenProfileSave.h b/stepmania/src/ScreenProfileSave.h new file mode 100644 index 0000000000..69c73d612e --- /dev/null +++ b/stepmania/src/ScreenProfileSave.h @@ -0,0 +1,41 @@ +#ifndef SCREEN_PROFILE_SAVE_H +#define SCREEN_PROFILE_SAVE_H + +#include "ScreenWithMenuElements.h" + +class ScreenProfileSave: public ScreenWithMenuElements +{ +public: + virtual void BeginScreen(); + virtual void Input( const InputEventPlus &input ); + void Continue(); + + virtual void PushSelf( lua_State *L ); +}; + +#endif + +/* + * (c) 2007 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */