From cf7fcc16038ffd6688a1a4979ff650924ebd5025 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Mon, 17 Jun 2019 15:47:06 +0100 Subject: [PATCH] Fix 'Smashing Drive' on AMD/Intel GPUs --- src/core/hle/D3D8/XbState.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/core/hle/D3D8/XbState.cpp b/src/core/hle/D3D8/XbState.cpp index 99034010a..d79ddb790 100644 --- a/src/core/hle/D3D8/XbState.cpp +++ b/src/core/hle/D3D8/XbState.cpp @@ -26,7 +26,8 @@ // ****************************************************************** #define _XBOXKRNL_DEFEXTRN_ #define LOG_PREFIX CXBXR_MODULE::D3DST - + +#include "core\kernel\init\CxbxKrnl.h" #include "core\kernel\support\Emu.h" #include "core\kernel\support\EmuXTL.h" @@ -90,10 +91,22 @@ void UpdateDeferredRenderStates() // Convert from Xbox Data Formats to PC switch (RenderState) { + case XTL::X_D3DRS_FOGSTART: + case XTL::X_D3DRS_FOGEND: { + // HACK: If the fog start/fog-end are negative, make them positive + // This fixes Smashing Drive on non-nvidia hardware + // Cause appears to be non-nvidia drivers clamping values < 0 to 0 + // Resulting in the fog formula becoming (0 - d) / 0, which breaks rendering + // This prevents that scenario for screen-space fog, *hopefully* without breaking eye-based fog also + float fogValue = *(float*)&Value; + if (fogValue < 0.0f) { + LOG_TEST_CASE("FOGSTART/FOGEND below 0"); + fogValue = std::abs(fogValue); + Value = *(DWORD*)&Value; + } + } break; case XTL::X_D3DRS_FOGENABLE: case XTL::X_D3DRS_FOGTABLEMODE: - case XTL::X_D3DRS_FOGSTART: - case XTL::X_D3DRS_FOGEND: case XTL::X_D3DRS_FOGDENSITY: case XTL::X_D3DRS_RANGEFOGENABLE: case XTL::X_D3DRS_LIGHTING: