diff --git a/stepmania/src/ScreenManager.cpp b/stepmania/src/ScreenManager.cpp index 457c34c393..aaed403879 100644 --- a/stepmania/src/ScreenManager.cpp +++ b/stepmania/src/ScreenManager.cpp @@ -17,6 +17,7 @@ #include "RageLog.h" #include "GameState.h" #include "RageException.h" +#include "DXUtil.h" ScreenManager* SCREENMAN = NULL; // global and accessable from anywhere in our program @@ -48,6 +49,8 @@ float CREDITS_Y( int p ) { ScreenManager::ScreenManager() { + m_ScreenBuffered = NULL; + m_textStats.LoadFromFont( THEME->GetPathTo("Fonts","normal") ); m_textStats.SetXY( STATS_X, STATS_Y ); m_textStats.SetHorizAlign( Actor::align_right ); @@ -83,6 +86,7 @@ ScreenManager::~ScreenManager() // delete current states for( int i=0; iFirstUpdate()) + continue; + m_ScreenStack[i]->Update( fDeltaTime ); + } } @@ -218,17 +239,20 @@ Screen* ScreenManager::MakeNewScreen( CString sClassName ) throw RageException( "Invalid Screen class name '%s'", sClassName ); } -void ScreenManager::SetNewScreen( CString sClassName ) +void ScreenManager::PrepNewScreen( CString sClassName ) { - /* Explicitely flush the directory cache each time we load a new screen. - * Perhaps we should only do this in debug? */ - FlushDirCache(); - - // It makes sense that ScreenManager should allocate memory for a new screen since it - // deletes it later on. This also convention will reduce includes because screens won't - // have to include each other's headers of other screens. - Screen* pNewScreen = MakeNewScreen(sClassName); + if(!sClassName.GetLength()) { + ASSERT( m_ScreenBuffered != NULL); + SetNewScreen( m_ScreenBuffered ); + m_ScreenBuffered = NULL; + } else { + ASSERT(m_ScreenBuffered == NULL); + m_ScreenBuffered = MakeNewScreen(sClassName); + } +} +void ScreenManager::SetNewScreen( Screen *pNewScreen ) +{ // move current screen to ScreenToDelete RefreshCreditsMessages(); m_ScreensToDelete.Copy( m_ScreenStack ); @@ -237,6 +261,23 @@ void ScreenManager::SetNewScreen( CString sClassName ) m_ScreenStack.Add( pNewScreen ); } +void ScreenManager::SetNewScreen( CString sClassName ) +{ + /* If we prepped a screen but didn't use it, nuke it. */ + SAFE_DELETE( m_ScreenBuffered ); + /* Explicitely flush the directory cache each time we load a new screen. + * Perhaps we should only do this in debug? */ + FlushDirCache(); + + float f = DXUtil_Timer(TIMER_GETAPPTIME); + // It makes sense that ScreenManager should allocate memory for a new screen since it + // deletes it later on. This also convention will reduce includes because screens won't + // have to include each other's headers of other screens. + Screen* pNewScreen = MakeNewScreen(sClassName); +LOG->Trace( "Loaded %s in %f", sClassName, DXUtil_Timer(TIMER_GETAPPTIME)-f); + SetNewScreen( pNewScreen ); +} + void ScreenManager::Prompt( ScreenMessage SM_SendWhenDone, CString sText, bool bYesNo, bool bDefaultAnswer, void(*OnYes)(), void(*OnNo)() ) { FlushDirCache(); diff --git a/stepmania/src/ScreenManager.h b/stepmania/src/ScreenManager.h index 59f34b5c62..2505c53abc 100644 --- a/stepmania/src/ScreenManager.h +++ b/stepmania/src/ScreenManager.h @@ -32,6 +32,7 @@ public: void Draw(); void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + void PrepNewScreen( CString sClassName ); void SetNewScreen( CString sClassName ); void Prompt( ScreenMessage SM_SendWhenDone, CString sText, bool bYesNo = false, bool bDefaultAnswer = false, void(*OnYes)() = NULL, void(*OnNo)() = NULL ); void TextEntry( ScreenMessage SM_SendWhenDone, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer) = NULL, void(*OnCanel)() = NULL ); @@ -45,6 +46,7 @@ public: private: CArray m_ScreenStack; CArray m_ScreensToDelete; + Screen *m_ScreenBuffered; BitmapText m_textStats; BitmapText m_textSystemMessage; @@ -52,6 +54,7 @@ private: Screen* MakeNewScreen( CString sClassName ); void EmptyDeleteQueue(); + void SetNewScreen( Screen *pNewScreen ); };