working on explicit profile load/saves: do this in a screen, not implicitly

as part of other operations
separate profile loads/locks for each player
This commit is contained in:
Glenn Maynard
2007-04-17 22:27:25 +00:00
parent 3e5206f810
commit a8a4803ed8
8 changed files with 361 additions and 51 deletions
+77 -28
View File
@@ -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 ) )
{
+4 -1
View File
@@ -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
+24 -18
View File
@@ -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 );
+6 -4
View File
@@ -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<UsbStorageDevice> 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
+89
View File
@@ -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<ScreenProfileLoad>
{
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.
*/
+43
View File
@@ -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.
*/
+77
View File
@@ -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<ScreenProfileSave>
{
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.
*/
+41
View File
@@ -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.
*/