Skip to content

Commit

Permalink
Merge pull request #1384 from xan1242/master
Browse files Browse the repository at this point in the history
[NFSMW] add shadow + other render options
  • Loading branch information
xan1242 committed Jul 8, 2023
2 parents aedaa5c + ad1d175 commit a8db886
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ ShadowsRes = 2048 ; Controls the resolution of dynamic sh
ShadowsFix = 1 ; Dynamic shadows will no longer disappear when going into tunnels, under bridges, etc.
ImproveShadowLOD = 1 ; Increases the level of detail of dynamic shadows. This may negatively affect performance.
AutoScaleShadowsRes = 1 ; Adjusts the specified ShadowsRes based on the user's aspect ratio to maintain quality. This may negatively affect performance.
DisableShadowTextureFilterOnRadeon = 1 ; Disables the forced bilinear filter for the shadow texture on ATI/AMD Radeon GPUs.
ShadowMapTextureFormat = 0 ; Set the texture format for the shadow map texture here. (-1 = Disable patches | 0 = D24S8 (Default, Sharp Shadows) | 1 = INTZ (Soft Shadows) | 2 = DF16 (Radeon Only, Soft Shadows) | 3 = DF24 (Radeon Only, Soft Shadows))
RainDropletsScale = 0.5 ; Adjusts the size of the on-screen rain droplets.
DisableMotionBlur = 0 ; Allows users to disable motion blur without changing registry settings.
LightStreaksEnable = 0 ; Leftover from NFS Underground 2. Enables the light trail effect. Not very visible at higher FPS than 60, but it does make the flares more saturated in color.
BleachByPassEnable = 0 ; (EXPERIMENTAL) Leftover from NFS Underground 2. Enables the "Enhanced Contrast" effect. Requires the IDI_SCREENFILTER_FX shader from Underground 2 to work. If you do not have it, the screen will be blurry!
ForcedGPUVendor = 0x10DE ; Force the GPU PCI VendorID here. This will affect the renderer and video options behavior. (0 = Disabled | 0x10DE = NVIDIA (Default) | 0x1002 = ATI/AMD | 0x8086 = Intel)

