Skip to content
Open
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
2 changes: 1 addition & 1 deletion Generals/Code/GameEngine/Include/GameClient/Drawable.h
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ class Drawable : public Thing,
FADING_OUT
};
FadingMode m_fadeMode;
UnsignedInt m_timeElapsedFade; ///< for how many frames have i been fading
Real m_timeElapsedFade; ///< for how long have i been fading (in 30fps-equivalent frames)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 30fps-equivalent frames comment turns wrong when LOGICFRAMES_PER_SECOND is changed.

Corrected comment:

for how many logic frames - incl. fractional ones - have i been fading

UnsignedInt m_timeToFade; ///< how slowly am I fading

UnsignedInt m_shroudClearFrame; ///< Last frame the local player saw this drawable "OBJECTSHROUD_CLEAR"
Expand Down
26 changes: 22 additions & 4 deletions Generals/Code/GameEngine/Source/GameClient/Drawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1147,10 +1147,14 @@ void Drawable::updateDrawable()
Real numer = (m_fadeMode == FADING_IN) ? (m_timeElapsedFade) : (m_timeToFade-m_timeElapsedFade);

setDrawableOpacity(numer/(Real)m_timeToFade);
++m_timeElapsedFade;
// TheSuperHackers @bugfix bobtista 15/09/2026 Decouple Drawable fade timing from render updates.
m_timeElapsedFade += TheFramePacer->getActualLogicTimeScaleOverFpsRatio();

if (m_timeElapsedFade > m_timeToFade)
{
setDrawableOpacity(m_fadeMode == FADING_IN ? 1.0f : 0.0f);
m_fadeMode = FADING_NONE;
}
}
}

Expand All @@ -1165,7 +1169,8 @@ void Drawable::updateDrawable()
{
//LERP
(*dm)->setTerrainDecalOpacity(m_decalOpacity);
m_decalOpacity += m_decalOpacityFadeRate;
// TheSuperHackers @bugfix bobtista 15/09/2026 Decouple decal opacity fade timing from render updates.
m_decalOpacity += m_decalOpacityFadeRate * TheFramePacer->getActualLogicTimeScaleOverFpsRatio();
}
//---------------

Expand Down Expand Up @@ -4845,6 +4850,7 @@ void Drawable::xferDrawableModules( Xfer *xfer )
* 6: Added m_ambientSoundEnabledFromScript flag (Added in Zero Hour)
* 7: Save the customize ambient sound info (Added in Zero Hour)
* 8: TheSuperHackers @bugfix Removed m_prevTintStatus because loading its value is unnecessary and undesirable
* 9: TheSuperHackers @info Preserve fractional fade progress in non-retail saves
*/
// ------------------------------------------------------------------------------------------------
void Drawable::xfer( Xfer *xfer )
Expand All @@ -4856,7 +4862,7 @@ void Drawable::xfer( Xfer *xfer )
#elif RETAIL_COMPATIBLE_XFER_SAVE
const XferVersion currentVersion = 7;
#else
const XferVersion currentVersion = 8;
const XferVersion currentVersion = 9;
#endif
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );
Expand Down Expand Up @@ -5030,7 +5036,19 @@ void Drawable::xfer( Xfer *xfer )
xfer->xferUser( &m_fadeMode, sizeof( FadingMode ) );

// time elapsed fade
xfer->xferUnsignedInt( &m_timeElapsedFade );
if (version >= 9)
{
xfer->xferReal( &m_timeElapsedFade );
}
else
{
UnsignedInt timeElapsedFadeFrames = static_cast<UnsignedInt>(m_timeElapsedFade);
xfer->xferUnsignedInt( &timeElapsedFadeFrames );
if (xfer->getXferMode() == XFER_LOAD)
{
m_timeElapsedFade = static_cast<Real>(timeElapsedFadeFrames);
}
}

