Compare commits

..

18 Commits

Author SHA1 Message Date
a9bacaab05 Add cutscenes framerate unlock. Fog fix rewritten 2026-01-15 18:57:45 +01:00
f5532b0ebb Add build optimizations 2026-01-15 18:56:19 +01:00
e00b9f09a5 Add fixes and cheats. Code refactoring 2026-01-10 10:40:09 +01:00
d685831add Add lib dependencies and optimizations 2026-01-10 10:39:04 +01:00
0992b91f65 Change cheat name 2026-01-06 11:37:29 +01:00
9a87acba34 Change cheat name 2026-01-06 11:20:06 +01:00
bd5d04fc44 Change cheat name 2026-01-06 11:19:06 +01:00
bb8b38a24f Add all uniform variables. Add find all uniform variables 2026-01-06 10:03:13 +01:00
03b3520523 Add all uniform variables. Add find all uniform variables 2026-01-06 10:02:40 +01:00
5aac823264 Code refactoring 2026-01-06 09:59:39 +01:00
5647e57559 Cheats tooltip description change 2026-01-05 22:11:29 +01:00
3378ba51c4 Add stealth cheat. Code refactoring 2026-01-05 21:21:39 +01:00
04e38c80d6 Add Reshade include 2026-01-05 21:20:10 +01:00
e7835848e4 Add common headers 2026-01-05 21:19:29 +01:00
b4a04d6346 Add cheat toggle function 2026-01-05 21:16:02 +01:00
5b0aa777a7 Add stealth cheat enumeration 2026-01-05 21:14:57 +01:00
7ea8806501 Add stealth cheat on OSD 2026-01-05 21:14:17 +01:00
d59cb679f1 Add common header include. Add shaders 2026-01-05 21:11:28 +01:00
12 changed files with 668 additions and 465 deletions

View File

@@ -47,6 +47,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Silent Hill f", "SilentHill
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "includes", "includes", "{3514D178-6BD5-4744-849B-517AAE8343D4}"
ProjectSection(SolutionItems) = preProject
includes\CommonHeaders.h = includes\CommonHeaders.h
includes\GameFixes.h = includes\GameFixes.h
includes\GameInformations.h = includes\GameInformations.h
includes\HotkeysManager.h = includes\HotkeysManager.h
@@ -93,6 +94,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sleep Awake", "SleepAwake\S
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "The Callisto Protocol", "The Callisto Protocol\TheCallistoProtocol.vcxproj", "{D2A82694-26E2-49E8-9AB0-99E26D40AFCF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shaders", "Shaders", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
ProjectSection(SolutionItems) = preProject
external\reshade\shaders\OSD.fx = external\reshade\shaders\OSD.fx
external\reshade\shaders\ReShade.fxh = external\reshade\shaders\ReShade.fxh
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64

View File

@@ -100,10 +100,9 @@
<LanguageStandard>stdcpp20</LanguageStandard>
<WholeProgramOptimization>true</WholeProgramOptimization>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<IntrinsicFunctions>false</IntrinsicFunctions>
<OmitFramePointers>true</OmitFramePointers>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@@ -117,7 +116,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
@@ -125,10 +124,9 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<LanguageStandard>stdcpp20</LanguageStandard>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization>
<OmitFramePointers>true</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@@ -149,10 +147,9 @@
<LanguageStandard>stdcpp20</LanguageStandard>
<WholeProgramOptimization>true</WholeProgramOptimization>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<IntrinsicFunctions>false</IntrinsicFunctions>
<OmitFramePointers>true</OmitFramePointers>
<IntrinsicFunctions>true</IntrinsicFunctions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@@ -166,7 +163,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
@@ -175,9 +172,8 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<LanguageStandard>stdcpp20</LanguageStandard>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>

View File