[NOSTrail]
FixNOSTrailLength = 1 ; Fixes the NOS trail length for higher FPS.
Expand Down
103 changes: 88 additions & 15 deletions source/NFSMostWanted.WidescreenFix/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,28 @@ namespace ShadowRes
{
constexpr uint32_t ShadowDepthCheckRes = 3072;

// 0 = D24S8 (Shadow Map)
// 1 = INTZ (Depth Buffer as Texture)
// 2 = DF16 (Depth Buffer as Texture, Radeon Only)
// 3 = DF24 (Depth Buffer as Texture, Radeon Only)
uint32_t ShadowMapTexFormats[] = {75, 0x5A544E49, 0x36314644, 0x34324644};
int CurrentTexFormat = 0;

uint32_t Resolution = 2048;
bool bAutoScaleShadowsRes = true;
bool bDisableShadowTextureFilterOnRadeon = true;

uintptr_t dword_6C86B1; // X
uint32_t dword_6C878B; // X
uint32_t dword_6C87BD; // X
// X resolution ptrs
uintptr_t dword_6C86B1;
uint32_t dword_6C878B;
uint32_t dword_6C87BD;
uintptr_t dword_6C87F4;

// Y resolution ptrs
uintptr_t dword_6C86C1;
uint32_t* dword_6C8786;
uint32_t* dword_6C87B8;
uintptr_t dword_6C87EF;

uintptr_t dword_6C86C1; // Y
uint32_t* dword_6C8786; // Y
uint32_t* dword_6C87B8; // Y

uintptr_t DepthBiasAddr_901AC0 = 0x901AC0;
uintptr_t DepthBiasSlopeAddr_901ABC = 0x901ABC;
Expand All @@ -91,15 +102,22 @@ namespace ShadowRes
*(uint32_t*)dword_6C86B1 = resX;
*(uint32_t*)dword_6C878B = resX;
*(uint32_t*)dword_6C87BD = resX;
*(uint32_t*)dword_6C87F4 = resX;

*(uint32_t*)dword_6C86C1 = resY;
*(uint32_t*)dword_6C8786 = resY;
*(uint32_t*)dword_6C87B8 = resY;
*(uint32_t*)dword_6C87EF = resY;

if (resX > resval)
resval = resX;

if (resval > ShadowDepthCheckRes)
if (CurrentTexFormat > 0)
{
DepthBias = *(int32_t*)DepthBiasAddr_901AC0 * (static_cast<float>(resval) / 1024.0f);
DepthBiasSlope = *(float*)DepthBiasSlopeAddr_901ABC * (static_cast<float>(resval) / 1024.0f);
}
else if (resval > ShadowDepthCheckRes)
{
DepthBias = *(int32_t*)DepthBiasAddr_901AC0 * (static_cast<float>(resval) / static_cast<float>(ShadowDepthCheckRes));
DepthBiasSlope = *(float*)DepthBiasSlopeAddr_901ABC * (static_cast<float>(resval) / static_cast<float>(ShadowDepthCheckRes));
Expand Down Expand Up @@ -288,13 +306,14 @@ void Init()

ShadowRes::Resolution = iniReader.ReadInteger("GRAPHICS", "ShadowsRes", 2048);
ShadowRes::bAutoScaleShadowsRes = iniReader.ReadInteger("GRAPHICS", "AutoScaleShadowsRes", 1) != 0;
ShadowRes::bDisableShadowTextureFilterOnRadeon = iniReader.ReadInteger("GRAPHICS", "DisableShadowTextureFilterOnRadeon", 1) != 0;
ShadowRes::CurrentTexFormat = iniReader.ReadInteger("GRAPHICS", "ShadowMapTextureFormat", 0);
static float fRainDropletsScale = iniReader.ReadFloat("GRAPHICS", "RainDropletsScale", 0.5f);
bool bShadowsFix = iniReader.ReadInteger("GRAPHICS", "ShadowsFix", 1) != 0;
bool bImproveShadowLOD = iniReader.ReadInteger("GRAPHICS", "ImproveShadowLOD", 1) != 0;
bool bDisableMotionBlur = iniReader.ReadInteger("GRAPHICS", "DisableMotionBlur", 0) != 0;
bool bLightStreaksEnable = iniReader.ReadInteger("GRAPHICS", "LightStreaksEnable", 0) != 0;
bool bBleachByPassEnable = iniReader.ReadInteger("GRAPHICS", "BleachByPassEnable", 0) != 0;
static uint32_t ForcedGPUVendor = static_cast<uint32_t>(iniReader.ReadInteger("GRAPHICS", "ForcedGPUVendor", 0x10DE));

bool bFixNOSTrailLength = iniReader.ReadInteger("NOSTrail", "FixNOSTrailLength", 1) == 1;
bool bFixNOSTrailPosition = iniReader.ReadInteger("NOSTrail", "FixNOSTrailPosition", 0) != 0;
Expand Down Expand Up @@ -400,27 +419,81 @@ void Init()
ShadowRes::dword_6C87B8 = hook::pattern("68 00 04 00 00 68 00 04 00 00 50 FF 52 5C 85 C0 7D 36").count(1).get(0).get<uint32_t>(1);
ShadowRes::dword_6C87BD = (uint32_t)ShadowRes::dword_6C87B8 + 5;

uintptr_t loc_6C87E5 = reinterpret_cast<uintptr_t>(hook::pattern("68 44 46 31 36 6A 02 6A 01 68").get_first(0));
ShadowRes::dword_6C87EF = loc_6C87E5 + 0xA;
ShadowRes::dword_6C87F4 = ShadowRes::dword_6C87EF + 5;

injector::UnprotectMemory(ShadowRes::dword_6C86B1, sizeof(uint32_t), oldprotect);
injector::UnprotectMemory(ShadowRes::dword_6C86C1, sizeof(uint32_t), oldprotect);
injector::UnprotectMemory(ShadowRes::dword_6C8786, sizeof(uint32_t), oldprotect);
injector::UnprotectMemory(ShadowRes::dword_6C878B, sizeof(uint32_t), oldprotect);
injector::UnprotectMemory(ShadowRes::dword_6C87B8, sizeof(uint32_t), oldprotect);
injector::UnprotectMemory(ShadowRes::dword_6C87BD, sizeof(uint32_t), oldprotect);
injector::UnprotectMemory(ShadowRes::dword_6C87F4, sizeof(uint32_t), oldprotect);
injector::UnprotectMemory(ShadowRes::dword_6C87EF, sizeof(uint32_t), oldprotect);

ShadowRes::update(ShadowRes::Resolution);
}

// this disables shadow texture filtering on Radeon (vendor 0x1002) cards
if (ShadowRes::bDisableShadowTextureFilterOnRadeon)

if (ShadowRes::CurrentTexFormat >= 0)
{
uintptr_t loc_6C87E5 = reinterpret_cast<uintptr_t>(hook::pattern("68 44 46 31 36 6A 02 6A 01 68").get_first(0));
uintptr_t loc_6C8798 = loc_6C87E5 - 0x4D;
uintptr_t loc_6C87D5 = loc_6C87E5 - 0x10;
uintptr_t loc_6C87A2 = loc_6C87E5 - 0x43;
uintptr_t loc_6C87B2 = loc_6C87E5 - 0x33;

uintptr_t loc_6C174E = reinterpret_cast<uintptr_t>(hook::pattern("68 44 46 31 36 6A 03 6A 02 6A 16 6A 01 52 50 FF").get_first(0));
uintptr_t loc_6C1703 = loc_6C174E - 0x4B;
uintptr_t loc_6C170A = loc_6C174E - 0x44;
uintptr_t loc_6C1719 = loc_6C174E - 0x35;
uintptr_t loc_6C172C = loc_6C174E - 0x22;
uintptr_t loc_6C1741 = loc_6C174E - 0xD;
uintptr_t loc_6C1764 = loc_6C174E + 0x16;

uintptr_t dword_982C08 = *reinterpret_cast<uintptr_t*>(loc_6C172C + 2);

if (ShadowRes::CurrentTexFormat > (_countof(ShadowRes::ShadowMapTexFormats) - 1))
ShadowRes::CurrentTexFormat = (_countof(ShadowRes::ShadowMapTexFormats) - 1);

// disable writes to the shadow map texture type variable
injector::MakeNOP(loc_6C1703, 6);
injector::MakeNOP(loc_6C172C, 10);
injector::MakeNOP(loc_6C1764, 10);

if (ShadowRes::ShadowMapTexFormats[ShadowRes::CurrentTexFormat] < 0x7F)
{
injector::MakeJMP(loc_6C8798, loc_6C87A2);
injector::WriteMemory<uint8_t>(loc_6C87B2 + 1, ShadowRes::ShadowMapTexFormats[ShadowRes::CurrentTexFormat] & 0xFF, true);

injector::MakeNOP(loc_6C170A, 2);
injector::WriteMemory<uint8_t>(loc_6C1719 + 1, ShadowRes::ShadowMapTexFormats[ShadowRes::CurrentTexFormat] & 0xFF, true);
}
else
{
injector::MakeJMP(loc_6C8798, loc_6C87D5);
injector::WriteMemory<uint32_t>(loc_6C87E5 + 1, ShadowRes::ShadowMapTexFormats[ShadowRes::CurrentTexFormat], true);

injector::MakeJMP(loc_6C170A, loc_6C1741);
injector::WriteMemory<uint32_t>(loc_6C174E + 1, ShadowRes::ShadowMapTexFormats[ShadowRes::CurrentTexFormat], true);
}

// Var at 0x00982C08
// 1 = Sample Shadow Map Directly, 2 = Depth Buffer as Texture
if (ShadowRes::CurrentTexFormat == 0)
*(uint32_t*)dword_982C08 = 1;
else
*(uint32_t*)dword_982C08 = 2;
}

if (ForcedGPUVendor)
{
uint32_t* dword_93D898 = *hook::pattern("A1 ? ? ? ? 49 3D 02 10 00 00 89 0D").count(1).get(0).get<uint32_t*>(1);
auto dword_8F1CA0 = *hook::pattern("8B 14 85 ? ? ? ? 0F AF 56 5C C1 FA 0F 89 56 5C").count(1).get(0).get<uint32_t*>(3);
dword_8F1CA0 += 0x1D4;

for (size_t i = 0; i < 20; i++)
{
uint32_t* dword__93D898 = hook::pattern(pattern_str(to_bytes(dword_93D898))).count(1).get(0).get<uint32_t>(0);
injector::WriteMemory(dword__93D898, dword_8F1CA0, true);
injector::WriteMemory(dword__93D898, &ForcedGPUVendor, true);
}
}

Expand Down

0 comments on commit a8db886

Please sign in to comment.