Add fog density and opacity

This commit is contained in:
2025-10-01 14:10:07 +02:00
parent 7409b52f4f
commit 01b2458e04

View File

@@ -12,12 +12,15 @@
#include "SDK/Engine_classes.hpp" #include "SDK/Engine_classes.hpp"
using namespace SDK; using namespace SDK;
// Unreal Engine variables
static UWorld* previousWorld = nullptr;
static ULevel* previousLevel = nullptr;
static AExponentialHeightFog* previousFogActor = nullptr;
// Constants // Constants
const std::string PLUGIN_NAME = "SilentHillf"; const std::string PLUGIN_NAME = "SilentHillf";
const std::string PLUGIN_LOG = PLUGIN_NAME + ".log"; const std::string PLUGIN_LOG = PLUGIN_NAME + ".log";
const std::string gameExecutable = "SHf-Win64-Shipping.exe"; const std::string gameExecutable = "SHf-Win64-Shipping.exe";
const float BASE_ASPECT = 1.777777791;
// Logger // Logger
std::shared_ptr<spdlog::logger> logger; std::shared_ptr<spdlog::logger> logger;
@@ -29,16 +32,22 @@ static bool g_fov_fix_enabled = false;
static bool g_DOF_fix_enabled = false; static bool g_DOF_fix_enabled = false;
static bool g_CA_fix_enabled = false; static bool g_CA_fix_enabled = false;
static bool g_Vignetting_fix_enabled = false; static bool g_Vignetting_fix_enabled = false;
static bool g_Fog_fix_enabled = false; static bool g_Volumetric_Fog_fix_enabled = false;
static bool g_Fog_Density_fix_enabled = false;
static bool g_Fog_Max_Opacity_fix_enabled = false;
static bool g_Camera_fix_enabled = false; static bool g_Camera_fix_enabled = false;
static int g_AdditionalFOVValue = 0; static int g_AdditionalFOVValue = 0;
static float g_CameraDistance = 1.f; static float g_CameraDistance = 1.f;
static float g_FogDensity = 0.4f;
static float g_FogMaxOpacity = 0.4f;
// Shared values // Shared values
static float g_FOV_In = 65.f; static float g_FOV_In = 65.f;
static float g_FOV_Out = 65.f; static float g_FOV_Out = 65.f;
static float g_Camera_In = 230.f; static float g_Camera_In = 230.f;
static float g_Camera_Out = 230.f; static float g_Camera_Out = 230.f;
static float g_DefaultFogDensity = 0.1f;
static float g_DefaultFogMaxOpacity = 1.f;
static bool g_Console_Enabled = false; static bool g_Console_Enabled = false;
// AOB Unreal Engine offsets addresses // AOB Unreal Engine offsets addresses
@@ -52,13 +61,19 @@ static uint8_t* FOVaddress = nullptr;
static uint8_t* DOFaddress = nullptr; static uint8_t* DOFaddress = nullptr;
static uint8_t* CAaddress = nullptr; static uint8_t* CAaddress = nullptr;
static uint8_t* Vignettingaddress = nullptr; static uint8_t* Vignettingaddress = nullptr;
static uint8_t* VolumetricFogaddress = nullptr; static uint8_t* Fogaddress = nullptr;
static uint8_t* VolumetricFogEngineaddress_1 = nullptr;
static uint8_t* VolumetricFogEngineaddress_2 = nullptr;
static uint8_t* FogDensityEngineaddress = nullptr;
static uint8_t* FogOpacityEngineaddress = nullptr;
static uint8_t* Cameraaddress = nullptr; static uint8_t* Cameraaddress = nullptr;
// Hooking // Hooking
static SafetyHookMid FOVHook{}; static SafetyHookMid FOVHook{};
static SafetyHookMid FogHook{};
static SafetyHookMid VolumetricFogHook{}; static SafetyHookMid VolumetricFogHook{};
static SafetyHookMid HUDHook{}; static SafetyHookMid FogDensityHook{};
static SafetyHookMid FogMaxOpacityHook{};
static SafetyHookMid CameraHook{}; static SafetyHookMid CameraHook{};
// Prototypes // Prototypes
@@ -67,6 +82,9 @@ static void DOFFixEnabled();
static void CAFixEnabled(); static void CAFixEnabled();
static void VignettingFixEnabled(); static void VignettingFixEnabled();
static void FogFixEnabled(); static void FogFixEnabled();
static void VolumetricFogFixEnabled();
static void FogDensityFixEnabled();
static void FogOpacityFixEnabled();
static void CameraFixEnabled(); static void CameraFixEnabled();
static void EnableConsole(); static void EnableConsole();
@@ -140,19 +158,87 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled)
} }
} }
if (VolumetricFogaddress == nullptr) { if (Fogaddress == nullptr) {
constexpr auto FogStringObfuscated = make_obfuscated<0x4A>("0F 84 ?? ?? ?? ?? F6 ?? ?? ?? 0F 84 ?? ?? ?? ?? 83 BF"); constexpr auto VolumetricFogStringObfuscated = make_obfuscated<0x4A>("40 ?? 48 83 ?? ?? 48 8B ?? ?? ?? ?? ?? 48 ?? ?? 48 89 ?? ?? ?? 48 8D ?? ?? 48 8D ?? ?? ?? E8");
VolumetricFogaddress = Memory::AOBScan(gameExecutable, FogStringObfuscated.decrypt(), PAGE_EXECUTE_READ); Fogaddress = Memory::AOBScan(gameExecutable, VolumetricFogStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
//"SHf-Win64-Shipping.exe" + 2174B8A - E8 51 73 F0 FE - call "SHf-Win64-Shipping.exe" + 107BEE0 //"SHf-Win64-Shipping.exe" + 28FC64E - 48 8D B9 A0 00 00 00 - lea rdi, [rcx + SilentHillfCore.dtor_list_head + 70]
//"SHf-Win64-Shipping.exe" + 2174B8F - 0F B6 C3 - movzx eax, bl //"SHf-Win64-Shipping.exe" + 28FC655 - 48 8B CF - mov rcx, rdi
//"SHf-Win64-Shipping.exe" + 2174B92 - 48 8B 4C 24 50 - mov rcx, [rsp + 50] //"SHf-Win64-Shipping.exe" + 28FC658 - E8 E3 84 87 FF - call "SHf-Win64-Shipping.exe" + 2174B40
//"SHf-Win64-Shipping.exe" + 2174B97 - 48 33 CC - xor rcx, rsp //"SHf-Win64-Shipping.exe" + 28FC65D - 84 C0 - test al, al
//"SHf-Win64-Shipping.exe" + 2174B9A - E8 91 78 C2 04 - call "SHf-Win64-Shipping.exe" + 6D9C430 //"SHf-Win64-Shipping.exe" + 28FC65F - 74 43 - je "SHf-Win64-Shipping.exe" + 28FC6A4
if (!VolumetricFogaddress) if (!Fogaddress)
logger->warn("Fog signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
else {
logger->info("Fog signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(Fogaddress));
Fogaddress += 0x1e;
}
}
if (VolumetricFogEngineaddress_1 == nullptr) {
constexpr auto VolumetricFogStringObfuscated = make_obfuscated<0x4A>("38 91 D0 02 ?? ?? 74 ?? 88 91 D0 02 ?? ?? E9 ?? ?? ?? ?? C3");
VolumetricFogEngineaddress_1 = Memory::AOBScan(gameExecutable, VolumetricFogStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
//"SHf-Win64-Shipping.exe" + 3593070 - 38 91 D0 02 00 00 - cmp[rcx + 000002D0], dl
//"SHf-Win64-Shipping.exe" + 3593076 - 74 0B - je "SHf-Win64-Shipping.exe" + 3593083
//"SHf-Win64-Shipping.exe" + 3593078 - 88 91 D0 02 00 00 - mov[rcx + 000002D0], dl
//"SHf-Win64-Shipping.exe" + 359307E - E9 DD E4 F7 FF - jmp "SHf-Win64-Shipping.exe" + 3511560
//"SHf-Win64-Shipping.exe" + 3593083 - C3 - ret
if (!VolumetricFogEngineaddress_1)
logger->warn("Volumetric fog signature not found. Maybe your game has been updated and is no more compatible with this plugin."); logger->warn("Volumetric fog signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
else { else {
logger->info("Volumetric fog signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(VolumetricFogaddress)); logger->info("Volumetric Fog signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(VolumetricFogEngineaddress_1));
VolumetricFogEngineaddress_1 += 0x8;
}
}
if (VolumetricFogEngineaddress_2 == nullptr) {
constexpr auto VolumetricFogStringObfuscated = make_obfuscated<0x4A>("88 83 D0 02 ?? ?? 8B 87 ?? ?? ?? ?? 89 83 ?? ?? ?? ?? 0F B6");
VolumetricFogEngineaddress_2 = Memory::AOBScan(gameExecutable, VolumetricFogStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
//"SHf-Win64-Shipping.exe" + 4CE3E25 - 0F B6 47 74 - movzx eax, byte ptr[rdi + 74]
//"SHf-Win64-Shipping.exe" + 4CE3E29 - 48 8B CB - mov rcx, rbx
//"SHf-Win64-Shipping.exe" + 4CE3E2C - 88 83 D0 02 00 00 - mov[rbx + 000002D0], al
//"SHf-Win64-Shipping.exe" + 4CE3E32 - 8B 87 98 00 00 00 - mov eax, [rdi + SilentHillfCore.dtor_list_head + 68]
//"SHf-Win64-Shipping.exe" + 4CE3E38 - 89 83 FC 02 00 00 - mov[rbx + 000002FC], eax
if (!VolumetricFogEngineaddress_2)
logger->warn("Volumetric fog signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
else {
logger->info("Volumetric Fog signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(VolumetricFogEngineaddress_2));
}
}
if (FogDensityEngineaddress == nullptr) {
constexpr auto FogDensityStringObfuscated = make_obfuscated<0x4A>("0F 2E ?? 30 02 ?? ?? 74 ?? F3 0F ?? ?? ?? ?? ?? ?? E9 ?? ?? ?? ?? C3");
FogDensityEngineaddress = Memory::AOBScan(gameExecutable, FogDensityStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
//"SHf-Win64-Shipping.exe" + 3590190 - 0F 2E 89 30 02 00 00 - ucomiss xmm1, [rcx + 00000230]
//"SHf-Win64-Shipping.exe" + 3590197 - 74 0D - je "SHf-Win64-Shipping.exe" + 35901A6
//"SHf-Win64-Shipping.exe" + 3590199 - F3 0F 11 89 30 02 00 00 - movss[rcx + 00000230], xmm1
//"SHf-Win64-Shipping.exe" + 35901A1 - E9 BA13F8FF - jmp "SHf-Win64-Shipping.exe" + 3511560
//"SHf-Win64-Shipping.exe" + 35901A6 - C3 - ret
if (!FogDensityEngineaddress)
logger->warn("Fog density signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
else {
logger->info("Fog density signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(FogDensityEngineaddress));
FogDensityEngineaddress += 0x9;
}
}
if (FogOpacityEngineaddress == nullptr) {
constexpr auto FogOpacityStringObfuscated = make_obfuscated<0x4A>("0F 2E ?? C4 02 ?? ?? 74 ?? F3 0F ?? ?? ?? ?? ?? ?? E9 ?? ?? ?? ?? C3");
FogOpacityEngineaddress = Memory::AOBScan(gameExecutable, FogOpacityStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
//"SHf-Win64-Shipping.exe" + 3590220 - 0F 2E 89 C4 02 00 00 - ucomiss xmm1, [rcx + 000002C4]
//"SHf-Win64-Shipping.exe" + 3590227 - 74 0D - je "SHf-Win64-Shipping.exe" + 3590236
//"SHf-Win64-Shipping.exe" + 3590229 - F3 0F 11 89 C4 02 00 00 - movss[rcx + 000002C4], xmm1
//"SHf-Win64-Shipping.exe" + 3590231 - E9 2A 13 F8 FF - jmp "SHf-Win64-Shipping.exe" + 3511560
//"SHf-Win64-Shipping.exe" + 3590236 - C3 - ret
if (!FogOpacityEngineaddress)
logger->warn("Fog opacity signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
else {
logger->info("Fog opacity signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(FogOpacityEngineaddress));
FogOpacityEngineaddress += 0x9;
} }
} }
@@ -172,7 +258,7 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled)
} }
} }
if (FOVaddress && Cameraaddress && DOFaddress && CAaddress && Vignettingaddress && VolumetricFogaddress) { if (FOVaddress && Cameraaddress && DOFaddress && CAaddress && Vignettingaddress && Fogaddress) {
logger->info("All AOB signatures found. Ready to patch..."); logger->info("All AOB signatures found. Ready to patch...");
AOBScanDone = true; AOBScanDone = true;
} }
@@ -234,7 +320,10 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled)
if (DOFaddress) DOFFixEnabled(); if (DOFaddress) DOFFixEnabled();
if (CAaddress) CAFixEnabled(); if (CAaddress) CAFixEnabled();
if (Vignettingaddress) VignettingFixEnabled(); if (Vignettingaddress) VignettingFixEnabled();
if (VolumetricFogaddress) FogFixEnabled(); if (Fogaddress) FogFixEnabled();
if (Fogaddress && VolumetricFogEngineaddress_1 && VolumetricFogEngineaddress_2) VolumetricFogFixEnabled();
if (Fogaddress && FogDensityEngineaddress) FogDensityFixEnabled();
if (Fogaddress && FogOpacityEngineaddress) FogOpacityFixEnabled();
if (!g_Console_Enabled && GObjectsaddress && GNamesaddress && AppendStringaddress && ProcessEventaddress) if (!g_Console_Enabled && GObjectsaddress && GNamesaddress && AppendStringaddress && ProcessEventaddress)
EnableConsole(); EnableConsole();
} }
@@ -264,10 +353,31 @@ extern "C" __declspec(dllexport) void SetVignettingFixEnabled(bool enabled, bool
if (!init) VignettingFixEnabled(); if (!init) VignettingFixEnabled();
} }
extern "C" __declspec(dllexport) void SetFogFixEnabled(bool enabled, bool init) extern "C" __declspec(dllexport) void SetVolumetricFogFixEnabled(bool enabled, bool init)
{ {
g_Fog_fix_enabled = enabled; g_Volumetric_Fog_fix_enabled = enabled;
if (!init) FogFixEnabled(); if (!init) {
FogFixEnabled();
VolumetricFogFixEnabled();
}
}
extern "C" __declspec(dllexport) void SetFogDensityFixEnabled(bool enabled, bool init)
{
g_Fog_Density_fix_enabled = enabled;
if (!init) {
FogFixEnabled();
FogDensityFixEnabled();
}
}
extern "C" __declspec(dllexport) void SetFogMaxOpacityFixEnabled(bool enabled, bool init)
{
g_Fog_Max_Opacity_fix_enabled = enabled;
if (!init) {
FogFixEnabled();
FogOpacityFixEnabled();
}
} }
extern "C" __declspec(dllexport) void SetCameraFixEnabled(bool enabled, bool init) extern "C" __declspec(dllexport) void SetCameraFixEnabled(bool enabled, bool init)
@@ -276,7 +386,6 @@ extern "C" __declspec(dllexport) void SetCameraFixEnabled(bool enabled, bool ini
if (!init) CameraFixEnabled(); if (!init) CameraFixEnabled();
} }
extern "C" __declspec(dllexport) void SetFOV(int fov) extern "C" __declspec(dllexport) void SetFOV(int fov)
{ {
g_AdditionalFOVValue = fov; g_AdditionalFOVValue = fov;
@@ -286,6 +395,14 @@ extern "C" __declspec(dllexport) void SetCameraDistance(float multiplier) {
g_CameraDistance = multiplier; g_CameraDistance = multiplier;
} }
extern "C" __declspec(dllexport) void SetFogDensity(float fogDensity) {
g_FogDensity = fogDensity;
}
extern "C" __declspec(dllexport) void SetFogMaxOpacity(float fogMaxOpacity) {
g_FogMaxOpacity = fogMaxOpacity;
}
// Getters for Reshade addon call // Getters for Reshade addon call
extern "C" __declspec(dllexport) void GetGameInfos(GameInfos* infos) { extern "C" __declspec(dllexport) void GetGameInfos(GameInfos* infos) {
if (!infos) return; if (!infos) return;
@@ -294,6 +411,8 @@ extern "C" __declspec(dllexport) void GetGameInfos(GameInfos* infos) {
infos->FOVOut = g_FOV_Out; infos->FOVOut = g_FOV_Out;
infos->cameraIn = g_Camera_In; infos->cameraIn = g_Camera_In;
infos->cameraOut = g_Camera_Out; infos->cameraOut = g_Camera_Out;
infos->defaultFogDensity = g_DefaultFogDensity;
infos->fogMaxOpacity = g_DefaultFogMaxOpacity;
infos->consoleEnabled = g_Console_Enabled; infos->consoleEnabled = g_Console_Enabled;
} }
@@ -309,7 +428,6 @@ static void FOVFixEnabled() {
}); });
} }
else FOVHook.enable(); else FOVHook.enable();
logger->info("FOV fix enabled"); logger->info("FOV fix enabled");
} }
if (!(g_fix_enabled && g_fov_fix_enabled) && FOVaddress) { if (!(g_fix_enabled && g_fov_fix_enabled) && FOVaddress) {
@@ -337,6 +455,98 @@ static void CameraFixEnabled() {
} }
} }
static void FogFixEnabled() {
if (g_fix_enabled && (g_Fog_Density_fix_enabled || g_Fog_Max_Opacity_fix_enabled || g_Volumetric_Fog_fix_enabled)
&& Fogaddress && VolumetricFogEngineaddress_1 && VolumetricFogEngineaddress_2 && FogDensityEngineaddress && FogOpacityEngineaddress) {
if (!FogHook) { // Generic hook for fogs fixes
FogHook = safetyhook::create_mid(Fogaddress,
[](SafetyHookContext& ctx) {
UWorld* World = UWorld::GetWorld();
if (!World) return;
if (World != previousWorld) {
previousWorld = World;
previousLevel = World->PersistentLevel;
previousFogActor = nullptr;
g_DefaultFogDensity = -1.f;
g_DefaultFogMaxOpacity = -1.f;
}
if (!previousFogActor && previousLevel) { // Fog attached to actor
for (AActor* Actor : previousLevel->Actors)
{
if (!Actor || !Actor->Class || !Actor->IsA(AExponentialHeightFog::StaticClass())) continue;
previousFogActor = reinterpret_cast<AExponentialHeightFog*>(Actor);
break;
}
}
if (previousFogActor && previousFogActor->Component) {
// Get default engine values
if (g_DefaultFogDensity == -1.f) g_DefaultFogDensity = previousFogActor->Component->FogDensity;
if (g_DefaultFogMaxOpacity == -1.f) g_DefaultFogMaxOpacity = previousFogActor->Component->FogMaxOpacity;
// Force fix values
previousFogActor->Component->SetFogDensity(g_fix_enabled && g_Fog_Density_fix_enabled ? g_FogDensity : g_DefaultFogDensity);
previousFogActor->Component->SetFogMaxOpacity(g_fix_enabled && g_Fog_Max_Opacity_fix_enabled ? g_FogMaxOpacity : g_DefaultFogMaxOpacity);
previousFogActor->Component->SetVolumetricFog(g_fix_enabled && g_Volumetric_Fog_fix_enabled ? false : true);
}
});
}
}
}
static void VolumetricFogFixEnabled() {
if (g_fix_enabled && g_Volumetric_Fog_fix_enabled && VolumetricFogEngineaddress_1 && VolumetricFogEngineaddress_2) {
if (!VolumetricFogHook) VolumetricFogHook = safetyhook::create_mid(VolumetricFogEngineaddress_1,
[](SafetyHookContext& ctx) { // Override engine override value
if (g_fix_enabled && g_Volumetric_Fog_fix_enabled) ctx.rdx = 0;
});
else VolumetricFogHook.enable();
Memory::PatchBytes(VolumetricFogEngineaddress_2, "\x90\x90\x90\x90\x90\x90", 6);
logger->info("Volumetric fog fix enabled");
}
if (!(g_fix_enabled && g_Volumetric_Fog_fix_enabled) && VolumetricFogEngineaddress_1 && VolumetricFogEngineaddress_2) {
if (previousFogActor && previousFogActor->Component)
previousFogActor->Component->SetVolumetricFog(true); // Restore volumetric fog
if (VolumetricFogHook) VolumetricFogHook.disable();
Memory::RestoreBytes(VolumetricFogEngineaddress_2);
logger->info("Volumetric fog fix disabled");
}
}
static void FogDensityFixEnabled() {
if (g_fix_enabled && g_Fog_Density_fix_enabled && FogDensityEngineaddress) {
if (!FogDensityHook) FogDensityHook = safetyhook::create_mid(FogDensityEngineaddress,
[](SafetyHookContext& ctx) { // Override engine override value
ctx.xmm1.f32[0] = g_FogDensity;
});
else FogDensityHook.enable();
logger->info("Fog density fix enabled");
}
if (!(g_fix_enabled && g_Fog_Density_fix_enabled) && FogDensityEngineaddress) {
if (previousFogActor && previousFogActor->Component)
previousFogActor->Component->SetFogDensity(g_DefaultFogDensity);
if (FogDensityHook) FogDensityHook.disable();
logger->info("Fog density fix disabled");
}
}
static void FogOpacityFixEnabled() {
if (g_fix_enabled && g_Fog_Max_Opacity_fix_enabled && FogOpacityEngineaddress) {
if (!FogMaxOpacityHook) FogMaxOpacityHook = safetyhook::create_mid(FogOpacityEngineaddress,
[](SafetyHookContext& ctx) { // Override engine override value
ctx.xmm1.f32[0] = g_FogMaxOpacity;
});
else FogMaxOpacityHook.enable();
logger->info("Fog opacity fix enabled");
}
if (!(g_fix_enabled && g_Fog_Max_Opacity_fix_enabled) && FogOpacityEngineaddress) {
if (previousFogActor && previousFogActor->Component)
previousFogActor->Component->SetFogMaxOpacity(g_DefaultFogMaxOpacity);
if (FogMaxOpacityHook) FogMaxOpacityHook.disable();
logger->info("Fog opacity fix disabled");
}
}
// Memory patch fixes // Memory patch fixes
static void DOFFixEnabled() { static void DOFFixEnabled() {
if (g_fix_enabled && g_DOF_fix_enabled && DOFaddress) { if (g_fix_enabled && g_DOF_fix_enabled && DOFaddress) {
@@ -371,18 +581,6 @@ static void VignettingFixEnabled() {
} }
} }
static void FogFixEnabled() {
if (g_fix_enabled && g_Fog_fix_enabled && VolumetricFogaddress) {
if (!VolumetricFogHook) {
VolumetricFogHook = safetyhook::create_mid(VolumetricFogaddress,
[](SafetyHookContext& ctx) {
ctx.rflags |= 0x40;
});
}
logger->info("Fog fix enabled");
}
}
// UE Console creation // UE Console creation
static void EnableConsole() static void EnableConsole()
{ {