// time to fade
xfer->xferUnsignedInt( &m_timeToFade );
Expand Down
2 changes: 1 addition & 1 deletion GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ class Drawable : public Thing,
FADING_OUT
};
FadingMode m_fadeMode;
UnsignedInt m_timeElapsedFade; ///< for how many frames have i been fading
Real m_timeElapsedFade; ///< for how long have i been fading (in 30fps-equivalent frames)
UnsignedInt m_timeToFade; ///< how slowly am I fading

UnsignedInt m_shroudClearFrame; ///< Last frame the local player saw this drawable "OBJECTSHROUD_CLEAR"
Expand Down
26 changes: 22 additions & 4 deletions GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,10 +1149,14 @@ void Drawable::updateDrawable()
Real numer = (m_fadeMode == FADING_IN) ? (m_timeElapsedFade) : (m_timeToFade-m_timeElapsedFade);

setDrawableOpacity(numer/(Real)m_timeToFade);
++m_timeElapsedFade;
// TheSuperHackers @bugfix bobtista 15/09/2026 Decouple Drawable fade timing from render updates.
m_timeElapsedFade += TheFramePacer->getActualLogicTimeScaleOverFpsRatio();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better for long term performance to pass timeScale as argument to Drawable::updateDrawable.


if (m_timeElapsedFade > m_timeToFade)
{
setDrawableOpacity(m_fadeMode == FADING_IN ? 1.0f : 0.0f);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now calls setDrawableOpacity twice. It can probably simplify to single call.

m_fadeMode = FADING_NONE;
}
}
}

Expand All @@ -1167,7 +1171,8 @@ void Drawable::updateDrawable()
{
//LERP
(*dm)->setTerrainDecalOpacity(m_decalOpacity);
m_decalOpacity += m_decalOpacityFadeRate;
// TheSuperHackers @bugfix bobtista 15/09/2026 Decouple decal opacity fade timing from render updates.
m_decalOpacity += m_decalOpacityFadeRate * TheFramePacer->getActualLogicTimeScaleOverFpsRatio();
}
//---------------

Expand Down Expand Up @@ -4850,6 +4855,7 @@ void Drawable::xferDrawableModules( Xfer *xfer )
* 6: Added m_ambientSoundEnabledFromScript flag (Added in Zero Hour)
* 7: Save the customize ambient sound info (Added in Zero Hour)
* 8: TheSuperHackers @bugfix Removed m_prevTintStatus because loading its value is unnecessary and undesirable
* 9: TheSuperHackers @info Preserve fractional fade progress in non-retail saves

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tweak

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better describe this as m_timeElapsedFade is now serialized as Real instead of UnsignedInt.

*/
// ------------------------------------------------------------------------------------------------
void Drawable::xfer( Xfer *xfer )
Expand All @@ -4861,7 +4867,7 @@ void Drawable::xfer( Xfer *xfer )
#elif RETAIL_COMPATIBLE_XFER_SAVE
const XferVersion currentVersion = 7;
#else
const XferVersion currentVersion = 8;
const XferVersion currentVersion = 9;
#endif
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );
Expand Down Expand Up @@ -5035,7 +5041,19 @@ void Drawable::xfer( Xfer *xfer )
xfer->xferUser( &m_fadeMode, sizeof( FadingMode ) );

// time elapsed fade
xfer->xferUnsignedInt( &m_timeElapsedFade );
if (version >= 9)
{
xfer->xferReal( &m_timeElapsedFade );
}
else
{
UnsignedInt timeElapsedFadeFrames = static_cast<UnsignedInt>(m_timeElapsedFade);
xfer->xferUnsignedInt( &timeElapsedFadeFrames );
if (xfer->getXferMode() == XFER_LOAD)
{
m_timeElapsedFade = static_cast<Real>(timeElapsedFadeFrames);
}
}

// time to fade
xfer->xferUnsignedInt( &m_timeToFade );
Expand Down
Loading