Add fixes and cheats. Code refactoring

This commit is contained in:
2026-01-10 10:40:09 +01:00
parent d685831add
commit e00b9f09a5

View File

@@ -1,45 +1,42 @@
#define IMGUI_DISABLE_INCLUDE_IMCONFIG_H
#define NOMINMAX
#define IMGUI_DISABLE_INCLUDE_IMCONFIG_H
#define IMGUI_HAS_DOCK 1
#include "GameInformations.h"
#include "inicpp.h"
#include <imgui.h>
#include <reshade.hpp>
#include <string>
#include <Windows.h>
#include "CommonHeaders.h"
#include "HotkeysManager.h"
#include "OSDManager.h"
#include <chrono>
#include <algorithm> // std::min
// Screen informations
static int screenWidth = GetSystemMetrics(SM_CXSCREEN);
static int screenHeight = GetSystemMetrics(SM_CYSCREEN);
static float aspectRatio = (float)screenWidth / screenHeight;
static uint32_t g_width = 0;
static uint32_t g_height = 0;
// Core game dll functions declarations
typedef void (*SetFixesFn)(GameFixes, bool);
typedef void (*SetBoolFn)(bool, bool);
typedef void (*SetIntFn)(int);
typedef void (*SetFloatFn)(float);
typedef float (*GetFloatFn)();
typedef bool (*GetBoolFn)();
static HMODULE fixLib = nullptr;
static LONG g_coreInitialized = 0;
static LONG g_hotkeysInitialized = 0;
static LONG g_uniformReseted = 0;
static SetBoolFn SetFixEnabled = nullptr;
static SetBoolFn SetFOVFixEnabled = nullptr;
static SetBoolFn SetDOFFixEnabled = nullptr;
static SetBoolFn SetCAFixEnabled = nullptr;
static SetBoolFn SetVignettingFixEnabled = nullptr;
static SetBoolFn SetCameraFixEnabled = nullptr;
static SetBoolFn SetCutscenesFixEnabled = nullptr;
static SetBoolFn SetCutscenesFPSFixEnabled = nullptr;
static SetBoolFn SetVolumetricFogFixEnabled = nullptr;
static SetBoolFn SetFogDensityFixEnabled = nullptr;
static SetBoolFn SetFogMaxOpacityFixEnabled = nullptr;
static SetFixesFn SetFixes = nullptr;
static SetIntFn SetFOV = nullptr;
static SetFloatFn SetCameraDistance = nullptr;
static SetFloatFn SetFogDensity = nullptr;
static SetFloatFn SetFogMaxOpacity = nullptr;
static SetFloatFn SetWorldTimeDilation = nullptr;
static SetFloatFn SetAITimeDilation = nullptr;
static GetGameInfosStruct GetGameInfos = nullptr;
void SetFixesEnabled(GameFixes fix, bool value) {
if (SetFixes) SetFixes(fix, value);
}
// Plugin variables for checkboxes and sliders
static bool skip_Intro_enabled = true;
static bool fov_fix_enabled = false;
static bool DOF_fix_enabled = false;
static bool CA_fix_enabled = false;
@@ -48,36 +45,53 @@ static bool camera_fix_enabled = false;
static bool cutscenes_fix_enabled = false;
static bool cutscenes_FPS_fix_enabled = false;
static bool volumetric_fog_fix_enabled = false;
static bool Fog_density_fix_enabled = false;
static bool Fog_max_opacity_fix_enabled = false;
static bool Fog_fix_enabled = false;
static bool fix_enabled = false;
static bool Time_Dilation_fix_enabled = false;
static bool StealthMode_fix_enabled;
static int worldFOVvalue = 0;
static float cameraDistanceValue = 1.f;
static float fogDensityValue = 0.1f;
static float fogMaxOpacityValue = 1.f;
static float worldTimeDilationValue = 1.f;
static float AITimeDilationValue = 1.f;
static bool console = true;
static float OSD_duration = 3.f;
// Overlays popups
static bool popup_Informations = false;
static bool show_log_overlay = false;
static std::string log_content;
// Plugin settings
const std::string SETTINGS_FILE = "./pluginsettings.ini";
const char* FIX_VERSION = "1.0.4";
const char* FIX_INFORMATIONS = "This fix allows to:\n - Control FOV in game.\n - Control camera distance.\n - Unlock cutscenes FPS and enable ultrawide.\n - Disable depth of field.\n - Disable chromatic aberrations.\n - Disable vignetting.\n - Control fog.\n - Re enable console.\n\nDisabling Fog will not entirely remove it.";
const char* FIX_INFORMATIONS = "This fix allows to:\n - Control FOV in game.\n - Control camera distance.\n - Unlock cutscenes FPS and enable ultrawide.\n - Enable cheats.\n - Disable depth of field.\n - Disable chromatic aberrations.\n - Disable vignetting.\n - Control fog.\n - Re enable console.";
const char* DONATION_URL = "https://buymeacoffee.com/k4sh44";
// Scaling factor based on screen resolution
float scale = 1.f;
// Prepare arrays of checkboxes for ImGui
static FixToggle individualFixes[] = {
{ "FOV", &fov_fix_enabled, GameFixes::FOV },
{ "Cutscenes", &cutscenes_fix_enabled, GameFixes::Cutscenes, "Remove black bars"},
{ "Vignetting", &Vignetting_fix_enabled, GameFixes::Vignetting },
{ "Fog", &Fog_fix_enabled, GameFixes::Fog },
{ "Camera", &camera_fix_enabled, GameFixes::Camera },
{ "Cutscenes FPS", &cutscenes_FPS_fix_enabled, GameFixes::Framerate, "Unlock cutscenes up to 240 FPS"},
{ "Depth of field", &DOF_fix_enabled, GameFixes::DOF },
{ "Chromatic aberrations", &CA_fix_enabled, GameFixes::ChromaticAberrations },
{ "Volumetric fog", &volumetric_fog_fix_enabled, GameFixes::VolumetricFog }
};
inline std::string toStringPrecision(float value, int precision) {
char buffer[64];
std::snprintf(buffer, sizeof(buffer), ("%." + std::to_string(precision) + "f").c_str(), value);
return std::string(buffer);
}
static FixToggle cheatFixes[] = {
{ "Time dilation", &Time_Dilation_fix_enabled, GameFixes::TimeDilation, "ALT + 1 (top keyboard row) to toggle" },
{ "Stealth mode", &StealthMode_fix_enabled, GameFixes::Stealth, "ALT + 2 (top keyboard row) to toggle." },
};
// Prepare array of sliders for ImGui
static SliderFix sliders[6];
// Load and unload game core dll functions /!\ necessary
static void LoadFixDLL()
{
if (InterlockedCompareExchange(&g_coreInitialized, 1, 0) != 0)
return;
static void LoadFixDLL() {
if (InterlockedCompareExchange(&g_coreInitialized, 1, 0) != 0) return;
if (GetModuleHandleA("SilentHillfCore.dll") == nullptr) {
fixLib = LoadLibraryA("SilentHillfCore.dll");
@@ -88,20 +102,13 @@ static void LoadFixDLL()
}
SetFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetFixEnabled");
SetFOVFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetFOVFixEnabled");
SetDOFFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetDOFFixEnabled");
SetCAFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetCAFixEnabled");
SetVignettingFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetVignettingFixEnabled");
SetVolumetricFogFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetVolumetricFogFixEnabled");
SetFogDensityFixEnabled = (SetBoolFn)GetProcAddress(fixLib,"SetFogDensityFixEnabled");
SetFogMaxOpacityFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetFogMaxOpacityFixEnabled");
SetCameraFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetCameraFixEnabled");
SetCutscenesFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetCutscenesFixEnabled");
SetCutscenesFPSFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetCutscenesFPSFixEnabled");
SetFixes = (SetFixesFn)GetProcAddress(fixLib, "SetFixesEnabled");
SetFOV = (SetIntFn)GetProcAddress(fixLib, "SetFOV");
SetCameraDistance = (SetFloatFn)GetProcAddress(fixLib, "SetCameraDistance");
SetFogDensity = (SetFloatFn)GetProcAddress(fixLib,"SetFogDensity");
SetFogMaxOpacity = (SetFloatFn)GetProcAddress(fixLib, "SetFogMaxOpacity");
SetWorldTimeDilation = (SetFloatFn)GetProcAddress(fixLib, "SetWorldTimeDilation");
SetAITimeDilation = (SetFloatFn)GetProcAddress(fixLib, "SetAITimeDilation");
GetGameInfos = (GetGameInfosStruct)GetProcAddress(fixLib, "GetGameInfos");
// Apply initial values loaded from settings
@@ -109,17 +116,36 @@ static void LoadFixDLL()
if (SetCameraDistance) SetCameraDistance(cameraDistanceValue);
if (SetFogDensity) SetFogDensity(fogDensityValue);
if (SetFogMaxOpacity) SetFogMaxOpacity(fogMaxOpacityValue);
if (SetFOVFixEnabled) SetFOVFixEnabled(fov_fix_enabled, true);
if (SetCameraFixEnabled) SetCameraFixEnabled(camera_fix_enabled, true);
if (SetCutscenesFixEnabled) SetCutscenesFixEnabled(cutscenes_fix_enabled, true);
if (SetCutscenesFPSFixEnabled) SetCutscenesFPSFixEnabled(cutscenes_FPS_fix_enabled, true);
if (SetDOFFixEnabled) SetDOFFixEnabled(DOF_fix_enabled, true);
if (SetCAFixEnabled) SetCAFixEnabled(CA_fix_enabled, true);
if (SetVignettingFixEnabled) SetVignettingFixEnabled(Vignetting_fix_enabled, true);
if (SetVolumetricFogFixEnabled) SetVolumetricFogFixEnabled(volumetric_fog_fix_enabled, true);
if (SetFogDensityFixEnabled) SetFogDensityFixEnabled(Fog_density_fix_enabled, true);
if (SetFogMaxOpacityFixEnabled) SetFogMaxOpacityFixEnabled(Fog_max_opacity_fix_enabled, true);
if (SetWorldTimeDilation) SetWorldTimeDilation(worldTimeDilationValue);
if (SetAITimeDilation) SetAITimeDilation(AITimeDilationValue);
if (SetFixEnabled) SetFixEnabled(fix_enabled, true);
if (SetFixes) {
SetFixes(GameFixes::SkipIntro, skip_Intro_enabled);
SetFixes(GameFixes::FOV, fov_fix_enabled);
SetFixes(GameFixes::Camera, camera_fix_enabled);
SetFixes(GameFixes::Cutscenes, cutscenes_fix_enabled);
SetFixes(GameFixes::Framerate, cutscenes_FPS_fix_enabled);
SetFixes(GameFixes::DOF, DOF_fix_enabled);
SetFixes(GameFixes::ChromaticAberrations, CA_fix_enabled);
SetFixes(GameFixes::Vignetting, Vignetting_fix_enabled);
SetFixes(GameFixes::VolumetricFog, volumetric_fog_fix_enabled);
SetFixes(GameFixes::Fog, Fog_fix_enabled);
SetFixes(GameFixes::TimeDilation, Time_Dilation_fix_enabled);
SetFixes(GameFixes::Stealth, StealthMode_fix_enabled);
SetFixes(GameFixes::DevConsole, console);
}
// Declare sliders only when function pointers are initilized (SetFOV ...)
sliders[0] = { "In game additional FOV", "##FOVValue", SliderType::Int, &worldFOVvalue, -20, 50, SetFOV };
sliders[1] = { "Camera distance (*)", "##CameraOffset", SliderType::Float, &cameraDistanceValue, 0, 3, SetCameraDistance, "%.2f", "Value is a multiplier."};
sliders[2] = { "Fog density (*)", "##FogDensityValue", SliderType::Float, &fogDensityValue, 0, 5, SetFogDensity, "%.2f",
"This will override engine dynamic value." };
sliders[3] = { "Fog opacity (*)", "##CameraSmoothnessValue", SliderType::Float, &fogMaxOpacityValue, 0, 1, SetFogMaxOpacity, "%.2f",
"This will override engine dynamic value." };
sliders[4] = { "World time dilation", "##WorldTimeDilationValue", SliderType::Float, &worldTimeDilationValue, 0.f, 2.f, SetWorldTimeDilation, nullptr,
"Will affect everything in the world.\nDefault value is 1." };
sliders[5] = { "AI time dilation", "##AITimeDilationValue", SliderType::Float, &AITimeDilationValue, 0.f, 2.f, SetAITimeDilation, nullptr,
"Will affect only enemies in the world.\nDefault value is 1." };
}
}
@@ -130,8 +156,12 @@ static void SaveSettings()
pluginIniFile["1#General fix"].setComment(std::vector<std::string>{ "The following sections are saved by plugin",
"You should not need to modify them",
" ",
"Controls if fix mod (globally) is enabled" });
"Controls if fix mod (globally) is enabled",
"Set Console to false if you don't want dev console to be enabled",
"Set Skip Intro to false if you don't wan't to skip them."});
pluginIniFile["1#General fix"]["Console"] = console;
pluginIniFile["1#General fix"]["Enabled"] = fix_enabled;
pluginIniFile["1#General fix"]["Skip Intro"] = skip_Intro_enabled;
pluginIniFile["2#Individual fix"].setComment("Controls each fix individually");
pluginIniFile["2#Individual fix"]["FOV"] = fov_fix_enabled;
pluginIniFile["2#Individual fix"]["Camera"] = camera_fix_enabled;
@@ -141,13 +171,16 @@ static void SaveSettings()
pluginIniFile["2#Individual fix"]["Chromatic aberrations"] = CA_fix_enabled;
pluginIniFile["2#Individual fix"]["Vignetting"] = Vignetting_fix_enabled;
pluginIniFile["2#Individual fix"]["Volumetric fog"] = volumetric_fog_fix_enabled;
pluginIniFile["2#Individual fix"]["Fog density"] = Fog_density_fix_enabled;
pluginIniFile["2#Individual fix"]["Fog opacity"] = Fog_max_opacity_fix_enabled;
pluginIniFile["2#Individual fix"]["Fog"] = Fog_fix_enabled;
pluginIniFile["2#Individual fix"]["Time dilation"] = Time_Dilation_fix_enabled;
pluginIniFile["2#Individual fix"]["Stealth Mode"] = StealthMode_fix_enabled;
pluginIniFile["3#Fixes tuning"].setComment("Individual fix fine tune");
pluginIniFile["3#Fixes tuning"]["World FOV"] = worldFOVvalue;
pluginIniFile["3#Fixes tuning"]["Camera distance"] = cameraDistanceValue;
pluginIniFile["3#Fixes tuning"]["Fog density"] = fogDensityValue;
pluginIniFile["3#Fixes tuning"]["Fog opacity"] = fogMaxOpacityValue;
pluginIniFile["3#Fixes tuning"]["World time dilation scale"] = worldTimeDilationValue;
pluginIniFile["3#Fixes tuning"]["AI time dilation scale"] = AITimeDilationValue;
pluginIniFile.save(SETTINGS_FILE);
}
@@ -157,7 +190,9 @@ static void LoadSettings()
ini::IniFile pluginIniFile;
try {
pluginIniFile.load(SETTINGS_FILE);
console = pluginIniFile["1#General fix"]["Console"].as<bool>();
fix_enabled = pluginIniFile["1#General fix"]["Enabled"].as<bool>();
skip_Intro_enabled = pluginIniFile["1#General fix"]["Skip Intro"].as<bool>();
fov_fix_enabled = pluginIniFile["2#Individual fix"]["FOV"].as<bool>();
camera_fix_enabled = pluginIniFile["2#Individual fix"]["Camera"].as<bool>();
cutscenes_fix_enabled = pluginIniFile["2#Individual fix"]["Cutscenes"].as<bool>();
@@ -166,215 +201,203 @@ static void LoadSettings()
CA_fix_enabled = pluginIniFile["2#Individual fix"]["Chromatic aberrations"].as<bool>();
Vignetting_fix_enabled = pluginIniFile["2#Individual fix"]["Vignetting"].as<bool>();
volumetric_fog_fix_enabled = pluginIniFile["2#Individual fix"]["Volumetric fog"].as<bool>();
Fog_density_fix_enabled = pluginIniFile["2#Individual fix"]["Fog density"].as<bool>();
Fog_max_opacity_fix_enabled = pluginIniFile["2#Individual fix"]["Fog opacity"].as<bool>();
Fog_fix_enabled = pluginIniFile["2#Individual fix"]["Fog"].as<bool>();
Time_Dilation_fix_enabled = pluginIniFile["2#Individual fix"]["Time dilation"].as<bool>();
StealthMode_fix_enabled = pluginIniFile["2#Individual fix"]["Stealth Mode"].as<bool>();
worldFOVvalue = pluginIniFile["3#Fixes tuning"]["World FOV"].as<int>();
cameraDistanceValue = pluginIniFile["3#Fixes tuning"]["Camera distance"].as<float>();
fogDensityValue = pluginIniFile["3#Fixes tuning"]["Fog density"].as<float>();
fogMaxOpacityValue = pluginIniFile["3#Fixes tuning"]["Fog opacity"].as<float>();
worldTimeDilationValue = pluginIniFile["3#Fixes tuning"]["World time dilation scale"].as<float>();
AITimeDilationValue = pluginIniFile["3#Fixes tuning"]["AI time dilation scale"].as<float>();
}
catch (const std::exception& e) {}
}
// Read plugin log file
static std::string read_log_file(const std::string& filename) {
std::ifstream file(filename);
std::string log;
if (!file.is_open()) {
log = "Impossible to open file : " + filename;
return log;
}
std::ostringstream ss;
ss << file.rdbuf();
log = ss.str();
return log;
}
// Reshade event callback functions
static void on_init_swapchain(reshade::api::swapchain* swapchain, bool resize) {
reshade::api::resource backbuffer = swapchain->get_current_back_buffer();
if (backbuffer != 0) {
reshade::api::device* device = swapchain->get_device();
reshade::api::resource_desc desc = device->get_resource_desc(backbuffer);
g_width = desc.texture.width;
g_height = desc.texture.height;
}
}
// Initialize ImGui widgets for Reshade
static void on_overlay_draw(reshade::api::effect_runtime* runtime)
{
ImGuiStyle& style = ImGui::GetStyle();
static void on_overlay_draw(reshade::api::effect_runtime* runtime) {
using namespace ImGui;
float aspectRatio = (float)g_width / g_height;
// Scaling factor based on screen resolution
float scale = std::min((float)g_height / 1200,1.f);
ImGuiStyle& style = GetStyle();
style.ItemSpacing = ImVec2(8 * scale, 8 * scale); // Spacing between widgets
style.FramePadding = ImVec2(3 * scale, 3 * scale); // Widgets padding
style.WindowPadding = ImVec2(10 * scale, 10 * scale); // Overlay padding
style.CellPadding = ImVec2(10 * scale, 10 * scale); // Table cells padding
ImGui::SetNextWindowSize(ImVec2(350 * scale, 150 * scale), ImGuiCond_Once);
SetNextWindowSize(ImVec2(350 * scale, 150 * scale), ImGuiCond_Once);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.84f, 0.12f, 0.51f, 1.0f)); // red
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.84f, 0.12f, 0.51f, 1.0f)); // red
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.84f, 0.2f, 0.51f, 1.0f)); // red
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.8f, 1.f, 1.f, 1.f)); // white
if (ImGui::Button("Like my work ? Consider donation")) ShellExecuteA(NULL, "open", DONATION_URL, NULL, NULL, SW_SHOWNORMAL); // Donation
ImGui::PopStyleColor(4); // Restore color
ImGui::SameLine();
if (ImGui::Button("Fix informations")) popup_Informations = true; // Fix information
if (popup_Informations)
{
ImGui::Begin("Informations", &popup_Informations);
ImGui::Text("Version : %s", FIX_VERSION);
ImGui::Text(FIX_INFORMATIONS);
ImGui::End();
PushStyleColor(ImGuiCol_Button, ImVec4(0.84f, 0.12f, 0.51f, 1.0f)); // red
PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.84f, 0.12f, 0.51f, 1.0f)); // red
PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.84f, 0.2f, 0.51f, 1.0f)); // red
PushStyleColor(ImGuiCol_Text, ImVec4(0.8f, 1.f, 1.f, 1.f)); // white
if (Button("Like my work ? Consider donation")) ShellExecuteA(NULL, "open", DONATION_URL, NULL, NULL, SW_SHOWNORMAL); // Donation
PopStyleColor(4); // Restore color
SameLine();
if (Button("Fix informations")) popup_Informations = true; // Fix information
SameLine();
if (Button("View logs")) {
log_content = read_log_file("SilentHillf.log");
show_log_overlay = true; // Fix information
}
if (ImGui::BeginTable("FixesTable", 2, ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableSetupColumn("LeftFix", ImGuiTableColumnFlags_WidthStretch, 0.3f);
ImGui::TableSetupColumn("RightFix", ImGuiTableColumnFlags_WidthStretch, 0.7f);
ImGui::TableNextRow();
// Drawing a left column with slider and general fix
ImGui::TableSetColumnIndex(0);
if (ImGui::CollapsingHeader("Enable fixes", ImGuiTreeNodeFlags_DefaultOpen))
if (ImGui::Checkbox("Fix enabled", &fix_enabled)) {
if (SetFixEnabled) SetFixEnabled(fix_enabled, false);
SaveSettings();
}
// Individual fixes
ImGui::TableSetColumnIndex(1);
if (ImGui::CollapsingHeader("Individual fixes", ImGuiTreeNodeFlags_DefaultOpen)) {
if (ImGui::BeginTable("IndividualFixesTable", 2, ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableSetupColumn("IndFix1", ImGuiTableColumnFlags_WidthStretch, 0.35f);
ImGui::TableSetupColumn("IndFix2", ImGuiTableColumnFlags_WidthStretch, 0.65f);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
if (ImGui::Checkbox("FOV", &fov_fix_enabled)) {
if (SetFOVFixEnabled) SetFOVFixEnabled(fov_fix_enabled, false);
SaveSettings();
}
if (ImGui::Checkbox("Cutscenes", &cutscenes_fix_enabled)) {
if (SetCutscenesFixEnabled) SetCutscenesFixEnabled(cutscenes_fix_enabled, false);
SaveSettings();
}
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("Must be enabled before playing cutscenes.");
ImGui::EndTooltip();
}
if (ImGui::Checkbox("Vignetting", &Vignetting_fix_enabled)) {
if (SetVignettingFixEnabled) SetVignettingFixEnabled(Vignetting_fix_enabled, false);
SaveSettings();
}
if (ImGui::Checkbox("Fog density", &Fog_density_fix_enabled)) {
if (SetFogDensityFixEnabled) SetFogDensityFixEnabled(Fog_density_fix_enabled, false);
SaveSettings();
}
if (ImGui::Checkbox("Fog opacity", &Fog_max_opacity_fix_enabled)) {
if (SetFogMaxOpacityFixEnabled) SetFogMaxOpacityFixEnabled(Fog_max_opacity_fix_enabled, false);
SaveSettings();
}
ImGui::TableSetColumnIndex(1);
if (ImGui::Checkbox("Camera", &camera_fix_enabled)) {
if (SetCameraFixEnabled) SetCameraFixEnabled(camera_fix_enabled, false);
SaveSettings();
}
if (ImGui::Checkbox("Cutscenes FPS", &cutscenes_FPS_fix_enabled)) {
if (SetCutscenesFPSFixEnabled) SetCutscenesFPSFixEnabled(cutscenes_FPS_fix_enabled, false);
SaveSettings();
}
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("Must be enabled before playing cutscenes.");
ImGui::EndTooltip();
}
if (ImGui::Checkbox("Depth of field", &DOF_fix_enabled)) {
if (SetDOFFixEnabled) SetDOFFixEnabled(DOF_fix_enabled, false);
SaveSettings();
}
if (ImGui::Checkbox("Chromatic aberrations", &CA_fix_enabled)) {
if (SetCAFixEnabled) SetCAFixEnabled(CA_fix_enabled, false);
SaveSettings();
}
if (ImGui::Checkbox("Volumetric fog", &volumetric_fog_fix_enabled)) {
if (SetVolumetricFogFixEnabled) SetVolumetricFogFixEnabled(volumetric_fog_fix_enabled, false);
SaveSettings();
}
ImGui::EndTable();
}
}
ImGui::EndTable();
if (popup_Informations) {
Begin("Informations", &popup_Informations, ImGuiWindowFlags_AlwaysAutoResize);
Text("Version : %s", FIX_VERSION);
Text(FIX_INFORMATIONS);
End();
}
if (show_log_overlay) {
Begin("Game log", &show_log_overlay, ImGuiWindowFlags_AlwaysAutoResize);
TextUnformatted(log_content.c_str());
End();
}
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 2 * style.ItemSpacing.y);
if (ImGui::BeginTable("FixesSliders", 2, ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableNextRow();
// Sliders
ImGui::TableSetColumnIndex(0);
if (ImGui::CollapsingHeader("In game additional FOV", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::SetNextItemWidth(180 * scale);
if (ImGui::SliderInt("##FOVValue", &worldFOVvalue, -20, 50)) {
if (SetFOV) SetFOV(worldFOVvalue);
SaveSettings();
if (BeginTabBar("MainTabs")) {
if (BeginTabItem("Fixes")) {
if (BeginTable("FixesTable", 2, ImGuiTableFlags_SizingStretchSame)) {
TableSetupColumn("LeftFix", ImGuiTableColumnFlags_WidthStretch, 0.3f);
TableSetupColumn("RightFix", ImGuiTableColumnFlags_WidthStretch, 0.7f);
TableNextRow();
// Drawing a left column with slider and general fix
TableSetColumnIndex(0);
if (CollapsingHeader("Enable fixes", ImGuiTreeNodeFlags_DefaultOpen))
if (Checkbox("Fix enabled", &fix_enabled)) {
if (SetFixEnabled) SetFixEnabled(fix_enabled, false);
SaveSettings();
}
// Individual fixes
TableSetColumnIndex(1);
if (CollapsingHeader("Individual fixes", ImGuiTreeNodeFlags_DefaultOpen)) {
if (BeginTable("IndividualFixesTable", 2, ImGuiTableFlags_SizingStretchSame)) {
TableSetupColumn("IndFix1", ImGuiTableColumnFlags_WidthStretch, 0.35f);
TableSetupColumn("IndFix2", ImGuiTableColumnFlags_WidthStretch, 0.65f);
TableNextRow();
TableSetColumnIndex(0);
for (int i = 0; i < 4; ++i) DrawFixCheckbox(individualFixes[i]);
TableSetColumnIndex(1);
for (int i = 4; i < IM_ARRAYSIZE(individualFixes); ++i) DrawFixCheckbox(individualFixes[i]);
EndTable();
}
}
EndTable();
}
}
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("This will affect in game FOV only.");
ImGui::EndTooltip();
SetCursorPosY(GetCursorPosY() - 2 * style.ItemSpacing.y);
if (BeginTable("FixesSliders", 2, ImGuiTableFlags_SizingStretchSame)) {
TableNextRow();
// Sliders
TableSetColumnIndex(0);
for (int i = 0; i < 2; ++i) DrawSlider(sliders[i], 200);
TableSetColumnIndex(1);
for (int i = 2; i < 4; ++i) DrawSlider(sliders[i], 200);
EndTable();
}
EndTabItem();
}
if (ImGui::CollapsingHeader("Camera distance (*)", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::SetNextItemWidth(180 * scale);
if (ImGui::SliderFloat("##CameraDistanceValue", &cameraDistanceValue, 0, 3, "%.2f")) {
if (SetCameraDistance) SetCameraDistance(cameraDistanceValue);
SaveSettings();
}
}
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("Value is a multiplier.");
ImGui::EndTooltip();
}
if (BeginTabItem("Cheats")){
for (const auto& cheat : cheatFixes) DrawFixCheckbox(cheat);
ImGui::TableSetColumnIndex(1);
if (ImGui::CollapsingHeader("Fog density (*)", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::SetNextItemWidth(180 * scale);
if (ImGui::SliderFloat("##FogDensityValue", &fogDensityValue, 0, 5, "%.2f")) {
if (SetFogDensity) SetFogDensity(fogDensityValue);
SaveSettings();
}
}
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("This will override engine dynamic value.");
ImGui::EndTooltip();
}
if (BeginTable("SlidersTable", 2, ImGuiTableFlags_SizingStretchSame)) {
TableSetupColumn("LeftSliders", ImGuiTableColumnFlags_WidthStretch, 0.5f);
TableSetupColumn("RightSliders", ImGuiTableColumnFlags_WidthStretch, 0.5f);
TableNextRow();
if (ImGui::CollapsingHeader("Fog opacity (*)", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::SetNextItemWidth(180 * scale);
if (ImGui::SliderFloat("##FogOpacityValue", &fogMaxOpacityValue, 0, 1, "%.2f")) {
if (SetFogMaxOpacity) SetFogMaxOpacity(fogMaxOpacityValue);
SaveSettings();
TableSetColumnIndex(0);
DrawSlider(sliders[4], 180);
TableSetColumnIndex(1);
DrawSlider(sliders[5], 180);
EndTable();
}
EndTabItem();
}
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("This will override engine dynamic value.");
ImGui::EndTooltip();
}
ImGui::EndTable();
}
EndTabBar();
// Fix status
if (ImGui::CollapsingHeader("Fix informations", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Text("Screen width: %d, height: %d, aspect ratio: %.2f", screenWidth, screenHeight, aspectRatio);
if (GetGameInfos) {
GameInfos infos{};
GetGameInfos(&infos);
if (infos.consoleEnabled)
ImGui::Text("Console enabled and bound to key Tilde");
ImGui::TextColored(ImColor(48, 179, 25), "FOV In: %.2f, Out: %.2f", infos.FOVIn, infos.FOVOut);
ImGui::TextColored(ImColor(48, 179, 25), "Camera distance In: %.2f, Out: %.2f", infos.cameraIn, infos.cameraOut);
ImGui::TextColored(ImColor(48, 179, 25), "Default fog density: %.3f, opacity: %3.f", infos.defaultFogDensity, infos.fogMaxOpacity);
// Fix status
if (CollapsingHeader("Fix informations", ImGuiTreeNodeFlags_DefaultOpen)) {
Text("Screen width: %d, height: %d, aspect ratio: %.2f", g_width, g_height, aspectRatio);
if (GetGameInfos) {
GameInfos infos{};
GetGameInfos(&infos);
if (infos.consoleEnabled)
Text("Console enabled and bound to key F2");
TextColored(ImColor(48, 179, 25), "FOV In: %.2f, Out: %.2f", infos.FOVIn, infos.FOVOut);
TextColored(ImColor(48, 179, 25), "Camera distance In: %.2f, Out: %.2f", infos.cameraIn, infos.cameraOut);
TextColored(ImColor(48, 179, 25), "Default fog density: %.3f, opacity: %3.f", infos.defaultFogDensity, infos.fogMaxOpacity);
}
}
}
}
static void on_reshade_present(reshade::api::effect_runtime* runtime) {
static auto last = std::chrono::steady_clock::now();
auto now = std::chrono::steady_clock::now();
float dt = std::chrono::duration<float>(now - last).count();
last = now;
ProcessHotkeys(runtime);
UpdateOSD(runtime, dt);
}
// Retrieve all shader uniform variables
static void on_reshade_begin_effects(reshade::api::effect_runtime* runtime, reshade::api::command_list* cmd_list,
reshade::api::resource_view rtv, reshade::api::resource_view rtv_srgb) {
if (!runtime) return;
FindAllUniformVariables(runtime, OSD_SHADER_NAME); // Find all uniforms and set their handle
if (InterlockedCompareExchange(&g_uniformReseted, 1, 0) != 0) return; // reset OSD uniforms once
ResetAllUniformVariables(runtime, OSD_SHADER_NAME);
runtime->save_current_preset(); // Save shader preset
}
static void InitializeHotkeys() { // Initialize hotkeys for cheats
if (InterlockedCompareExchange(&g_hotkeysInitialized, 1, 0) != 0) return; // Initialize hotkeys once
RegisterHotkey('1', Modifier::Alt, [] {
ToggleOSD(Time_Dilation_fix_enabled, GameFixes::TimeDilation,
u_td_show, u_td_enabled, OSD_duration,
{ {u_td_world, worldTimeDilationValue}, {u_td_AI, AITimeDilationValue} });
});
RegisterHotkey('2', Modifier::Alt, [] {
ToggleOSD(StealthMode_fix_enabled, GameFixes::Stealth, u_Stealth_show, u_Stealth_enabled, OSD_duration);
});
}
// Main dll intrance
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID)
{
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID) {
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
@@ -383,12 +406,19 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID)
LoadSettings();
reshade::register_overlay("Silent Hill f", &on_overlay_draw);
reshade::register_event<reshade::addon_event::init_swapchain>(on_init_swapchain);
reshade::register_event<reshade::addon_event::init_effect_runtime>(
[](reshade::api::effect_runtime* runtime) {
LoadFixDLL();
InitializeHotkeys();
});
reshade::register_event<reshade::addon_event::reshade_present>(&on_reshade_present);
reshade::register_event<reshade::addon_event::reshade_begin_effects>(&on_reshade_begin_effects);
break;
case DLL_PROCESS_DETACH:
reshade::unregister_event<reshade::addon_event::reshade_present>(&on_reshade_present);
reshade::unregister_event<reshade::addon_event::reshade_begin_effects>(&on_reshade_begin_effects);
reshade::unregister_event<reshade::addon_event::init_swapchain>(on_init_swapchain);
reshade::unregister_addon(hinstDLL);
break;
}