@@ -1,12 +1,7 @@
#define IMGUI_DISABLE_INCLUDE_IMCONFIG_H
#define IMGUI_HAS_DOCK 1
#include "GameInformations.h"
#include "GameFixes.h"
#include "inicpp.h"
#include <imgui.h>
#include <reshade.hpp>
#include <string>
#include "CommonHeaders.h"
#include <Windows.h>
// Screen informations
@@ -23,14 +18,19 @@ typedef void (*SetFloatFn)(float);
static HMODULE fixLib = nullptr;
static LONG g_coreInitialized = 0;
static SetBoolFn SetFixEnabled = nullptr;
static SetFixesFn SetFixesEnabled = nullptr;
static SetFixesFn SetFixes = nullptr;
static SetIntFn SetFOV = nullptr;
static SetFloatFn SetCameraDistance = nullptr;
static SetFloatFn SetFogDensity = nullptr;
static SetFloatFn SetFogMaxOpacity = nullptr;
static GetGameInfosStruct GetGameInfos = nullptr;
void SetFixesEnabled(GameFixes fix, bool value) { if (SetFixes) SetFixes(fix, value); }
// Plugin variables for checkboxes and sliders
static bool fov_fix_enabled = false;
static bool ultrawide_fix_enabled = false;
static bool cutscenes_FPS_fix_enabled = false;
static bool camera_fix_enabled = false;
static bool DOF_fix_enabled = false;
static bool CA_fix_enabled = false;
@@ -40,6 +40,8 @@ static bool fix_enabled = false;
static bool console = true;
static int worldFOVvalue = 0.f;
static float CameraDistancevalue = 1.f;
static float fogDensityValue = 0.15f;
static float fogMaxOpacityValue = 1.f;
// Overlays popups
static bool popup_Informations = false;
@@ -48,12 +50,26 @@ static std::string log_content;
// Plugin settings
const std::string SETTINGS_FILE = "./pluginsettings.ini";
const char* FIX_VERSION = "1.0.1";
const char* FIX_INFORMATIONS = "This fix allows to:\n - Control FOV in game.\n - Enable ultrawide in custcenes.\n - Control camera distance.\n - Disable depth of field.\n - Disable chromatic aberrations.\n - Disable vignetting.\n - Disable fog.\n - Re enable dev console.";
const char* FIX_VERSION = "1.0.2";
const char* FIX_INFORMATIONS = "This fix allows to:\n - Control FOV in game.\n - Enable ultrawide in custcenes.\n - Unlock cutscenes framerate.\n - Control camera distance.\n - Disable depth of field.\n - Disable chromatic aberrations.\n - Disable vignetting.\n - Disable fog.\n - Re enable dev console.";
const char* DONATION_URL = "https://buymeacoffee.com/k4sh44";
// Prepare arrays of checkboxes for ImGui
static FixToggle individualFixes[] = {
{ "FOV", &fov_fix_enabled, GameFixes::FOV },
{ "Ultrawide", &ultrawide_fix_enabled, GameFixes::UltraWide, "This fix is intended for ultrawide displays only (21/9, 32/9 ...)."},
{ "Vignetting", &Vignetting_fix_enabled, GameFixes::Vignetting },
{ "Fog", &Fog_fix_enabled, GameFixes::Fog },
{ "Cutscenes FPS", &cutscenes_FPS_fix_enabled, GameFixes::Framerate, "Unlock cutscenes up to 240 FPS"},
{ "Camera distance", &camera_fix_enabled, GameFixes::Camera },
{ "Depth of field", &DOF_fix_enabled, GameFixes::DOF },
{ "Chromatic aberrations", &CA_fix_enabled, GameFixes::ChromaticAberrations }
};
// Scaling factor based on screen resolution
float scale = (float)screenHeight / 1200;
// Prepare array of sliders for ImGui
static SliderFix sliders[4];
// Load and unload game core dll functions /!\ necessary
static void LoadFixDLL()
@@ -70,25 +86,37 @@ static void LoadFixDLL()
}
SetFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetFixEnabled");
SetFixesEnabled = (SetFixesFn)GetProcAddress(fixLib, "SetFixesEnabled");
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");
GetGameInfos = (GetGameInfosStruct)GetProcAddress(fixLib, "GetGameInfos");
// Apply initial values loaded from settings
if (SetFOV) SetFOV(worldFOVvalue);
if (SetCameraDistance) SetCameraDistance(CameraDistancevalue);
if (SetFogDensity) SetFogDensity(fogDensityValue);
if (SetFogMaxOpacity) SetFogMaxOpacity(fogMaxOpacityValue);
if (SetFixEnabled) SetFixEnabled(fix_enabled, true);
if (SetFixesEnabled) {
SetFixesEnabled(GameFixes::FOV, fov_fix_enabled);
SetFixesEnabled(GameFixes::UltraWide, ultrawide_fix_enabled);
SetFixesEnabled(GameFixes::Camera, camera_fix_enabled);
SetFixesEnabled(GameFixes::DOF, DOF_fix_enabled);
SetFixesEnabled(GameFixes::ChromaticAberrations, CA_fix_enabled);
SetFixesEnabled(GameFixes::Vignetting, Vignetting_fix_enabled);
SetFixesEnabled(GameFixes::Fog, Fog_fix_enabled);
SetFixesEnabled(GameFixes::DevConsole, console);
if (SetFixes) {
SetFixes(GameFixes::FOV, fov_fix_enabled);
SetFixes(GameFixes::UltraWide, ultrawide_fix_enabled);
SetFixes(GameFixes::Framerate, cutscenes_FPS_fix_enabled);
SetFixes(GameFixes::Camera, camera_fix_enabled);
SetFixes(GameFixes::DOF, DOF_fix_enabled);
SetFixes(GameFixes::ChromaticAberrations, CA_fix_enabled);
SetFixes(GameFixes::Vignetting, Vignetting_fix_enabled);
SetFixes(GameFixes::Fog, Fog_fix_enabled);
SetFixes(GameFixes::DevConsole, console);
}
sliders[0] = { "In game additional FOV", "##FOVValue", SliderType::Int, &worldFOVvalue, -20, 70, SetFOV };
sliders[1] = { "Camera distance (*)", "##CameraOffset", SliderType::Float, &CameraDistancevalue, 0, 4, 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 (*)", "##FogOpacityValue", SliderType::Float, &fogMaxOpacityValue, 0, 1, SetFogMaxOpacity, "%.2f",
"This will override engine dynamic value." };
}
}
@@ -111,15 +139,17 @@ static void SaveSettings()
pluginIniFile["2#Individual fix"]["Chromatic aberrations"] = CA_fix_enabled;
pluginIniFile["2#Individual fix"]["Vignetting"] = Vignetting_fix_enabled;
pluginIniFile["2#Individual fix"]["Fog"] = Fog_fix_enabled;
pluginIniFile["2#Individual fix"]["Cutscenes FPS"] = cutscenes_FPS_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.save(SETTINGS_FILE);
}
static void LoadSettings()
{
static void LoadSettings() {
ini::IniFile pluginIniFile;
try {
pluginIniFile.load(SETTINGS_FILE);
@@ -132,8 +162,12 @@ static void LoadSettings()
CA_fix_enabled = pluginIniFile["2#Individual fix"]["Chromatic aberrations"].as<bool>();
Vignetting_fix_enabled = pluginIniFile["2#Individual fix"]["Vignetting"].as<bool>();
Fog_fix_enabled = pluginIniFile["2#Individual fix"]["Fog"].as<bool>();
cutscenes_FPS_fix_enabled = pluginIniFile["2#Individual fix"]["Cutscenes FPS"].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>();
}
catch (const std::exception& e) {}
}
@@ -153,8 +187,7 @@ void read_log_file(const std::string& filename) {
}
// Initialize ImGui widgets for Reshade
static void on_overlay_draw(reshade::api::effect_runtime* runtime)
{
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
@@ -177,16 +210,14 @@ static void on_overlay_draw(reshade::api::effect_runtime* runtime)
show_log_overlay = true; // Fix information
}
if (popup_Informations)
{
if (popup_Informations) {
ImGui::Begin("Informations", &popup_Informations, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::Text("Version : %s", FIX_VERSION);
ImGui::Text(FIX_INFORMATIONS);
ImGui::End();
}
if (show_log_overlay)
{
if (show_log_overlay) {
ImGui::Begin("Game log", &show_log_overlay, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::TextUnformatted(log_content.c_str());
ImGui::End();
@@ -204,31 +235,6 @@ static void on_overlay_draw(reshade::api::effect_runtime* runtime)
if (SetFixEnabled) SetFixEnabled(fix_enabled, false);
SaveSettings();
}
// Sliders
ImGui::TableSetColumnIndex(0);
if (ImGui::CollapsingHeader("In game additional FOV", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::SetNextItemWidth(180 * scale);
if (ImGui::SliderInt("##FOVValue", &worldFOVvalue, -20, 70)) {
if (SetFOV) SetFOV(worldFOVvalue);
SaveSettings();
}
}
if (ImGui::CollapsingHeader("Camera distance (*)", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::SetNextItemWidth(150 * scale);
if (ImGui::SliderFloat("##CameraValue", &CameraDistancevalue, 0, 4, "%.2f")) {
if (SetCameraDistance) SetCameraDistance(CameraDistancevalue); SaveSettings();
}
}
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("Value is a multiplier.");
ImGui::EndTooltip();
}
// Individual fixes
ImGui::TableSetColumnIndex(1);
if (ImGui::CollapsingHeader("Individual fixes", ImGuiTreeNodeFlags_DefaultOpen)) {
@@ -238,58 +244,27 @@ static void on_overlay_draw(reshade::api::effect_runtime* runtime)
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
if (ImGui::Checkbox("FOV", &fov_fix_enabled)) {
if (SetFixesEnabled) SetFixesEnabled(GameFixes::FOV, fov_fix_enabled);
SaveSettings();
}
if (ImGui::Checkbox("Vignetting", &Vignetting_fix_enabled)) {
if (SetFixesEnabled) SetFixesEnabled(GameFixes::Vignetting, Vignetting_fix_enabled);
SaveSettings();
}
if (ImGui::Checkbox("Fog", &Fog_fix_enabled)) {
if (SetFixesEnabled) SetFixesEnabled(GameFixes::Fog, Fog_fix_enabled);
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();
}
for (int i = 0; i < 4; ++i) DrawFixCheckbox(individualFixes[i]);
ImGui::TableSetColumnIndex(1);
if (ImGui::Checkbox("Ultrawide", &ultrawide_fix_enabled)) {
if (SetFixesEnabled) SetFixesEnabled(GameFixes::UltraWide, ultrawide_fix_enabled);
SaveSettings();
}
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::Text("This fix is intended for ultrawide displays only (21/9, 32/9 ...).");
ImGui::EndTooltip();
}
for (int i = 4; i < IM_ARRAYSIZE(individualFixes); ++i) DrawFixCheckbox(individualFixes[i]);
if (ImGui::Checkbox("Camera distance", &camera_fix_enabled)) {
if (SetFixesEnabled) SetFixesEnabled(GameFixes::Camera, camera_fix_enabled);
SaveSettings();
}
if (ImGui::Checkbox("Depth of field", &DOF_fix_enabled)) {
if (SetFixesEnabled) SetFixesEnabled(GameFixes::DOF, DOF_fix_enabled);
SaveSettings();
}
if (ImGui::Checkbox("Chromatic aberrations", &CA_fix_enabled)) {
if (SetFixesEnabled) SetFixesEnabled(GameFixes::ChromaticAberrations ,CA_fix_enabled);
SaveSettings();
}
ImGui::EndTable();
}
}
ImGui::EndTable();
}
// Draw individual fix sliders
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 2 * style.ItemSpacing.y);
if (ImGui::BeginTable("FixesSliders", 2, ImGuiTableFlags_SizingStretchSame)) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
for (int i = 0; i < 2; ++i) DrawSlider(sliders[i], 200);
ImGui::TableSetColumnIndex(1);
for (int i = 2; i < 4; ++i) DrawSlider(sliders[i], 200);
ImGui::EndTable();
}
ImGui::EndTabItem();
// Fix status
if (ImGui::CollapsingHeader("Fix informations", ImGuiTreeNodeFlags_DefaultOpen)) {
@@ -306,10 +281,8 @@ static void on_overlay_draw(reshade::api::effect_runtime* runtime)
}
// Main dll intrance
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID)
{
switch (ul_reason_for_call)
{
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;

View File

@@ -98,9 +98,10 @@
<AdditionalIncludeDirectories>$(SolutionDir)external\reshade\include;$(SolutionDir)external\reshade\deps\imgui;$(SolutionDir)includes</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<LanguageStandard>stdcpp20</LanguageStandard>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -112,7 +113,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<IntrinsicFunctions>false</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
@@ -121,6 +122,8 @@
<LanguageStandard>stdcpp20</LanguageStandard>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -137,9 +140,10 @@
<AdditionalIncludeDirectories>$(SolutionDir)external\reshade\include;$(SolutionDir)external\reshade\deps\imgui;$(SolutionDir)includes</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<LanguageStandard>stdcpp20</LanguageStandard>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -151,16 +155,17 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<IntrinsicFunctions>false</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)external\reshade\include;$(SolutionDir)external\reshade\deps\imgui;$(SolutionDir)includes</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WholeProgramOptimization>true</WholeProgramOptimization>
<WholeProgramOptimization>false</WholeProgramOptimization>
<LanguageStandard>stdcpp20</LanguageStandard>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -169,6 +174,8 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\libs\HotkeysManager.cpp" />
<ClCompile Include="..\libs\OSDManager.cpp" />
<ClCompile Include="dllmain.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

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;
}

