From 4bcf9fcbfd4c19567591b98e350d57dc8372ed3d Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Tue, 26 Jul 2005 03:08:03 +0000 Subject: [PATCH] Calling SetNewScreen when not the top screen on the stack only replaces the top screen. This allows a screen to push a helper screen, which can then enter an entirely separate set of helper screens before one pops back. (For example, a screen could push ScreenServiceOptions to enter the options menu, which then replaces itself with the various options menus, and finally pops back to the original screen when the player backs out entirely.) (Some support is still missing to allow non-special-case use of this; coming soon ...) However, in rare cases we want to kill all screens on the stack, regardless of how many there are (operator menu). Fix that case. --- stepmania/src/ScreenManager.cpp | 22 ++++++++++++++++++++-- stepmania/src/ScreenManager.h | 3 ++- stepmania/src/StepMania.cpp | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/stepmania/src/ScreenManager.cpp b/stepmania/src/ScreenManager.cpp index 37250b2175..e33a6629df 100644 --- a/stepmania/src/ScreenManager.cpp +++ b/stepmania/src/ScreenManager.cpp @@ -280,7 +280,7 @@ static bool g_bIsConcurrentlyLoading = false; /* Pop the top screen off the stack, sending SM_LoseFocus messages and * returning the message the popped screen wants sent to the new top * screen. Does not send SM_GainFocus. */ -ScreenMessage ScreenManager::PopTopScreenInternal() +ScreenMessage ScreenManager::PopTopScreenInternal( bool bSendLoseFocus ) { if( g_ScreenStack.empty() ) return SM_None; @@ -288,7 +288,8 @@ ScreenMessage ScreenManager::PopTopScreenInternal() LoadedScreen ls = g_ScreenStack.back(); g_ScreenStack.erase( g_ScreenStack.end()-1, g_ScreenStack.end() ); - ls.m_pScreen->HandleScreenMessage( SM_LoseFocus ); + if( bSendLoseFocus ) + ls.m_pScreen->HandleScreenMessage( SM_LoseFocus ); if( g_setPersistantScreens.find(ls.m_pScreen->GetName()) != g_setPersistantScreens.end() ) { @@ -698,6 +699,23 @@ void ScreenManager::PopTopScreen( ScreenMessage SM ) m_PopTopScreen = SM; } +/* Clear the screen stack; only used before major, unusual state changes, + * such as resetting the game or jumping to the service menu. Don't call + * from inside a screen. */ +void ScreenManager::PopAllScreens() +{ + if( g_ScreenStack.empty() ) + return; + + /* Make sure only the top screen receives LoseFocus. */ + bool bFirst = true; + while( !g_ScreenStack.empty() ) + { + PopTopScreenInternal( bFirst ); + bFirst = false; + } +} + void ScreenManager::PostMessageToTopScreen( ScreenMessage SM, float fDelay ) { Screen* pTopScreen = GetTopScreen(); diff --git a/stepmania/src/ScreenManager.h b/stepmania/src/ScreenManager.h index e5aba262e7..6957b582e1 100644 --- a/stepmania/src/ScreenManager.h +++ b/stepmania/src/ScreenManager.h @@ -38,6 +38,7 @@ public: bool IsConcurrentlyLoading() const; void PushScreen( Screen *pNewScreen, bool bDeleteWhenDone=false, ScreenMessage SendOnPop=SM_None ); void PopTopScreen( ScreenMessage SM ); + void PopAllScreens(); Screen* MakeNewScreen( const CString &sName ); Screen *GetTopScreen(); @@ -81,7 +82,7 @@ private: bool m_bZeroNextUpdate; void LoadDelayedScreen(); - ScreenMessage PopTopScreenInternal(); + ScreenMessage PopTopScreenInternal( bool bSendLoseFocus = true ); // Keep these sounds always loaded, because they could be // played at any time. We want to eliminate SOUND->PlayOnce diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index e6e0037030..9f4e45591d 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -1303,6 +1303,7 @@ bool HandleGlobalInputs( DeviceInput DeviceI, InputEventType type, GameInput Gam { SCREENMAN->SystemMessage( "Service switch pressed" ); GAMESTATE->Reset(); + SCREENMAN->PopAllScreens(); SCREENMAN->SetNewScreen( "ScreenOptionsService" ); } return true;