simplify
fix "zero first update" logic
This commit is contained in:
@@ -371,21 +371,6 @@ void ScreenManager::EmptyDeleteQueue()
|
|||||||
TEXTUREMAN->DiagnosticOutput();
|
TEXTUREMAN->DiagnosticOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: Big hack:
|
|
||||||
* All screens must receive at least one update before they draw.
|
|
||||||
* However, no screen should ever receive an update until it's ready
|
|
||||||
* to be drawn; otherwise Gameplay will queue music to start even though
|
|
||||||
* Stage might still be delaying for a while, throwing off timing.
|
|
||||||
*
|
|
||||||
* This is tricky with prepped screens. We can't do an Update(0) in
|
|
||||||
* LoadPreppedScreen, since that'll cause the delete queue to be cleared
|
|
||||||
* while the screen is on the stack, and possibly other odd things.
|
|
||||||
* So, update before we draw, which is also a hack (rendering shouldn't
|
|
||||||
* change state!). Only do this when we have to, so we don't double
|
|
||||||
* the number of updates. */
|
|
||||||
static bool g_TopNeedsNeedsNullUpdate = false;
|
|
||||||
static bool g_SkipRendering = false;
|
|
||||||
|
|
||||||
void ScreenManager::Update( float fDeltaTime )
|
void ScreenManager::Update( float fDeltaTime )
|
||||||
{
|
{
|
||||||
// Only update the topmost screen on the stack.
|
// Only update the topmost screen on the stack.
|
||||||
@@ -402,9 +387,6 @@ void ScreenManager::Update( float fDeltaTime )
|
|||||||
* to load the new screen will come after 4 seconds plus the load time.
|
* to load the new screen will come after 4 seconds plus the load time.
|
||||||
*
|
*
|
||||||
* So, let's just zero the first update for every screen.
|
* So, let's just zero the first update for every screen.
|
||||||
*
|
|
||||||
* XXX: If a new Screen is set during this Update, that new screen is Drawn
|
|
||||||
* before its first Update.
|
|
||||||
*/
|
*/
|
||||||
ASSERT( !m_ScreenStack.empty() || m_DelayedScreen != "" ); // Why play the game if there is nothing showing?
|
ASSERT( !m_ScreenStack.empty() || m_DelayedScreen != "" ); // Why play the game if there is nothing showing?
|
||||||
|
|
||||||
@@ -434,31 +416,20 @@ void ScreenManager::Update( float fDeltaTime )
|
|||||||
TEXTUREMAN->DiagnosticOutput();
|
TEXTUREMAN->DiagnosticOutput();
|
||||||
|
|
||||||
LoadDelayedScreen();
|
LoadDelayedScreen();
|
||||||
|
|
||||||
/* Ack. We can't Update(0), since we want to skip the *next* update
|
|
||||||
* (which is the one that will have all this load time in it). We
|
|
||||||
* can't draw it until we've updated it. Let's simply not render
|
|
||||||
* the next frame, so we'll come around quickly and handle it correctly. */
|
|
||||||
g_SkipRendering = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScreenManager::Draw()
|
void ScreenManager::Draw()
|
||||||
{
|
{
|
||||||
DISPLAY->BeginFrame();
|
/* If it hasn't been updated yet, skip the render. We can't call Update(0), since
|
||||||
|
* that'll confuse the "zero out the next update after loading a screen logic.
|
||||||
if(g_SkipRendering)
|
* If we don't render, don't call BeginFrame or EndFrame. That way, we won't
|
||||||
{
|
* clear the buffer, and we won't wait for vsync. */
|
||||||
/* Leave the frame there (if any). */
|
if( m_ScreenStack.back()->IsFirstUpdate() )
|
||||||
g_SkipRendering = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if(g_TopNeedsNeedsNullUpdate)
|
DISPLAY->BeginFrame();
|
||||||
{
|
|
||||||
g_TopNeedsNeedsNullUpdate = false;
|
|
||||||
m_ScreenStack.back()->Update( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !m_ScreenStack.empty() && !m_ScreenStack.back()->IsTransparent() ) // top screen isn't transparent
|
if( !m_ScreenStack.empty() && !m_ScreenStack.back()->IsTransparent() ) // top screen isn't transparent
|
||||||
m_ScreenStack.back()->Draw();
|
m_ScreenStack.back()->Draw();
|
||||||
@@ -485,7 +456,7 @@ void ScreenManager::Input( const DeviceInput& DeviceI, const InputEventType type
|
|||||||
Screen* ScreenManager::MakeNewScreen( CString sClassName )
|
Screen* ScreenManager::MakeNewScreen( CString sClassName )
|
||||||
{
|
{
|
||||||
/* By default, RageSounds handles the song timer. When we change screens, reset this;
|
/* By default, RageSounds handles the song timer. When we change screens, reset this;
|
||||||
* screens turn this off in their ctor if they handle timers themselves (gameplay, edit). */
|
* screens turn this off in SM_GainFocus if they handle timers themselves (edit). */
|
||||||
SOUND->HandleSongTimer( true );
|
SOUND->HandleSongTimer( true );
|
||||||
|
|
||||||
/* Cleanup song data. This can free up a fair bit of memory, so do it before
|
/* Cleanup song data. This can free up a fair bit of memory, so do it before
|
||||||
@@ -512,11 +483,7 @@ void ScreenManager::PrepNewScreen( CString sClassName )
|
|||||||
void ScreenManager::LoadPreppedScreen()
|
void ScreenManager::LoadPreppedScreen()
|
||||||
{
|
{
|
||||||
ASSERT( m_ScreenBuffered != NULL);
|
ASSERT( m_ScreenBuffered != NULL);
|
||||||
SetNewScreen( m_ScreenBuffered );
|
SetFromNewScreen( m_ScreenBuffered, false );
|
||||||
|
|
||||||
// Need to update the new screen once, or else it will be
|
|
||||||
// drawn before ever being Update()d.
|
|
||||||
g_TopNeedsNeedsNullUpdate = true;
|
|
||||||
|
|
||||||
m_ScreenBuffered = NULL;
|
m_ScreenBuffered = NULL;
|
||||||
}
|
}
|
||||||
@@ -527,20 +494,22 @@ void ScreenManager::DeletePreppedScreen()
|
|||||||
TEXTUREMAN->DeleteCachedTextures();
|
TEXTUREMAN->DeleteCachedTextures();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenManager::SetNewScreen( Screen *pNewScreen )
|
/* Add a screen to m_ScreenStack. If Stack is true, it's added to the stack; otherwise any
|
||||||
|
* current screens are removed. This is the only function that adds to m_ScreenStack. */
|
||||||
|
void ScreenManager::SetFromNewScreen( Screen *pNewScreen, bool Stack )
|
||||||
{
|
{
|
||||||
RefreshCreditsMessages();
|
RefreshCreditsMessages();
|
||||||
THEME->ReloadMetricsIfNecessary();
|
THEME->ReloadMetricsIfNecessary();
|
||||||
|
|
||||||
// move current screen(s) to ScreenToDelete
|
if( !Stack )
|
||||||
m_ScreensToDelete.insert(m_ScreensToDelete.end(), m_ScreenStack.begin(), m_ScreenStack.end());
|
{
|
||||||
m_ScreenStack.clear();
|
// move current screen(s) to ScreenToDelete
|
||||||
|
m_ScreensToDelete.insert(m_ScreensToDelete.end(), m_ScreenStack.begin(), m_ScreenStack.end());
|
||||||
|
m_ScreenStack.clear();
|
||||||
|
}
|
||||||
|
|
||||||
m_ScreenStack.push_back( pNewScreen );
|
m_ScreenStack.push_back( pNewScreen );
|
||||||
|
|
||||||
/* Make sure we always send at least one update before drawing. */
|
|
||||||
pNewScreen->Update( 0 );
|
|
||||||
|
|
||||||
PostMessageToTopScreen( SM_GainFocus, 0 );
|
PostMessageToTopScreen( SM_GainFocus, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,7 +577,8 @@ retry:
|
|||||||
else
|
else
|
||||||
GAMESTATE->m_bIsOnSystemMenu = false;
|
GAMESTATE->m_bIsOnSystemMenu = false;
|
||||||
|
|
||||||
SetNewScreen( pNewScreen );
|
LOG->Trace("... SetFromNewScreen");
|
||||||
|
SetFromNewScreen( pNewScreen, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenManager::AddNewScreenToTop( CString sClassName, ScreenMessage messageSendOnPop )
|
void ScreenManager::AddNewScreenToTop( CString sClassName, ScreenMessage messageSendOnPop )
|
||||||
@@ -619,7 +589,7 @@ void ScreenManager::AddNewScreenToTop( CString sClassName, ScreenMessage message
|
|||||||
m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus );
|
m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus );
|
||||||
|
|
||||||
Screen* pNewScreen = MakeNewScreen(sClassName);
|
Screen* pNewScreen = MakeNewScreen(sClassName);
|
||||||
m_ScreenStack.push_back( pNewScreen );
|
SetFromNewScreen( pNewScreen, true );
|
||||||
m_MessageSendOnPop = messageSendOnPop;
|
m_MessageSendOnPop = messageSendOnPop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,16 +603,22 @@ void ScreenManager::Prompt( ScreenMessage SM_SendWhenDone, CString sText, bool b
|
|||||||
m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus );
|
m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus );
|
||||||
|
|
||||||
// add the new state onto the back of the array
|
// add the new state onto the back of the array
|
||||||
m_ScreenStack.push_back( new ScreenPrompt(SM_SendWhenDone, sText, bYesNo, bDefaultAnswer, OnYes, OnNo, pCallbackData) );
|
Screen *pNewScreen = new ScreenPrompt( sText, bYesNo, bDefaultAnswer, OnYes, OnNo, pCallbackData);
|
||||||
|
SetFromNewScreen( pNewScreen, true );
|
||||||
|
|
||||||
|
m_MessageSendOnPop = SM_SendWhenDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenManager::TextEntry( ScreenMessage SM_SendWhenDone, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer), void(*OnCanel)() )
|
void ScreenManager::TextEntry( ScreenMessage SM_SendWhenDone, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer), void(*OnCancel)() )
|
||||||
{
|
{
|
||||||
if( m_ScreenStack.size() )
|
if( m_ScreenStack.size() )
|
||||||
m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus );
|
m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus );
|
||||||
|
|
||||||
// add the new state onto the back of the array
|
// add the new state onto the back of the array
|
||||||
m_ScreenStack.push_back( new ScreenTextEntry("ScreenTextEntry", SM_SendWhenDone, sQuestion, sInitialAnswer, OnOK, OnCanel) );
|
Screen *pNewScreen = new ScreenTextEntry( "ScreenTextEntry", sQuestion, sInitialAnswer, OnOK, OnCancel );
|
||||||
|
SetFromNewScreen( pNewScreen, true );
|
||||||
|
|
||||||
|
m_MessageSendOnPop = SM_SendWhenDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenManager::MiniMenu( Menu* pDef, ScreenMessage SM_SendOnOK, ScreenMessage SM_SendOnCancel )
|
void ScreenManager::MiniMenu( Menu* pDef, ScreenMessage SM_SendOnOK, ScreenMessage SM_SendOnCancel )
|
||||||
@@ -651,7 +627,8 @@ void ScreenManager::MiniMenu( Menu* pDef, ScreenMessage SM_SendOnOK, ScreenMessa
|
|||||||
m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus );
|
m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus );
|
||||||
|
|
||||||
// add the new state onto the back of the array
|
// add the new state onto the back of the array
|
||||||
m_ScreenStack.push_back( new ScreenMiniMenu(pDef, SM_SendOnOK, SM_SendOnCancel) );
|
Screen *pNewScreen = new ScreenMiniMenu( pDef, SM_SendOnOK, SM_SendOnCancel );
|
||||||
|
SetFromNewScreen( pNewScreen, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenManager::PopTopScreen( ScreenMessage SM )
|
void ScreenManager::PopTopScreen( ScreenMessage SM )
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ private:
|
|||||||
ScreenSystemLayer *m_SystemLayer;
|
ScreenSystemLayer *m_SystemLayer;
|
||||||
|
|
||||||
Screen* MakeNewScreen( CString sClassName );
|
Screen* MakeNewScreen( CString sClassName );
|
||||||
void SetNewScreen( Screen *pNewScreen );
|
void SetFromNewScreen( Screen *pNewScreen, bool Stack );
|
||||||
CString m_DelayedScreen;
|
CString m_DelayedScreen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,11 @@ const float PROMPT_Y = CENTER_Y + 120;
|
|||||||
|
|
||||||
bool ScreenPrompt::s_bLastAnswer = false;
|
bool ScreenPrompt::s_bLastAnswer = false;
|
||||||
|
|
||||||
ScreenPrompt::ScreenPrompt( ScreenMessage SM_SendWhenDone, CString sText, bool bYesNoPrompt, bool bDefaultAnswer, void(*OnYes)(void*), void(*OnNo)(void*), void* pCallbackData ) :
|
ScreenPrompt::ScreenPrompt( CString sText, bool bYesNoPrompt, bool bDefaultAnswer, void(*OnYes)(void*), void(*OnNo)(void*), void* pCallbackData ) :
|
||||||
Screen("ScreenPrompt")
|
Screen("ScreenPrompt")
|
||||||
{
|
{
|
||||||
m_bIsTransparent = true; // draw screens below us
|
m_bIsTransparent = true; // draw screens below us
|
||||||
|
|
||||||
m_SMSendWhenDone = SM_SendWhenDone;
|
|
||||||
m_bYesNoPrompt = bYesNoPrompt;
|
m_bYesNoPrompt = bYesNoPrompt;
|
||||||
m_bAnswer = bDefaultAnswer;
|
m_bAnswer = bDefaultAnswer;
|
||||||
m_pOnYes = OnYes;
|
m_pOnYes = OnYes;
|
||||||
@@ -128,7 +127,7 @@ void ScreenPrompt::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
case SM_DoneOpeningWipingLeft:
|
case SM_DoneOpeningWipingLeft:
|
||||||
break;
|
break;
|
||||||
case SM_DoneOpeningWipingRight:
|
case SM_DoneOpeningWipingRight:
|
||||||
SCREENMAN->PopTopScreen( m_SMSendWhenDone );
|
SCREENMAN->PopTopScreen();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class ScreenPrompt : public Screen
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScreenPrompt( CString sName );
|
ScreenPrompt( CString sName );
|
||||||
ScreenPrompt( ScreenMessage SM_SendWhenDone, CString sText, bool bYesNoPrompt=false, bool bDefaultAnswer = false, void(*OnYes)(void*) = NULL, void(*OnNo)(void*) = NULL, void* pCallbackData = NULL );
|
ScreenPrompt( CString sText, bool bYesNoPrompt=false, bool bDefaultAnswer = false, void(*OnYes)(void*) = NULL, void(*OnNo)(void*) = NULL, void* pCallbackData = NULL );
|
||||||
|
|
||||||
virtual void Update( float fDeltaTime );
|
virtual void Update( float fDeltaTime );
|
||||||
virtual void DrawPrimitives();
|
virtual void DrawPrimitives();
|
||||||
|
|||||||
@@ -40,12 +40,11 @@ bool ScreenTextEntry::s_bCancelledLast = false;
|
|||||||
* Handle UTF-8. Right now, we need to at least be able to backspace
|
* Handle UTF-8. Right now, we need to at least be able to backspace
|
||||||
* a whole UTF-8 character. Better would be to operate in longchars.
|
* a whole UTF-8 character. Better would be to operate in longchars.
|
||||||
*/
|
*/
|
||||||
ScreenTextEntry::ScreenTextEntry( CString sClassName, ScreenMessage SM_SendWhenDone, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer), void(*OnCancel)() ) :
|
ScreenTextEntry::ScreenTextEntry( CString sClassName, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer), void(*OnCancel)() ) :
|
||||||
Screen( sClassName )
|
Screen( sClassName )
|
||||||
{
|
{
|
||||||
m_bIsTransparent = true; // draw screens below us
|
m_bIsTransparent = true; // draw screens below us
|
||||||
|
|
||||||
m_SMSendWhenDone = SM_SendWhenDone;
|
|
||||||
m_pOnOK = OnOK;
|
m_pOnOK = OnOK;
|
||||||
m_pOnCancel = OnCancel;
|
m_pOnCancel = OnCancel;
|
||||||
|
|
||||||
@@ -179,7 +178,7 @@ void ScreenTextEntry::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
case SM_DoneOpeningWipingLeft:
|
case SM_DoneOpeningWipingLeft:
|
||||||
break;
|
break;
|
||||||
case SM_DoneOpeningWipingRight:
|
case SM_DoneOpeningWipingRight:
|
||||||
SCREENMAN->PopTopScreen( m_SMSendWhenDone );
|
SCREENMAN->PopTopScreen();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
class ScreenTextEntry : public Screen
|
class ScreenTextEntry : public Screen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScreenTextEntry( CString sName, ScreenMessage SM_SendWhenDone, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer) = NULL, void(*OnCanel)() = NULL );
|
ScreenTextEntry( CString sName, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer) = NULL, void(*OnCanel)() = NULL );
|
||||||
|
|
||||||
virtual void Update( float fDeltaTime );
|
virtual void Update( float fDeltaTime );
|
||||||
virtual void DrawPrimitives();
|
virtual void DrawPrimitives();
|
||||||
@@ -45,7 +45,6 @@ protected:
|
|||||||
Quad m_rectAnswerBox;
|
Quad m_rectAnswerBox;
|
||||||
wstring m_sAnswer;
|
wstring m_sAnswer;
|
||||||
BitmapText m_textAnswer;
|
BitmapText m_textAnswer;
|
||||||
ScreenMessage m_SMSendWhenDone;
|
|
||||||
void(*m_pOnOK)( CString sAnswer );
|
void(*m_pOnOK)( CString sAnswer );
|
||||||
void(*m_pOnCancel)();
|
void(*m_pOnCancel)();
|
||||||
bool m_bCancelled;
|
bool m_bCancelled;
|
||||||
|
|||||||
Reference in New Issue
Block a user