Skip to content

Commit d27e1b7

Browse files
authored
Merge branch 'master' into fix-upgrades
2 parents 2b6ba73 + 1542a9c commit d27e1b7

4 files changed

Lines changed: 94 additions & 61 deletions

File tree

Client/cefweb/CWebApp.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,13 @@ namespace
101101
if (disableGpu)
102102
{
103103
commandLine->AppendSwitch("disable-gpu");
104-
// Also disable GPU compositing when GPU is disabled
105-
commandLine->AppendSwitch("disable-gpu-compositing");
106104
}
107105

106+
// Disable GPU compositing in all cases.
107+
// This keeps Chromium's compositor on the software path even when GPU
108+
// rendering stays enabled for other browser pipelines.
109+
commandLine->AppendSwitch("disable-gpu-compositing");
110+
108111
// Hardware video decoding - enable when GPU is enabled and video acceleration is requested
109112
if (!disableGpu && enableVideoAccel)
110113
{

Client/game_sa/CVehicleSA.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,10 +1928,7 @@ void CVehicleSA::RecalculateSuspensionLines()
19281928
if (!pModelInfo)
19291929
return;
19301930

1931-
// Parenthesise the precedence to match the original intent: only proceed
1932-
// for monster trucks or cars. The bareword `pModelInfo && X || Y` parsed
1933-
// as `(pModelInfo && X) || Y`, which let a null pModelInfo fall through
1934-
// to the IsCar() deref below on pure-car paths.
1931+
// Only cars and monster trucks use this suspension setup path.
19351932
if ((pModelInfo->IsMonsterTruck() || pModelInfo->IsCar()))
19361933
{
19371934
// Trains (Their trailers do as well!)

Client/mods/deathmatch/logic/CNetAPI.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,12 @@ void CNetAPI::DoPulse()
381381
}
382382

383383
// Time to freeze because of lack of return sync?
384+
// Only treat missing return-sync as network trouble while the local player is alive.
385+
// During expected dead/spectate periods (e.g. race map voting), return-sync can pause
386+
// by design and would otherwise show a misleading "NETWORK TROUBLE" warning.
384387
if (!g_pClientGame->IsDownloadingBigPacket() && (m_bStoredReturnSync) && (m_ulLastPuresyncTime != 0) && (m_ulLastSyncReturnTime != 0) &&
385-
(ulCurrentTime <= m_ulLastPuresyncTime + 5000) && (ulCurrentTime >= m_ulLastSyncReturnTime + 10000) &&
386-
(!g_pClientGame->GetLocalPlayer()->m_bIsGettingIntoVehicle) && (!m_bIncreaseTimeoutTime))
388+
(ulCurrentTime <= m_ulLastPuresyncTime + 5000) && (ulCurrentTime >= m_ulLastSyncReturnTime + 10000) && !pPlayer->IsDead() &&
389+
!pPlayer->IsDying() && (!g_pClientGame->GetLocalPlayer()->m_bIsGettingIntoVehicle) && (!m_bIncreaseTimeoutTime))
387390
{
388391
// No vehicle or vehicle in seat 0?
389392
if (!pVehicle || pPlayer->GetOccupiedVehicleSeat() == 0)

Client/multiplayer_sa/CMultiplayerSA.cpp

Lines changed: 83 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <game/CPedDamageResponse.h>
1717
#include <game/CEventList.h>
1818
#include <game/CEventDamage.h>
19-
#include "../game_sa/CCamSA.h"
2019
#include <cmath>
2120

2221
class CEventDamageSAInterface;
@@ -4899,6 +4898,81 @@ struct FollowCamLastGoodAngles
48994898
};
49004899
static FollowCamLastGoodAngles s_lastGoodAngles{};
49014900

