Skip to content

Commit c12ffaf

Browse files
authored
Hopefully fix fog light flicker precision (#4906)
#### Summary Adjust weather interpolation resync precision in `CWeatherSA::ResyncInterpolationWithGameClock`. This keeps `InterpolationValue` aligned with the engine comparison path and removes fog transition light flicker. #### Motivation Fog to sunny flicker was fixed, but lights still flickered when blending into fog. This change prevents precision mismatches that can trigger the wrap branch and spike light related weather values. #### Test plan Test in-game on v26595 with fast clock and repeated `setWeatherBlended` into fog. Verify car lights, traffic lights, and other 2dfx lights no longer flash each second during the blend.
1 parent 3d7128a commit c12ffaf

1 file changed

Lines changed: 10 additions & 7 deletions

File tree

Client/game_sa/CWeatherSA.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,16 @@ void CWeatherSA::ResyncInterpolationWithGameClock(unsigned char primary, unsigne
3737
else
3838
{
3939
// Match the value CWeather::Update derives at 0x72B897:
40-
// v0 = (seconds / 60 + minutes) / 60
41-
// Snapping to minutes only would drop seconds and make CTimeCycle::CalcColoursForPoint
42-
// step m_CurrentColours per game-minute, which surfaces as flicker on vehicle coronas
43-
// (m_fSpriteBrightness) and shadows (m_wShadowStrength) when the clock runs fast.
44-
const auto ucMinute = *reinterpret_cast<unsigned char*>(VAR_TimeMinutes);
45-
const auto ucSecond = *reinterpret_cast<unsigned char*>(VAR_TimeSeconds);
46-
const float fInterp = std::min(1.f, static_cast<float>(ucMinute) / 60.f + static_cast<float>(ucSecond) / 3600.f);
40+
// v0 = ((double)seconds * 0.016666668 + (double)minutes) * 0.016666668
41+
// Keep this <= engine v0 to avoid triggering the wrap branch on precision mismatches.
42+
const auto ucMinute = *reinterpret_cast<unsigned char*>(VAR_TimeMinutes);
43+
const auto ucSecond = *reinterpret_cast<unsigned char*>(VAR_TimeSeconds);
44+
const double dInterp = std::min(1.0, (static_cast<double>(ucSecond) * 0.016666668 + static_cast<double>(ucMinute)) * 0.016666668);
45+
float fInterp = static_cast<float>(dInterp);
46+
47+
if (static_cast<double>(fInterp) > dInterp)
48+
fInterp = std::nextafterf(fInterp, 0.0f);
49+
4750
MemPutFast<float>(VAR_InterpolationValue, fInterp);
4851
}
4952
}

0 commit comments

Comments
 (0)