2025-10-09 11:59:21 +02:00
# 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>
// 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 SetUltraWideFixEnabled = nullptr ;
static SetBoolFn SetDOFFixEnabled = nullptr ;
static SetBoolFn SetCAFixEnabled = nullptr ;
static SetBoolFn SetVignettingFixEnabled = nullptr ;
static SetBoolFn SetCameraFixEnabled = nullptr ;
static SetIntFn SetFOV = nullptr ;
static SetFloatFn SetCameraDistance = nullptr ;
static GetGameInfosStruct GetGameInfos = nullptr ;
// Plugin variables for checkboxes and sliders
static bool fov_fix_enabled = false ;
static bool ultrawide_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 fix_enabled = false ;
static int worldFOVvalue = 0 ;
static float cameraDistanceValue = 1.f ;
static bool popup_Informations = false ;
// 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 cutscenes. \n - Controls camera distance. \n - Disable depth of field. \n - Disable chromatic aberrations. \n - Re enable dev console. " ;
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 ( " BloodOfMehranCore.dll " ) = = nullptr ) {
fixLib = LoadLibraryA ( " BloodOfMehranCore.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 " ) ;
SetUltraWideFixEnabled = ( SetBoolFn ) GetProcAddress ( fixLib , " SetUltraWideFixEnabled " ) ;
SetCameraFixEnabled = ( SetBoolFn ) GetProcAddress ( fixLib , " SetCameraFixEnabled " ) ;
SetDOFFixEnabled = ( SetBoolFn ) GetProcAddress ( fixLib , " SetDOFFixEnabled " ) ;
SetCAFixEnabled = ( SetBoolFn ) GetProcAddress ( fixLib , " SetCAFixEnabled " ) ;
SetVignettingFixEnabled = ( SetBoolFn ) GetProcAddress ( fixLib , " SetVignettingFixEnabled " ) ;
SetFOV = ( SetIntFn ) GetProcAddress ( fixLib , " SetFOV " ) ;
SetCameraDistance = ( SetFloatFn ) GetProcAddress ( fixLib , " SetCameraDistance " ) ;
GetGameInfos = ( GetGameInfosStruct ) GetProcAddress ( fixLib , " GetGameInfos " ) ;
// Apply initial values loaded from settings
if ( SetFOV ) SetFOV ( worldFOVvalue ) ;
if ( SetCameraDistance ) SetCameraDistance ( cameraDistanceValue ) ;
if ( SetFOVFixEnabled ) SetFOVFixEnabled ( fov_fix_enabled , true ) ;
if ( SetUltraWideFixEnabled ) SetUltraWideFixEnabled ( ultrawide_fix_enabled , true ) ;
if ( SetCameraFixEnabled ) SetCameraFixEnabled ( camera_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 ( SetFixEnabled ) SetFixEnabled ( fix_enabled , true ) ;
}
}
// Settings functions
static void SaveSettings ( )
{
ini : : IniFile pluginIniFile ;
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 " } ) ;
pluginIniFile [ " 1#General fix " ] [ " Enabled " ] = fix_enabled ;
pluginIniFile [ " 2#Individual fix " ] . setComment ( " Controls each fix individually " ) ;
pluginIniFile [ " 2#Individual fix " ] [ " FOV " ] = fov_fix_enabled ;
pluginIniFile [ " 2#Individual fix " ] [ " UltraWide " ] = ultrawide_fix_enabled ;
pluginIniFile [ " 2#Individual fix " ] [ " Camera " ] = camera_fix_enabled ;
pluginIniFile [ " 2#Individual fix " ] [ " DOF " ] = DOF_fix_enabled ;
pluginIniFile [ " 2#Individual fix " ] [ " Chromatic aberrations " ] = CA_fix_enabled ;
pluginIniFile [ " 2#Individual fix " ] [ " Vignetting " ] = Vignetting_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 . save ( SETTINGS_FILE ) ;
}
static void LoadSettings ( )
{
ini : : IniFile pluginIniFile ;
try {
pluginIniFile . load ( SETTINGS_FILE ) ;
fix_enabled = pluginIniFile [ " 1#General fix " ] [ " Enabled " ] . as < bool > ( ) ;
fov_fix_enabled = pluginIniFile [ " 2#Individual fix " ] [ " FOV " ] . as < bool > ( ) ;
ultrawide_fix_enabled = pluginIniFile [ " 2#Individual fix " ] [ " UltraWide " ] . as < bool > ( ) ;
camera_fix_enabled = pluginIniFile [ " 2#Individual fix " ] [ " Camera " ] . as < bool > ( ) ;
DOF_fix_enabled = pluginIniFile [ " 2#Individual fix " ] [ " DOF " ] . as < bool > ( ) ;
CA_fix_enabled = pluginIniFile [ " 2#Individual fix " ] [ " Chromatic aberrations " ] . as < bool > ( ) ;
Vignetting_fix_enabled = pluginIniFile [ " 2#Individual fix " ] [ " Vignetting " ] . as < bool > ( ) ;
worldFOVvalue = pluginIniFile [ " 3#Fixes tuning " ] [ " World FOV " ] . as < int > ( ) ;
cameraDistanceValue = pluginIniFile [ " 3#Fixes tuning " ] [ " Camera distance " ] . as < float > ( ) ;
}
catch ( const std : : exception & e ) { }
}
// 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 ) ;
ImGui : : PushStyleColor ( ImGuiCol_Button , ImVec4 ( 0.84f , 0.12f , 0.51f , 1.0f ) ) ; // pink
ImGui : : PushStyleColor ( ImGuiCol_ButtonHovered , ImVec4 ( 0.84f , 0.12f , 0.51f , 1.0f ) ) ; // pink
ImGui : : PushStyleColor ( ImGuiCol_ButtonActive , ImVec4 ( 0.84f , 0.2f , 0.51f , 1.0f ) ) ; // pink
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 ( ) ;
}
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 ( " Camera " , & camera_fix_enabled ) ) {
if ( SetCameraFixEnabled ) SetCameraFixEnabled ( camera_fix_enabled , false ) ;
SaveSettings ( ) ;
}
ImGui : : TableSetColumnIndex ( 1 ) ;
if ( ImGui : : Checkbox ( " Cutscenes pillarboxing " , & ultrawide_fix_enabled ) ) {
if ( SetUltraWideFixEnabled ) SetUltraWideFixEnabled ( ultrawide_fix_enabled , false ) ;
SaveSettings ( ) ;
}
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 ( ) ;
}
ImGui : : EndTable ( ) ;
}
}
ImGui : : EndTable ( ) ;
}
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 ( ImGui : : IsItemHovered ( ) ) {
ImGui : : BeginTooltip ( ) ;
ImGui : : Text ( " This will affect in game FOV only. " ) ;
ImGui : : EndTooltip ( ) ;
}
ImGui : : TableSetColumnIndex ( 1 ) ;
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 ( ) ;
}
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 ( 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 ) ;
}
}
}
// 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 ( ) ;
2025-10-09 22:30:27 +02:00
reshade : : register_overlay ( " Blood Of Mehran " , & on_overlay_draw ) ;
2025-10-09 11:59:21 +02:00
reshade : : register_event < reshade : : addon_event : : init_effect_runtime > (
[ ] ( reshade : : api : : effect_runtime * runtime ) {
LoadFixDLL ( ) ;
} ) ;
break ;
case DLL_PROCESS_DETACH :
reshade : : unregister_addon ( hinstDLL ) ;
break ;
}
return TRUE ;
}