Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Generals/Code/GameEngine/Include/GameClient/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class Display : public SubsystemInterface
virtual void setCinematicTextFrames( Int frames ) { m_cinematicTextFrames = frames; }

virtual Real getAverageFPS( void ) = 0; ///< returns the average FPS.
virtual Real getCurrentFPS( void ) = 0; ///< returns the current FPS.
virtual Int getLastFrameDrawCalls( void ) = 0; ///< returns the number of draw calls issued in the previous frame

protected:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,13 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
// scroll the view
if (m_isScrolling)
{

// TheSuperHackers @bugfix Mauller 07/06/2025 Adjust the viewport scrolling so it is independent of GameClient FPS
// The scaling is based on the current logic rate, this provides a consistent scroll speed at all GameClient FPS
// This also fixes scrolling within replays when fast forwarding due to the uncapped FPS
// When the FPS is in excess of the expected frame rate, the ratio will reduce the offset of the cameras movement
const Real logicToFpsRatio = TheGlobalData->m_framesPerSecondLimit / TheDisplay->getCurrentFPS();

switch (m_scrollType)
{
case SCROLL_RMB:
Expand All @@ -416,8 +423,8 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
m_anchor.y = m_currentPos.y - maxY;
}

offset.x = TheGlobalData->m_horizontalScrollSpeedFactor * (m_currentPos.x - m_anchor.x);
offset.y = TheGlobalData->m_verticalScrollSpeedFactor * (m_currentPos.y - m_anchor.y);
offset.x = TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * (m_currentPos.x - m_anchor.x);
offset.y = TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * (m_currentPos.y - m_anchor.y);
Coord2D vec;
vec.x = offset.x;
vec.y = offset.y;
Expand All @@ -431,19 +438,19 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
{
if (scrollDir[DIR_UP])
{
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (scrollDir[DIR_DOWN])
{
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (scrollDir[DIR_LEFT])
{
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (scrollDir[DIR_RIGHT])
{
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
}
break;
Expand All @@ -453,19 +460,19 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
UnsignedInt width = TheDisplay->getWidth();
if (m_currentPos.y < edgeScrollSize)
{
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (m_currentPos.y >= height-edgeScrollSize)
{
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (m_currentPos.x < edgeScrollSize)
{
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (m_currentPos.x >= width-edgeScrollSize)
{
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ class W3DDisplay : public Display
static W3DAssetManager *m_assetManager; ///< W3D asset manager

void drawFPSStats( void ); ///< draw the fps on the screen
virtual Real getAverageFPS( void ); ///< return the average FPS.
virtual Real getAverageFPS( void ); ///< return the average FPS.
virtual Real getCurrentFPS( void ); ///< return the current FPS.
virtual Int getLastFrameDrawCalls( void ); ///< returns the number of draw calls issued in the previous frame

protected:
Expand All @@ -166,6 +167,7 @@ class W3DDisplay : public Display
IRegion2D m_clipRegion; ///< the clipping region for images
Bool m_isClippedEnabled; ///<used by 2D drawing operations to define clip re
Real m_averageFPS; ///<average fps over the last 30 frames.
Real m_currentFPS; ///<current fps value.
#if defined(RTS_DEBUG)
Int64 m_timerAtCumuFPSStart;
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -873,8 +873,8 @@ void W3DDisplay::updateAverageFPS(void)
if (historyOffset >= FPS_HISTORY_SIZE)
historyOffset = 0;

double currentFPS = 1.0/elapsedSeconds;
fpsHistory[historyOffset++] = currentFPS;
m_currentFPS = 1.0/elapsedSeconds;
fpsHistory[historyOffset++] = m_currentFPS;
numSamples++;
if (numSamples > FPS_HISTORY_SIZE)
numSamples = FPS_HISTORY_SIZE;
Expand Down Expand Up @@ -1600,6 +1600,11 @@ Real W3DDisplay::getAverageFPS()
return m_averageFPS;
}

Real W3DDisplay::getCurrentFPS()
{
return m_currentFPS;
}

Int W3DDisplay::getLastFrameDrawCalls()
{
return Debug_Statistics::Get_Draw_Calls();
Expand Down
1 change: 1 addition & 0 deletions Generals/Code/Tools/GUIEdit/Include/GUIEditDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class GUIEditDisplay : public Display
#endif

virtual Real getAverageFPS(void) { return 0; }
virtual Real getCurrentFPS(void) { return 0; }
virtual Int getLastFrameDrawCalls( void ) { return 0; }

protected:
Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Include/GameClient/Display.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ class Display : public SubsystemInterface
virtual void setCinematicTextFrames( Int frames ) { m_cinematicTextFrames = frames; }

virtual Real getAverageFPS( void ) = 0; ///< returns the average FPS.
virtual Real getCurrentFPS( void ) = 0; ///< returns the current FPS.
virtual Int getLastFrameDrawCalls( void ) = 0; ///< returns the number of draw calls issued in the previous frame

protected:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,13 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
// scroll the view
if (m_isScrolling)
{

// TheSuperHackers @bugfix Mauller 07/06/2025 Adjust the viewport scrolling so it is independent of GameClient FPS
// The scaling is based on the current logic rate, this provides a consistent scroll speed at all GameClient FPS
// This also fixes scrolling within replays when fast forwarding due to the uncapped FPS
// When the FPS is in excess of the expected frame rate, the ratio will reduce the offset of the cameras movement
const Real logicToFpsRatio = TheGlobalData->m_framesPerSecondLimit / TheDisplay->getCurrentFPS();

switch (m_scrollType)
{
case SCROLL_RMB:
Expand All @@ -415,8 +422,8 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
m_anchor.y = m_currentPos.y - maxY;
}

offset.x = TheGlobalData->m_horizontalScrollSpeedFactor * (m_currentPos.x - m_anchor.x);
offset.y = TheGlobalData->m_verticalScrollSpeedFactor * (m_currentPos.y - m_anchor.y);
offset.x = TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * (m_currentPos.x - m_anchor.x);
offset.y = TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * (m_currentPos.y - m_anchor.y);
Coord2D vec;
vec.x = offset.x;
vec.y = offset.y;
Expand All @@ -430,19 +437,19 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
{
if (scrollDir[DIR_UP])
{
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (scrollDir[DIR_DOWN])
{
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (scrollDir[DIR_LEFT])
{
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (scrollDir[DIR_RIGHT])
{
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
}
break;
Expand All @@ -452,19 +459,19 @@ GameMessageDisposition LookAtTranslator::translateGameMessage(const GameMessage
UnsignedInt width = TheDisplay->getWidth();
if (m_currentPos.y < edgeScrollSize)
{
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.y -= TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (m_currentPos.y >= height-edgeScrollSize)
{
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.y += TheGlobalData->m_verticalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (m_currentPos.x < edgeScrollSize)
{
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.x -= TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
if (m_currentPos.x >= width-edgeScrollSize)
{
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
offset.x += TheGlobalData->m_horizontalScrollSpeedFactor * logicToFpsRatio * SCROLL_AMT * TheGlobalData->m_keyboardScrollFactor;
}
}
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ class W3DDisplay : public Display
static W3DAssetManager *m_assetManager; ///< W3D asset manager

void drawFPSStats( void ); ///< draw the fps on the screen
virtual Real getAverageFPS( void ); ///< return the average FPS.
virtual Real getAverageFPS( void ); ///< return the average FPS.
virtual Real getCurrentFPS( void ); ///< return the current FPS.
virtual Int getLastFrameDrawCalls( void ); ///< returns the number of draw calls issued in the previous frame

protected:
Expand All @@ -167,6 +168,7 @@ class W3DDisplay : public Display
IRegion2D m_clipRegion; ///< the clipping region for images
Bool m_isClippedEnabled; ///<used by 2D drawing operations to define clip re
Real m_averageFPS; ///<average fps over the last 30 frames.
Real m_currentFPS; ///<current fps value.
#if defined(RTS_DEBUG)
Int64 m_timerAtCumuFPSStart;
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -923,8 +923,8 @@ void W3DDisplay::updateAverageFPS(void)
if (historyOffset >= FPS_HISTORY_SIZE)
historyOffset = 0;

double currentFPS = 1.0/elapsedSeconds;
fpsHistory[historyOffset++] = currentFPS;
m_currentFPS = 1.0/elapsedSeconds;
fpsHistory[historyOffset++] = m_currentFPS;
numSamples++;
if (numSamples > FPS_HISTORY_SIZE)
numSamples = FPS_HISTORY_SIZE;
Expand Down Expand Up @@ -1671,6 +1671,11 @@ Real W3DDisplay::getAverageFPS()
return m_averageFPS;
}

Real W3DDisplay::getCurrentFPS()
{
return m_currentFPS;
}

Int W3DDisplay::getLastFrameDrawCalls()
{
return Debug_Statistics::Get_Draw_Calls();
Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/Tools/GUIEdit/Include/GUIEditDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class GUIEditDisplay : public Display
#endif

virtual Real getAverageFPS(void) { return 0; }
virtual Real getCurrentFPS(void) { return 0; }
virtual Int getLastFrameDrawCalls( void ) { return 0; }

protected:
Expand Down
Loading