View File

@@ -1,15 +1,9 @@
#define IMGUI_DISABLE_INCLUDE_IMCONFIG_H
#define IMGUI_HAS_DOCK 1
#include "ImGuiWidgets.h"
#include "GameInformations.h"
#include "GameFixes.h"
#include "CommonHeaders.h"
#include "HotkeysManager.h"
#include "OSDManager.h"
#include "inicpp.h"
#include <imgui.h>
#include <reshade.hpp>
#include <string>
#include <chrono>
#include <Windows.h>
@@ -42,7 +36,6 @@ void SetFixesEnabled(GameFixes fix, bool value) {
if (SetFixes) SetFixes(fix, value);
}
bool toto;
// Plugin variables for checkboxes and sliders
static bool fov_fix_enabled = false;
static bool Camera_fix_enabled = false;
@@ -53,6 +46,7 @@ static bool Fog_fix_enabled = false;
static bool Time_Dilation_fix_enabled = false;
static bool GodMode_fix_enabled = false;
static bool Ignore_hits_fix_enabled = false;
static bool Stealth_fix_enabled = false;
static bool fix_enabled = false;
static bool console = true;
static int worldFOVValue = 0;
@@ -68,20 +62,9 @@ static bool popup_Informations = false;
static bool show_log_overlay = false;
static std::string log_content;
// Shader toggles and variables
static reshade::api::effect_uniform_variable u_td_show = {};
static reshade::api::effect_uniform_variable u_td_enabled = {};
static reshade::api::effect_uniform_variable u_td_world = {};
static reshade::api::effect_uniform_variable u_td_AI = {};
static reshade::api::effect_uniform_variable u_GodMode_show = {};
static reshade::api::effect_uniform_variable u_GodMode_enabled = {};
static reshade::api::effect_uniform_variable u_Invulnerability_show = {};
static reshade::api::effect_uniform_variable u_Invulnerability_enabled = {};
constexpr auto OSD_SHADER_NAME = "OSD.fx";
// Plugin settings
const std::string SETTINGS_FILE = "./pluginsettings.ini";
const char* FIX_VERSION = "0.9.6";
const char* FIX_VERSION = "0.9.7";
const char* FIX_INFORMATIONS = "This fix allows to:\n - Control FOV in game.\n - Control camera distance.\n - Control HUD scaling.\n - Enable cheats.\n - Disable chromatic aberrations.\n - Disable vignetting.\n - Disable fog.\n - Re enable dev console.";
const char* DONATION_URL = "https://buymeacoffee.com/k4sh44";
@@ -92,7 +75,24 @@ float scale = (float)screenHeight / 1200;
extern "C" __declspec(dllexport) const char* NAME = "The Callisto Protocol";
extern "C" __declspec(dllexport) const char* DESCRIPTION = "Reshade addon to re-enable console, control FOV, camera distance, HUD, some effects and enable cheats.";
// UI sliders
// Prepare arrays of checkboxes for ImGui
static FixToggle individualFixes[] = {
{ "FOV", &fov_fix_enabled, GameFixes::FOV },
{ "Fog", &Fog_fix_enabled, GameFixes::Fog },
{ "Vignetting", &Vignetting_fix_enabled, GameFixes::Vignetting },
{ "Camera distance", &Camera_fix_enabled, GameFixes::Camera,
"Experimental fix. Use at your own risk." },
{ "HUD scaling", &HUD_fix_enabled, GameFixes::HUD },
{ "Chromatic aberrations", &CA_fix_enabled, GameFixes::ChromaticAberrations }
};
static FixToggle cheatFixes[] = {
{ "Time dilation", &Time_Dilation_fix_enabled, GameFixes::TimeDilation, "ALT + 1 (top keyboard row) to toggle" },
{ "God mode", &GodMode_fix_enabled, GameFixes::GodMode, "ALT + 2 (top keyboard row) to toggle.\nJacob won't receive any damage." },
{ "Ignore hits", &Ignore_hits_fix_enabled, GameFixes::IgnoreHits, "ALT + 3 (top keyboard row) to toggle.\nJacob can't be hit." },
{ "Stealth mode",&Stealth_fix_enabled, GameFixes::Stealth, "ALT + 4 (top keyboard row) to toggle.\nEnemies won't attack you" }
};
// Prepare array of sliders for ImGui
static SliderFix sliders[6];
// Load and unload game core dll functions /!\ necessary
@@ -137,7 +137,8 @@ static void LoadFixDLL()
SetFixes(GameFixes::Fog, Fog_fix_enabled);
SetFixes(GameFixes::TimeDilation, Time_Dilation_fix_enabled);
SetFixes(GameFixes::GodMode, GodMode_fix_enabled);
SetFixes(GameFixes::Invulnerable, Ignore_hits_fix_enabled);
SetFixes(GameFixes::IgnoreHits, Ignore_hits_fix_enabled);
SetFixes(GameFixes::Stealth, Stealth_fix_enabled);
SetFixes(GameFixes::DevConsole, console);
}
@@ -175,6 +176,7 @@ static void SaveSettings() {
pluginIniFile["2#Individual fix"]["Time dilation"] = Time_Dilation_fix_enabled;
pluginIniFile["2#Individual fix"]["God Mode"] = GodMode_fix_enabled;
pluginIniFile["2#Individual fix"]["Ignore hits"] = Ignore_hits_fix_enabled;
pluginIniFile["2#Individual fix"]["Stealth"] = Stealth_fix_enabled;
pluginIniFile["3#Fixes tuning"].setComment("Individual fix fine tune");
pluginIniFile["3#Fixes tuning"]["World FOV"] = worldFOVValue;
pluginIniFile["3#Fixes tuning"]["HUD scale"] = HUDScaleValue;
@@ -202,6 +204,7 @@ static void LoadSettings() {
Time_Dilation_fix_enabled = pluginIniFile["2#Individual fix"]["Time dilation"].as<bool>();
GodMode_fix_enabled = pluginIniFile["2#Individual fix"]["God Mode"].as<bool>();
Ignore_hits_fix_enabled = pluginIniFile["2#Individual fix"]["Ignore hits"].as<bool>();
Stealth_fix_enabled = pluginIniFile["2#Individual fix"]["Stealth"].as<bool>();
worldFOVValue = pluginIniFile["3#Fixes tuning"]["World FOV"].as<int>();
HUDScaleValue = pluginIniFile["3#Fixes tuning"]["HUD scale"].as<int>();
cameraOffsetValue = pluginIniFile["3#Fixes tuning"]["Camera offset"].as<float>();
@@ -226,22 +229,6 @@ static std::string read_log_file(const std::string& filename) {
log = ss.str();
return log;
}
// Prepare arrays of checkboxes for ImGui
static FixToggle individualFixes[] = {
{ "FOV", &fov_fix_enabled, GameFixes::FOV },
{ "Fog", &Fog_fix_enabled, GameFixes::Fog },
{ "Vignetting", &Vignetting_fix_enabled, GameFixes::Vignetting },
{ "Camera distance", &Camera_fix_enabled, GameFixes::Camera,
"Experimental fix. Use at your own risk." },
{ "HUD scaling", &HUD_fix_enabled, GameFixes::HUD },
{ "Chromatic aberrations", &CA_fix_enabled, GameFixes::ChromaticAberrations }
};
static FixToggle cheatFixes[] = {
{ "Time dilation", &Time_Dilation_fix_enabled, GameFixes::TimeDilation, "ALT + F1 to toggle" },
{ "God mode", &GodMode_fix_enabled, GameFixes::GodMode, "ALT + F2 to toggle.\nJacob won't receive any damage." },
{ "Ignore hits", &Ignore_hits_fix_enabled, GameFixes::Invulnerable, "ALT + F3 to toggle.\nJacob can't be hit." }
};
// Initialize ImGui widgets for Reshade
static void on_overlay_draw(reshade::api::effect_runtime* runtime) {
@@ -377,66 +364,32 @@ static void on_reshade_present(reshade::api::effect_runtime* runtime) {
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;
u_td_show = runtime->find_uniform_variable(nullptr, "OSD_ShowTD");
u_td_enabled = runtime->find_uniform_variable(nullptr, "TD_Enabled");
u_td_world = runtime->find_uniform_variable(nullptr, "TD_World");
u_td_AI = runtime->find_uniform_variable(nullptr, "TD_AI");
u_GodMode_show = runtime->find_uniform_variable(nullptr, "OSD_ShowGodMode");
u_GodMode_enabled = runtime->find_uniform_variable(nullptr, "GodMode_Enabled");
u_Invulnerability_show = runtime->find_uniform_variable(nullptr, "OSD_ShowInvuln");
u_Invulnerability_enabled = runtime->find_uniform_variable(nullptr, "Invulnerability_Enabled");
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() {
static void InitializeHotkeys() { // Initialize hotkeys for cheats
if (InterlockedCompareExchange(&g_hotkeysInitialized, 1, 0) != 0) return; // Initialize hotkeys once
RegisterHotkey(VK_F1, Modifier::Alt, [] {
Time_Dilation_fix_enabled = !Time_Dilation_fix_enabled;
SetFixesEnabled(GameFixes::TimeDilation, Time_Dilation_fix_enabled);
SaveSettings();
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} });
});
ShowOSD(OSD_duration,
[](reshade::api::effect_runtime* rt) {
ResetAllUniformVariables(rt, OSD_SHADER_NAME);
rt->set_uniform_value_bool(u_td_show, true);
rt->set_uniform_value_bool(u_td_enabled, Time_Dilation_fix_enabled);
rt->set_uniform_value_float(u_td_world, worldTimeDilationValue);
rt->set_uniform_value_float(u_td_AI, AITimeDilationValue);
},
[](reshade::api::effect_runtime* rt) { rt->set_uniform_value_bool(u_td_show, false); });
RegisterHotkey('2', Modifier::Alt, [] {
ToggleOSD(GodMode_fix_enabled, GameFixes::GodMode, u_GodMode_show, u_GodMode_enabled, OSD_duration);
});
RegisterHotkey(VK_F2, Modifier::Alt, [] {
GodMode_fix_enabled = !GodMode_fix_enabled;
SetFixesEnabled(GameFixes::GodMode, GodMode_fix_enabled);
SaveSettings();
ShowOSD(OSD_duration,
[](reshade::api::effect_runtime* rt) {
ResetAllUniformVariables(rt, OSD_SHADER_NAME);
rt->set_uniform_value_bool(u_GodMode_show, true);
rt->set_uniform_value_bool(u_GodMode_enabled, GodMode_fix_enabled);
},
[](reshade::api::effect_runtime* rt) { rt->set_uniform_value_bool(u_GodMode_show, false); });
RegisterHotkey('3', Modifier::Alt, [] {
ToggleOSD(Ignore_hits_fix_enabled, GameFixes::IgnoreHits, u_IgnoreHits_show, u_IgnoreHits_enabled, OSD_duration);
});
RegisterHotkey(VK_F3, Modifier::Alt, [] {
Ignore_hits_fix_enabled = !Ignore_hits_fix_enabled;
SetFixesEnabled(GameFixes::Invulnerable, Ignore_hits_fix_enabled);
SaveSettings();
ShowOSD(OSD_duration,
[](reshade::api::effect_runtime* rt) {
ResetAllUniformVariables(rt, OSD_SHADER_NAME);
rt->set_uniform_value_bool(u_Invulnerability_show, true);
rt->set_uniform_value_bool(u_Invulnerability_enabled, Ignore_hits_fix_enabled);
},
[](reshade::api::effect_runtime* rt) { rt->set_uniform_value_bool(u_Invulnerability_show, false); });
RegisterHotkey('4', Modifier::Alt, [] {
ToggleOSD(Stealth_fix_enabled, GameFixes::Stealth, u_Stealth_show, u_Stealth_enabled, OSD_duration);
});
}

View File

@@ -15,9 +15,13 @@ uniform float TD_AI = 1.0;
// God mode
uniform bool OSD_ShowGodMode = false;
uniform bool GodMode_Enabled = false;
// Invulnerability
uniform bool OSD_ShowInvuln = false;
uniform bool Invulnerability_Enabled = false;
// Ignore hits
uniform bool OSD_ShowIgnoreHits = false;
uniform bool IgnoreHits_Enabled = false;
// Stealth
uniform bool OSD_ShowStealth = false;
uniform bool Stealth_Enabled = false;
// --- Character arrays for labels ---
static const int ON_LENGTH = 2;
static float ON_CHARS[32] = {
@@ -48,7 +52,7 @@ static float WORLD_CHARS[32] = {
};
static const int AI_LEN = 5;
static float AI_CHARS[32] = {
32-32,65-32,73-32,58-32,32-32,0,0,0,
32-32,65-32,73-32,58-32,32-32,0,0,0, // AI :
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
@@ -63,10 +67,18 @@ static float GOD_CHARS[32] = {
};
static const int INV_LEN = 12;
static float INV_CHARS[32] = { // 73 103 110 111 114 101 32 104 105 116 115 32
static float INV_CHARS[32] = {
73-32, 103-32, 110-32, 111-32, 114-32, 101-32, 32-32, 104-32, // "Ignore hits"
105-32, 116-32, 115-32, 32-32, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static const int STEALTH_LEN = 13;
static float STEALTH_CHARS[32] = {
83-32, 116-32, 101-32, 97-32, 108-32, 116-32, 104-32, 32-32, // "Stealth Mode"
77-32, 111-32, 100-32, 101-32, 32-32, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
@@ -154,14 +166,12 @@ float4 DrawFlag(float2 uv, inout float2 pen, float2 charSize, const float label[
float4 PS_OSD(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target {
float4 col = tex2D(ReShade::BackBuffer, uv);
if (!OSD_ShowTD && !OSD_ShowGodMode && !OSD_ShowInvuln)
if (!OSD_ShowTD && !OSD_ShowGodMode && !OSD_ShowIgnoreHits && !OSD_ShowStealth)
return col;
float margin_top = 20.0;
float2 screen_size = float2(BUFFER_WIDTH, BUFFER_HEIGHT);
float aspect = screen_size.x/screen_size.y;
float2 center_uv = float2(0.5, margin_top/screen_size.y+0.01);
float2 p = uv - center_uv; p.x *= aspect;
float2 center_uv = float2(0.5, margin_top / ReShade::ScreenSize.y + 0.01);
float2 p = uv - center_uv; p.x *= ReShade::AspectRatio;
// --- Frame rect ---
float charAdvance = 0.003;
@@ -184,25 +194,30 @@ float4 PS_OSD(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target {
totalLen = GOD_LEN + OFF_LENGTH;
color = float3(1.0, 0.3, 0.3);
}
if (Invulnerability_Enabled && OSD_ShowInvuln) {
if (IgnoreHits_Enabled && OSD_ShowIgnoreHits) {
totalLen = INV_LEN + ON_LENGTH;
color = float3(0.3, 1.0, 0.3);
}
if (!Invulnerability_Enabled && OSD_ShowInvuln) {
if (!IgnoreHits_Enabled && OSD_ShowIgnoreHits) {
totalLen = INV_LEN + OFF_LENGTH;
color = float3(1.0, 0.3, 0.3);
}
if (Stealth_Enabled && OSD_ShowStealth) {
totalLen = STEALTH_LEN + ON_LENGTH;
color = float3(0.3, 1.0, 0.3);
}
if (!Stealth_Enabled && OSD_ShowStealth) {
totalLen = STEALTH_LEN + OFF_LENGTH;
color = float3(1.0, 0.3, 0.3);
}
float2 size_uv = float2((totalLen* charAdvance * 0.5 + charAdvance * 1.0) * aspect, 20.0/screen_size.y);
float2 size_uv = float2((totalLen* charAdvance * 0.5 + charAdvance * 1.0) * ReShade::AspectRatio, 20.0 / ReShade::ScreenSize.y);
float thickness_px = 1.0;
float thickness = thickness_px * ReShade::PixelSize.y;
float radius_px = 2.0;
float radius = radius_px * ReShade::PixelSize.y;
float d = sdRoundRect(p,size_uv,radius);
if (abs(d)<thickness) {
//float3 border = TD_Enabled ? float3(0.3,1.0,0.3) : float3(1.0,0.3,0.3);
col.rgb = lerp(col.rgb, color, 0.85);
}
if (abs(d)<thickness) col.rgb = lerp(col.rgb, color, 0.85);
// --- Draw all flags ---
float2 pen = center_uv;
@@ -232,12 +247,11 @@ float4 PS_OSD(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target {
if (OSD_ShowGodMode)
AlphaBlend(combined, DrawFlag(uv, pen, charSize, GOD_CHARS, GOD_LEN, GodMode_Enabled));
if (OSD_ShowInvuln)
AlphaBlend(combined, DrawFlag(uv, pen, charSize, INV_CHARS, INV_LEN, Invulnerability_Enabled));
if (OSD_ShowIgnoreHits)
AlphaBlend(combined, DrawFlag(uv, pen, charSize, INV_CHARS, INV_LEN, IgnoreHits_Enabled));
// --- final blend ---
//float3 textColor = TD_Enabled ? float3(0.3,1.0,0.3) : float3(1.0,0.3,0.3);
if (OSD_ShowStealth)
AlphaBlend(combined, DrawFlag(uv, pen, charSize, STEALTH_CHARS, STEALTH_LEN, Stealth_Enabled));
combined.rgb *= color;
col.rgb = lerp(col.rgb, combined.rgb, combined.a);

124
external/reshade/shaders/ReShade.fxh vendored Normal file
View File

@@ -0,0 +1,124 @@
/*
* SPDX-License-Identifier: CC0-1.0
*/
#pragma once
#if !defined(__RESHADE__) || __RESHADE__ < 30000
#error "ReShade 3.0+ is required to use this header file"
#endif
#ifndef RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN
#define RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN 0
#endif
#ifndef RESHADE_DEPTH_INPUT_IS_REVERSED
#define RESHADE_DEPTH_INPUT_IS_REVERSED 1
#endif
#ifndef RESHADE_DEPTH_INPUT_IS_MIRRORED
#define RESHADE_DEPTH_INPUT_IS_MIRRORED 0
#endif
#ifndef RESHADE_DEPTH_INPUT_IS_LOGARITHMIC
#define RESHADE_DEPTH_INPUT_IS_LOGARITHMIC 0
#endif
#ifndef RESHADE_DEPTH_MULTIPLIER
#define RESHADE_DEPTH_MULTIPLIER 1
#endif
#ifndef RESHADE_DEPTH_LINEARIZATION_FAR_PLANE
#define RESHADE_DEPTH_LINEARIZATION_FAR_PLANE 1000.0
#endif
// Above 1 expands coordinates, below 1 contracts and 1 is equal to no scaling on any axis
#ifndef RESHADE_DEPTH_INPUT_Y_SCALE
#define RESHADE_DEPTH_INPUT_Y_SCALE 1
#endif
#ifndef RESHADE_DEPTH_INPUT_X_SCALE
#define RESHADE_DEPTH_INPUT_X_SCALE 1
#endif
// An offset to add to the Y coordinate, (+) = move up, (-) = move down
#ifndef RESHADE_DEPTH_INPUT_Y_OFFSET
#define RESHADE_DEPTH_INPUT_Y_OFFSET 0
#endif
#ifndef RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET
#define RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET 0
#endif
// An offset to add to the X coordinate, (+) = move right, (-) = move left
#ifndef RESHADE_DEPTH_INPUT_X_OFFSET
#define RESHADE_DEPTH_INPUT_X_OFFSET 0
#endif
#ifndef RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET
#define RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET 0
#endif
#define BUFFER_PIXEL_SIZE float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT)
#define BUFFER_SCREEN_SIZE float2(BUFFER_WIDTH, BUFFER_HEIGHT)
#define BUFFER_ASPECT_RATIO (BUFFER_WIDTH * BUFFER_RCP_HEIGHT)
namespace ReShade
{
#if defined(__RESHADE_FXC__)
float GetAspectRatio() { return BUFFER_WIDTH * BUFFER_RCP_HEIGHT; }
float2 GetPixelSize() { return float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT); }
float2 GetScreenSize() { return float2(BUFFER_WIDTH, BUFFER_HEIGHT); }
#define AspectRatio GetAspectRatio()
#define PixelSize GetPixelSize()
#define ScreenSize GetScreenSize()
#else
// These are deprecated and will be removed eventually.
static const float AspectRatio = BUFFER_WIDTH * BUFFER_RCP_HEIGHT;
static const float2 PixelSize = float2(BUFFER_RCP_WIDTH, BUFFER_RCP_HEIGHT);
static const float2 ScreenSize = float2(BUFFER_WIDTH, BUFFER_HEIGHT);
#endif
// Global textures and samplers
texture BackBufferTex : COLOR;
texture DepthBufferTex : DEPTH;
sampler BackBuffer { Texture = BackBufferTex; };
sampler DepthBuffer { Texture = DepthBufferTex; };
// Helper functions
float GetLinearizedDepth(float2 texcoord)
{
#if RESHADE_DEPTH_INPUT_IS_UPSIDE_DOWN
texcoord.y = 1.0 - texcoord.y;
#endif
#if RESHADE_DEPTH_INPUT_IS_MIRRORED
texcoord.x = 1.0 - texcoord.x;
#endif
texcoord.x /= RESHADE_DEPTH_INPUT_X_SCALE;
texcoord.y /= RESHADE_DEPTH_INPUT_Y_SCALE;
#if RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET
texcoord.x -= RESHADE_DEPTH_INPUT_X_PIXEL_OFFSET * BUFFER_RCP_WIDTH;
#else // Do not check RESHADE_DEPTH_INPUT_X_OFFSET, since it may be a decimal number, which the preprocessor cannot handle
texcoord.x -= RESHADE_DEPTH_INPUT_X_OFFSET / 2.000000001;
#endif
#if RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET
texcoord.y += RESHADE_DEPTH_INPUT_Y_PIXEL_OFFSET * BUFFER_RCP_HEIGHT;
#else
texcoord.y += RESHADE_DEPTH_INPUT_Y_OFFSET / 2.000000001;
#endif
float depth = tex2Dlod(DepthBuffer, float4(texcoord, 0, 0)).x * RESHADE_DEPTH_MULTIPLIER;
#if RESHADE_DEPTH_INPUT_IS_LOGARITHMIC
const float C = 0.01;
depth = (exp(depth * log(C + 1.0)) - 1.0) / C;
#endif
#if RESHADE_DEPTH_INPUT_IS_REVERSED
depth = 1.0 - depth;
#endif
const float N = 1.0;
depth /= RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - depth * (RESHADE_DEPTH_LINEARIZATION_FAR_PLANE - N);
return depth;
}
}
// Vertex shader generating a triangle covering the entire screen
// See also https://www.reddit.com/r/gamedev/comments/2j17wk/a_slightly_faster_bufferless_vertex_shader_trick/
void PostProcessVS(in uint id : SV_VertexID, out float4 position : SV_Position, out float2 texcoord : TEXCOORD)
{
texcoord.x = (id == 2) ? 2.0 : 0.0;
texcoord.y = (id == 1) ? 2.0 : 0.0;
position = float4(texcoord * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
}

8
includes/CommonHeaders.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
#include "ImGuiWidgets.h"
#include "GameInformations.h"
#include "GameFixes.h"
#include "inicpp.h"
#include <imgui.h>
#include <reshade.hpp>

View File

@@ -19,5 +19,6 @@ enum class GameFixes : int {
FilmGrain,
TimeDilation,
GodMode,
Invulnerable
IgnoreHits,
Stealth
};

View File

@@ -2,10 +2,27 @@
#include <reshade.hpp>
#include <functional>
#include "GameFixes.h"
constexpr auto OSD_SHADER_NAME = "OSD.fx";
using OSDUpdateFn = std::function<void(reshade::api::effect_runtime*)>;
using OSDEndFn = std::function<void(reshade::api::effect_runtime*)>;
// Reshade shader uniform variables
extern reshade::api::effect_uniform_variable u_td_show;
extern reshade::api::effect_uniform_variable u_td_enabled;
extern reshade::api::effect_uniform_variable u_td_world;
extern reshade::api::effect_uniform_variable u_td_AI;
extern reshade::api::effect_uniform_variable u_GodMode_show;
extern reshade::api::effect_uniform_variable u_GodMode_enabled;
extern reshade::api::effect_uniform_variable u_IgnoreHits_show;
extern reshade::api::effect_uniform_variable u_IgnoreHits_enabled;
extern reshade::api::effect_uniform_variable u_Stealth_show;
extern reshade::api::effect_uniform_variable u_Stealth_enabled;
extern void SetFixesEnabled(GameFixes fix, bool value);
extern void SaveSettings();
/**
* @brief Displays an On-Screen Display (OSD) for a specified duration.
*
@@ -23,7 +40,6 @@ using OSDEndFn = std::function<void(reshade::api::effect_runtime*)>;
*/
void ShowOSD(float duration, OSDUpdateFn onUpdate, OSDEndFn onEnd);
/**
* @brief Updates the OSD system each frame and executes callbacks if needed.
*
@@ -38,6 +54,15 @@ void ShowOSD(float duration, OSDUpdateFn onUpdate, OSDEndFn onEnd);
*/
void UpdateOSD(reshade::api::effect_runtime* runtime, float deltaTime);
/**
* @brief Find all uniform variables enumerated.
*
* This function must be called typically in `on_reshade_begin_effects`,
* @param runtime Pointer to the current `reshade::api::effect_runtime` object.
* @param effect_name File name of the effect file to enumerate uniform variables from (eg. myfile.fx)
*/
void FindAllUniformVariables(reshade::api::effect_runtime* runtime, const char* effect_name);
/**
* @brief Reset all uniform variables enumerated.
*
@@ -47,3 +72,44 @@ void UpdateOSD(reshade::api::effect_runtime* runtime, float deltaTime);
* @param effect_name File name of the effect file to enumerate uniform variables from (eg. myfile.fx)
*/
void ResetAllUniformVariables(reshade::api::effect_runtime* runtime, const char* effect_name);
/**
* @brief Toggle cheats & OSD display.
*
* This function must be called once, typically in `init_effect_runtime`,
* using an atomic compare-and-exchange operation
* @param cheatEnabled cheat variable.
* @param fix cheat type to toggle (TimeDilation, God Mode ...)
* @param showUniform the Reshade uniform variable to show/hide the cheat on OSD
* @param enabledUniform the cheat state (enabled or not)
* @param duration the default OSD display duration (default 3 s)
* @param effect_name File name of the effect file to enumerate uniform variables from (eg. myfile.fx)
* @param extraFloats extra Reshade uniform variable (float) to initialize
*/
template<typename T>
void ToggleOSD(T& cheatEnabled, GameFixes fix,
reshade::api::effect_uniform_variable showUniform,
reshade::api::effect_uniform_variable enabledUniform,
float duration = 3.f,
std::initializer_list<std::pair<reshade::api::effect_uniform_variable, float>> extraFloats = {}) {
cheatEnabled = !cheatEnabled;
SetFixesEnabled(fix, cheatEnabled);
SaveSettings();
std::vector<std::pair<reshade::api::effect_uniform_variable, float>> stableFloats(extraFloats);
ShowOSD(duration,
[=, stableFloats = std::move(stableFloats)](reshade::api::effect_runtime* rt) {
ResetAllUniformVariables(rt, OSD_SHADER_NAME);
rt->set_uniform_value_bool(showUniform, true);
rt->set_uniform_value_bool(enabledUniform, cheatEnabled);
for (auto& uniform : stableFloats)
if (uniform.first.handle)
rt->set_uniform_value_float(uniform.first, uniform.second);
},
[=](reshade::api::effect_runtime* rt) {
rt->set_uniform_value_bool(showUniform, false);
});
}

View File

@@ -4,6 +4,18 @@ static float g_timer = 0.0f;
static OSDUpdateFn g_onUpdate;
static OSDEndFn g_onEnd;
// Reshade shader uniform variables
reshade::api::effect_uniform_variable u_td_show = {};
reshade::api::effect_uniform_variable u_td_enabled = {};
reshade::api::effect_uniform_variable u_td_world = {};
reshade::api::effect_uniform_variable u_td_AI = {};
reshade::api::effect_uniform_variable u_GodMode_show = {};
reshade::api::effect_uniform_variable u_GodMode_enabled = {};
reshade::api::effect_uniform_variable u_IgnoreHits_show = {};
reshade::api::effect_uniform_variable u_IgnoreHits_enabled = {};
reshade::api::effect_uniform_variable u_Stealth_show = {};
reshade::api::effect_uniform_variable u_Stealth_enabled = {};
void ShowOSD(float duration, OSDUpdateFn onUpdate, OSDEndFn onEnd) {
g_timer = duration;
g_onUpdate = std::move(onUpdate);
@@ -25,9 +37,21 @@ void UpdateOSD(reshade::api::effect_runtime* runtime, float deltaTime) {
}
}
void FindAllUniformVariables(reshade::api::effect_runtime* runtime, const char* effect_name) {
u_td_show = runtime->find_uniform_variable(OSD_SHADER_NAME, "OSD_ShowTD");
u_td_enabled = runtime->find_uniform_variable(OSD_SHADER_NAME, "TD_Enabled");
u_td_world = runtime->find_uniform_variable(OSD_SHADER_NAME, "TD_World");
u_td_AI = runtime->find_uniform_variable(OSD_SHADER_NAME, "TD_AI");
u_GodMode_show = runtime->find_uniform_variable(OSD_SHADER_NAME, "OSD_ShowGodMode");
u_GodMode_enabled = runtime->find_uniform_variable(OSD_SHADER_NAME, "GodMode_Enabled");
u_IgnoreHits_show = runtime->find_uniform_variable(OSD_SHADER_NAME, "OSD_ShowIgnoreHits");
u_IgnoreHits_enabled = runtime->find_uniform_variable(OSD_SHADER_NAME, "IgnoreHits_Enabled");
u_Stealth_show = runtime->find_uniform_variable(OSD_SHADER_NAME, "OSD_ShowStealth");
u_Stealth_enabled = runtime->find_uniform_variable(OSD_SHADER_NAME, "Stealth_Enabled");
}
void ResetAllUniformVariables(reshade::api::effect_runtime* runtime, const char* effect_name) {
runtime->enumerate_uniform_variables(effect_name, [runtime](reshade::api::effect_runtime* rt, reshade::api::effect_uniform_variable OSDvar) {
runtime->reset_uniform_value(OSDvar);
});
}
}