diff --git a/SilentHillf/SilentHillf.vcxproj b/SilentHillf/SilentHillf.vcxproj new file mode 100644 index 0000000..0bf4e84 --- /dev/null +++ b/SilentHillf/SilentHillf.vcxproj @@ -0,0 +1,161 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {122F77EF-8C36-43EA-96FA-3D0D3851CF01} + Silent Hill f + 10.0 + Silent Hill f + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + false + Unicode + + + + + + + + + + + + + + + + + + + + + .addon + SilentHillfUI + + + .addon + SilentHillfUI + + + .addon + SilentHillfUI + + + .addon + SilentHillfUI + + + + Level3 + true + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SolutionDir)external\reshade\include;$(SolutionDir)external\reshade\deps\imgui + MultiThreadedDLL + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SolutionDir)external\reshade\include;$(SolutionDir)external\reshade\deps\imgui + MultiThreadedDLL + + + Windows + true + false + + + + + Level3 + true + _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SolutionDir)external\reshade\include;$(SolutionDir)external\reshade\deps\imgui + MultiThreadedDLL + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(SolutionDir)external\reshade\include;$(SolutionDir)external\reshade\deps\imgui + MultiThreadedDLL + true + + + Windows + true + false + + + + + + + + + \ No newline at end of file diff --git a/SilentHillf/dllmain.cpp b/SilentHillf/dllmain.cpp new file mode 100644 index 0000000..3dc6a33 --- /dev/null +++ b/SilentHillf/dllmain.cpp @@ -0,0 +1,300 @@ +#define IMGUI_DISABLE_INCLUDE_IMCONFIG_H +#define IMGUI_HAS_DOCK 1 + +#include +#include +#include +#include +#include + +// Screen informations +static int screenWidth = GetSystemMetrics(SM_CXSCREEN); +static int screenHeight = GetSystemMetrics(SM_CYSCREEN); +static float aspectRatio = (float)screenWidth / screenHeight; + +// Core game dll functions declarations +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 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 SetFogFixEnabled = nullptr; +static SetIntFn SetFOV = nullptr; + +static GetFloatFn GetFOVIn = nullptr; +static GetFloatFn GetFOVOut = nullptr; +static GetBoolFn GetConsoleEnabled = nullptr; + +// Plugin variables for checkboxes and sliders +static bool fov_fix_enabled = false; +static bool DOF_fix_enabled = false; +static bool CA_fix_enabled = false; +static bool Vignetting_fix_enabled = false; +static bool camera_fix_enabled = false; +static bool Fog_fix_enabled = false; +static bool fix_enabled = false; +static int worldFOVvalue = 0; + +static bool popup_Informations = false; + +// Plugin settings +const char* SETTINGS_FILE = "PluginSettings.ini"; +const char* GENERAL_FIX_SETTING = "GeneralFIX="; +const char* WORLD_FOV_FIX_SETTING = "WorldFOVFIX="; +const char* ASPECT_FIX_SETTING = "AspectFIX="; +const char* CAMERA_FIX_SETTING = "CameraFIX="; +const char* HUD_FIX_SETTING = "HUDFIX="; +const char* DOF_FIX_SETTING = "DOFFIX="; +const char* CA_FIX_SETTING = "CAFIX="; +const char* VIGNETTING_FIX_SETTING = "VignettingFIX="; +const char* FOG_FIX_SETTING = "FogFIX="; +const char* WORLD_FOV_SETTING = "WorldFOV="; +const char* CAMERA_DISTANCE_SETTING = "CameraDistance="; +const char* CAMERA_HEIGHT_SETTING = "CameraHeight="; +const char* HUD_SETTING = "HUDValue="; +const char* FIX_VERSION = "1.0.1"; +const char* FIX_INFORMATIONS = "This fix allows to:\n - Control FOV in game.\n - Disable depth of field.\n - Disable chromatic aberrations.\n - Disable vignetting.\n - Disable fog.\n - Re enable console.\n\nDisabling Fog will not entirely remove it."; +const char* DONATION_URL = "https://buymeacoffee.com/k4sh44"; + +// Scaling factor based on screen resolution +float scale = 1.f; + +// Load and unload game core dll functions /!\ necessary +static void LoadFixDLL() +{ + if (InterlockedCompareExchange(&g_coreInitialized, 1, 0) != 0) + return; + + if (GetModuleHandleA("SilentHillfCore.dll") == nullptr) { + fixLib = LoadLibraryA("SilentHillfCore.dll"); + + if (!fixLib) { + MessageBoxA(nullptr, "Impossible to load game core dll", "Erreur", MB_OK); + return; + } + + 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"); + SetFogFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetFogFixEnabled"); + //SetCameraFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetCameraFixEnabled"); + SetFOV = (SetIntFn)GetProcAddress(fixLib, "SetFOV"); + GetFOVIn = (GetFloatFn)GetProcAddress(fixLib, "GetFOVIn"); + GetFOVOut = (GetFloatFn)GetProcAddress(fixLib, "GetFOVOut");; + GetConsoleEnabled = (GetBoolFn)GetProcAddress(fixLib, "GetConsoleEnabled"); + + // Apply initial values loaded from settings + if (SetFOV) SetFOV(worldFOVvalue); + if (SetFOVFixEnabled) SetFOVFixEnabled(fov_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 (SetFogFixEnabled) SetFogFixEnabled(Fog_fix_enabled, true); + if (SetFixEnabled) SetFixEnabled(fix_enabled, true); + } +} + +// Settings functions +static void SaveSettings() +{ + std::ofstream file(SETTINGS_FILE); + if (file.is_open()) + { + file << GENERAL_FIX_SETTING << (fix_enabled ? "1" : "0") << "\n"; + file << WORLD_FOV_FIX_SETTING << (fov_fix_enabled ? "1" : "0") << "\n"; + file << DOF_FIX_SETTING << (DOF_fix_enabled ? "1" : "0") << "\n"; + file << CA_FIX_SETTING << (CA_fix_enabled ? "1" : "0") << "\n"; + file << VIGNETTING_FIX_SETTING << (Vignetting_fix_enabled ? "1" : "0") << "\n"; + file << FOG_FIX_SETTING << (Fog_fix_enabled ? "1" : "0") << "\n"; + file << WORLD_FOV_SETTING << worldFOVvalue << "\n"; + file.close(); + } +} + +static void LoadSettings() +{ + std::ifstream file(SETTINGS_FILE); + if (file.is_open()) + { + std::string line; + while (std::getline(file, line)) + { + if (line.find(GENERAL_FIX_SETTING) == 0) + { + std::string val = line.substr(strlen(GENERAL_FIX_SETTING)); + fix_enabled = (val == "1" || val == "true"); + } + else if (line.find(WORLD_FOV_FIX_SETTING) == 0) + { + std::string val = line.substr(strlen(WORLD_FOV_FIX_SETTING)); + fov_fix_enabled = (val == "1" || val == "true"); + } + else if (line.find(DOF_FIX_SETTING) == 0) + { + std::string val = line.substr(strlen(DOF_FIX_SETTING)); + DOF_fix_enabled = (val == "1" || val == "true"); + } + else if (line.find(CA_FIX_SETTING) == 0) + { + std::string val = line.substr(strlen(CA_FIX_SETTING)); + CA_fix_enabled = (val == "1" || val == "true"); + } + else if (line.find(VIGNETTING_FIX_SETTING) == 0) + { + std::string val = line.substr(strlen(VIGNETTING_FIX_SETTING)); + Vignetting_fix_enabled = (val == "1" || val == "true"); + } + else if (line.find(FOG_FIX_SETTING) == 0) + { + std::string val = line.substr(strlen(FOG_FIX_SETTING)); + Fog_fix_enabled = (val == "1" || val == "true"); + } + else if (line.find(WORLD_FOV_SETTING) == 0) + worldFOVvalue = std::stoi(line.substr(strlen(WORLD_FOV_SETTING))); + } + file.close(); + } +} + +// Initialize ImGui widgets for Reshade +static void on_overlay_draw(reshade::api::effect_runtime* runtime) +{ + ImGuiStyle& style = ImGui::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); + + if (ImGui::Button("Like my work ? Consider donation")) ShellExecuteA(NULL, "open", DONATION_URL, NULL, NULL, SW_SHOWNORMAL); // Donation + 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(); + } + + if (ImGui::BeginTable("FixesTable", 2, ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("LeftFix", ImGuiTableColumnFlags_WidthStretch, 0.4f); + ImGui::TableSetupColumn("RightFix", ImGuiTableColumnFlags_WidthStretch, 0.6f); + 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(); + } + + // Sliders + if (ImGui::CollapsingHeader("In game additional FOV", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::SetNextItemWidth(150 * scale); + if (ImGui::SliderInt("##FOVValue", &worldFOVvalue, -20, 50)) { + if (SetFOV) SetFOV(worldFOVvalue); + 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("Vignetting", &Vignetting_fix_enabled)) { + if (SetVignettingFixEnabled) SetVignettingFixEnabled(Vignetting_fix_enabled, false); + SaveSettings(); + } + + if (ImGui::Checkbox("Fog", &Fog_fix_enabled)) { + if (SetFogFixEnabled) SetFogFixEnabled(Fog_fix_enabled, false); + SaveSettings(); + } + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Enabling this fix is a one way."); + ImGui::Text("Reverting it in real time would end in game crash."); + ImGui::Text("So disabling this fix is only possible by doing it here and restart the game."); + ImGui::EndTooltip(); + } + + ImGui::TableSetColumnIndex(1); + + 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("Camera", &camera_fix_enabled)) { + // if (SetCameraFixEnabled) SetCameraFixEnabled(camera_fix_enabled, false); + // SaveSettings(); + //} + ImGui::EndTable(); + } + } + ImGui::EndTable(); + } + + // Fix status + if (ImGui::CollapsingHeader("Fix informations", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::Text("Screen width: %d, height: %d, aspect ratio: %.2f", screenWidth, screenHeight, aspectRatio); + if (GetConsoleEnabled && GetConsoleEnabled()) + ImGui::Text("Console enabled and bound to key Tilde"); + if (GetFOVIn && GetFOVOut) + ImGui::TextColored(ImColor(48, 179, 25), "FOV In: %.2f, Out: %.2f", GetFOVIn(), GetFOVOut()); + } +} + +// Main dll intrance +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + if (!reshade::register_addon(hinstDLL)) + return FALSE; + LoadSettings(); + + reshade::register_overlay("Silent Hill f", &on_overlay_draw); + reshade::register_event( + [](reshade::api::effect_runtime* runtime) { + LoadFixDLL(); + }); + break; + case DLL_PROCESS_DETACH: + reshade::unregister_addon(hinstDLL); + break; + } + return TRUE; +} \ No newline at end of file