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;