4901+
static void RecoverFollowCamState(DWORD dwCam)
4902+
{
4903+
auto badf = [](float v) { return !std::isfinite(v); };
4904+
4905+
const float rawBeta = *(float*)(dwCam + 0xBC);
4906+
const float rawTargetBeta = *(float*)(dwCam + 0x8C);
4907+
const float rawBetaSpd = *(float*)(dwCam + 0xC0);
4908+
const float rawAlpha = *(float*)(dwCam + 0xAC);
4909+
const float rawTrueBeta = *(float*)(dwCam + 0xA0);
4910+
4911+
const bool badBeta = badf(rawBeta);
4912+
const bool badTargetBeta = badf(rawTargetBeta);
4913+
const bool badBetaSpd = badf(rawBetaSpd);
4914+
const bool badAlpha = badf(rawAlpha);
4915+
4916+
if (!badBeta && !badTargetBeta && !badBetaSpd && !badAlpha)
4917+
{
4918+
s_lastGoodAngles = FollowCamLastGoodAngles{true, rawBeta, rawAlpha};
4919+
return;
4920+
}
4921+
4922+
// Prefer live SA values first, then a recent finite snapshot.
4923+
float safeBeta = rawBeta;
4924+
if (badf(safeBeta))
4925+
{
4926+
if (std::isfinite(rawTrueBeta))
4927+
safeBeta = rawTrueBeta;
4928+
else if (std::isfinite(rawTargetBeta))
4929+
safeBeta = rawTargetBeta;
4930+
else if (s_lastGoodAngles.valid && std::isfinite(s_lastGoodAngles.beta))
4931+
safeBeta = s_lastGoodAngles.beta;
4932+
else
4933+
safeBeta = 0.0f;
4934+
}
4935+
4936+
float safeAlpha = rawAlpha;
4937+
if (badf(safeAlpha))
4938+
{
4939+
if (s_lastGoodAngles.valid && std::isfinite(s_lastGoodAngles.alpha))
4940+
safeAlpha = s_lastGoodAngles.alpha;
4941+
else
4942+
safeAlpha = 0.0f;
4943+
}
4944+
4945+
// Only touch fields that are invalid. Keeping valid fields untouched avoids
4946+
// fighting SA's own follow-cam smoothing and mouse input handling.
4947+
if (badBeta)
4948+
*(float*)(dwCam + 0xBC) = safeBeta;
4949+
4950+
if (badTargetBeta)
4951+
*(float*)(dwCam + 0x8C) = safeBeta;
4952+
4953+
if (badBetaSpd)
4954+
*(float*)(dwCam + 0xC0) = 0.0f;
4955+
4956+
if (badAlpha)
4957+
*(float*)(dwCam + 0xAC) = safeAlpha;
4958+
4959+
if (std::isfinite(safeBeta) && std::isfinite(safeAlpha))
4960+
s_lastGoodAngles = FollowCamLastGoodAngles{true, safeBeta, safeAlpha};
4961+
}
4962+
4963+
static void GetSafeFollowCamAngles(DWORD dwCam, float& outBeta, float& outAlpha)
4964+
{
4965+
RecoverFollowCamState(dwCam);
4966+
4967+
outBeta = *(float*)(dwCam + 0xBC);
4968+
outAlpha = *(float*)(dwCam + 0xAC);
4969+
4970+
if (!std::isfinite(outBeta))
4971+
outBeta = 0.0f;
4972+
if (!std::isfinite(outAlpha))
4973+
outAlpha = 0.0f;
4974+
}
4975+
49024976
bool _cdecl VehicleCamStart(DWORD dwCam, DWORD pVehicleInterface)
49034977
{
49044978
SClientEntity<CVehicleSA>* pVehicleClientEntity = pGameInterface->GetPools()->GetVehicle((DWORD*)pVehicleInterface);
@@ -5020,61 +5094,15 @@ static void __declspec(naked) HOOK_VehicleCamLookDir1()
50205094

50215095
bool _cdecl VehicleCamLookDir2(DWORD dwCam)
50225096
{
5023-
// Recover non-finite follow-camera angles before lookdir reconstruction
5024-
// would propagate them into the camera direction vector.
5025-
{
5026-
auto badf = [](float v) { return !std::isfinite(v); };
5027-
5028-
const float rawBeta = *(float*)(dwCam + 0xBC);
5029-
const float rawBetaSpd = *(float*)(dwCam + 0xC0);
5030-
const float rawAlpha = *(float*)(dwCam + 0xAC);
5031-
const bool badBeta = badf(rawBeta);
5032-
const bool badBetaSpd = badf(rawBetaSpd);
5033-
const bool badAlpha = badf(rawAlpha);
5034-
const bool needRecover = badBeta || badBetaSpd || badAlpha;
5035-
5036-
if (needRecover)
5037-
{
5038-
// Preserve live beta when only beta speed is invalid to avoid
5039-
// snapping camera input to stale history.
5040-
float fallbackBeta = std::isfinite(rawBeta) ? rawBeta : 0.0f;
5041-
float fallbackAlpha = std::isfinite(rawAlpha) ? rawAlpha : 0.0f;
5042-
5043-
if (!std::isfinite(rawBeta))
5044-
{
5045-
const float trueBeta = *(float*)(dwCam + 0xA0);
5046-
if (std::isfinite(trueBeta))
5047-
fallbackBeta = trueBeta;
5048-
else if (s_lastGoodAngles.valid && std::isfinite(s_lastGoodAngles.beta))
5049-
fallbackBeta = s_lastGoodAngles.beta;
5050-
}
5051-
5052-
if (!std::isfinite(rawAlpha) && s_lastGoodAngles.valid && std::isfinite(s_lastGoodAngles.alpha))
5053-
fallbackAlpha = s_lastGoodAngles.alpha;
5054-
5055-
*(float*)(dwCam + 0xBC) = fallbackBeta; // m_fHorizontalAngle (beta)
5056-
if (badBetaSpd)
5057-
*(float*)(dwCam + 0xC0) = 0.0f; // m_fBetaSpeed
5058-
5059-
// Rewrite TargetBeta only when beta itself is invalid.
5060-
if (badBeta)
5061-
*(float*)(dwCam + 0x8C) = fallbackBeta;
5062-
if (badAlpha)
5063-
*(float*)(dwCam + 0xAC) = fallbackAlpha;
5064-
}
5065-
5066-
if (std::isfinite(rawBeta) && std::isfinite(rawAlpha))
5067-
{
5068-
s_lastGoodAngles = FollowCamLastGoodAngles{true, rawBeta, rawAlpha};
5069-
}
5070-
}
5097+
// Repair only invalid follow-cam internals, then use the sanitized angles
5098+
// for output reconstruction.
5099+
float fPhi = 0.0f;
5100+
float fTheta = 0.0f;
5101+
GetSafeFollowCamAngles(dwCam, fPhi, fTheta);
50715102

50725103
// Calculates the look direction vector for the vehicle camera. This vector
50735104
// is later multiplied by a factor and added to the vehicle position by SA
50745105
// to obtain the final camera position.
5075-
float fPhi = *(float*)(dwCam + 0xBC);
5076-
float fTheta = *(float*)(dwCam + 0xAC);
5077-
50785106
MemPutFast<CVector>(dwCam + 0x190, -gravcam_matGravity.vRight * cos(fPhi) * cos(fTheta) - gravcam_matGravity.vFront * sin(fPhi) * cos(fTheta) +
50795107
gravcam_matGravity.vUp * sin(fTheta));
50805108

@@ -5105,7 +5133,9 @@ static void __declspec(naked) HOOK_VehicleCamLookDir2()
51055133

51065134
void _cdecl VehicleCamHistory(DWORD dwCam, CVector* pvecTarget, float fTargetTheta, float fRadius, float fZoom)
51075135
{
5108-
float fPhi = *(float*)(dwCam + 0xBC);
5136+
float fPhi = 0.0f;
5137+
float fAlphaIgnored = 0.0f;
5138+
GetSafeFollowCamAngles(dwCam, fPhi, fAlphaIgnored);
51095139

51105140
CVector vecDir = -gravcam_matGravity.vRight * cos(fPhi) * cos(fTargetTheta) - gravcam_matGravity.vFront * sin(fPhi) * cos(fTargetTheta) +
51115141
gravcam_matGravity.vUp * sin(fTargetTheta);

0 commit comments

Comments
 (0)