diff --git a/Core/GameEngine/Include/GameClient/GameWindowTransitions.h b/Core/GameEngine/Include/GameClient/GameWindowTransitions.h index a95e4c3603d..5812db830c0 100644 --- a/Core/GameEngine/Include/GameClient/GameWindowTransitions.h +++ b/Core/GameEngine/Include/GameClient/GameWindowTransitions.h @@ -647,7 +647,7 @@ class TransitionGroup typedef std::list TransitionWindowList; TransitionWindowList m_transitionWindowList; Int m_directionMultiplier; - Int m_currentFrame; ///< maintain how long we've spent on this transition; + Real m_currentFrame; ///< maintain how long we've spent on this transition (in 30fps-equivalent frames); AsciiString m_name; }; diff --git a/Core/GameEngine/Source/GameClient/GUI/GameWindowTransitions.cpp b/Core/GameEngine/Source/GameClient/GUI/GameWindowTransitions.cpp index cd2205a44a2..6e424bd59a4 100644 --- a/Core/GameEngine/Source/GameClient/GUI/GameWindowTransitions.cpp +++ b/Core/GameEngine/Source/GameClient/GUI/GameWindowTransitions.cpp @@ -55,6 +55,7 @@ #include "GameClient/GameWindowTransitions.h" #include "GameClient/GameWindow.h" #include "GameClient/GameWindowManager.h" +#include "Common/FramePacer.h" //----------------------------------------------------------------------------- // DEFINES //////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- @@ -239,7 +240,7 @@ Int TransitionWindow::getTotalFrames( void ) //----------------------------------------------------------------------------- TransitionGroup::TransitionGroup( void ) { - m_currentFrame = 0; + m_currentFrame = 0.0f; m_fireOnce = FALSE; } @@ -256,7 +257,7 @@ TransitionGroup::~TransitionGroup( void ) void TransitionGroup::init( void ) { - m_currentFrame = 0; + m_currentFrame = 0.0f; m_directionMultiplier = 1; TransitionWindowList::iterator it = m_transitionWindowList.begin(); while (it != m_transitionWindowList.end()) @@ -270,13 +271,34 @@ void TransitionGroup::init( void ) void TransitionGroup::update( void ) { - m_currentFrame += m_directionMultiplier; // we go forward or backwards depending. - TransitionWindowList::iterator it = m_transitionWindowList.begin(); - while (it != m_transitionWindowList.end()) + // TheSuperHackers @tweak bobtista GUI transition timing is now decoupled from the render update. + // Step every integer frame between the old and new accumulator value so discrete-state-machine + // transitions cannot skip a state when the render frame rate dips below the base rate. + const Real timeScale = TheFramePacer->getBaseOverUpdateFpsRatio(); + const Int prevFrame = (Int)m_currentFrame; + m_currentFrame += m_directionMultiplier * timeScale; + const Int newFrame = (Int)m_currentFrame; + + if( newFrame == prevFrame ) { - TransitionWindow *tWin = *it; - tWin->update(m_currentFrame); - it++; + return; + } + + const Int step = (newFrame > prevFrame) ? 1 : -1; + for( Int frame = prevFrame + step; frame != newFrame + step; frame += step ) + { + TransitionWindowList::iterator it = m_transitionWindowList.begin(); + while (it != m_transitionWindowList.end()) + { + TransitionWindow *tWin = *it; + tWin->update(frame); + it++; + } + + if( isFinished() ) + { + break; + } } } @@ -315,7 +337,7 @@ void TransitionGroup::reverse( void ) tWin->reverse(totalFrames); it++; } - m_currentFrame = totalFrames; + m_currentFrame = (Real)totalFrames; // m_currentFrame ++; } diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 4a90702f645..6d5cdeb2c02 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5504,6 +5504,9 @@ static const UnsignedInt FRAMES_BEFORE_EXPIRE_TO_FADE = LOGICFRAMES_PER_SECOND * // ------------------------------------------------------------------------------------------------ void InGameUI::updateAndDrawWorldAnimations( void ) { + // TheSuperHackers @tweak bobtista World animation Z-rise is now decoupled from the render update. + const Real zRiseTimeScale = TheFramePacer->getActualLogicTimeScaleOverFpsRatio(); + // go through all animations for( WorldAnimationListIterator it = m_worldAnimationList.begin(); it != m_worldAnimationList.end(); /*empty*/ ) @@ -5535,7 +5538,9 @@ void InGameUI::updateAndDrawWorldAnimations( void ) // update the Z value if( wad->m_zRisePerSecond ) - wad->m_worldPos.z += wad->m_zRisePerSecond / LOGICFRAMES_PER_SECOND; + { + wad->m_worldPos.z += wad->m_zRisePerSecond / LOGICFRAMES_PER_SECOND * zRiseTimeScale; + } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index 4cc38ed6569..2e2ee9ab69a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -5677,6 +5677,9 @@ static const UnsignedInt FRAMES_BEFORE_EXPIRE_TO_FADE = LOGICFRAMES_PER_SECOND * // ------------------------------------------------------------------------------------------------ void InGameUI::updateAndDrawWorldAnimations( void ) { + // TheSuperHackers @tweak bobtista World animation Z-rise is now decoupled from the render update. + const Real zRiseTimeScale = TheFramePacer->getActualLogicTimeScaleOverFpsRatio(); + // go through all animations for( WorldAnimationListIterator it = m_worldAnimationList.begin(); it != m_worldAnimationList.end(); /*empty*/ ) @@ -5708,7 +5711,9 @@ void InGameUI::updateAndDrawWorldAnimations( void ) // update the Z value if( wad->m_zRisePerSecond ) - wad->m_worldPos.z += wad->m_zRisePerSecond / LOGICFRAMES_PER_SECOND; + { + wad->m_worldPos.z += wad->m_zRisePerSecond / LOGICFRAMES_PER_SECOND * zRiseTimeScale; + } }