Files
ReshadePluginsAddon/WuchangFF/dllmain.cpp

251 lines
9.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#define IMGUI_DISABLE_INCLUDE_IMCONFIG_H
#define IMGUI_HAS_DOCK 1
#include <imgui.h>
#include <reshade.hpp>
#include <fstream>
#include <string>
#include <Windows.h>
#include <thread>
#include <chrono>
// Core game dll functions declarations
typedef void (*SetBoolFn)(bool, bool);
typedef void (*SetIntFn)(int);
typedef float (*GetFloatFn)();
typedef void (*InitDLL)();
static HMODULE fixLib = nullptr;
static SetBoolFn SetFixEnabled = nullptr;
static SetBoolFn SetFOVFixEnabled = nullptr;
static SetBoolFn SetAspectRatioFixEnabled = nullptr;
static SetBoolFn SetDOFFixEnabled = nullptr;
static SetIntFn SetFOV = nullptr;
static GetFloatFn GetFOVIn = nullptr;
static GetFloatFn GetCompensadedFOV = nullptr;
static GetFloatFn GetFOVOut = nullptr;
static InitDLL InitializeLogger = nullptr;
// Plugin variables for checkboxes and sliders
static bool fov_fix_enabled = false;
static bool aspect_ratio_fix_enabled = false;
static bool DOF_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* DOF_FIX_SETTING = "DOFFIX=";
const char* WORLD_FOV_SETTING = "WorldFOV=";
const char* FIX_VERSION = "1.0.1";
const char* FIX_INFORMATIONS = "This fix allows to:\n - Control in game FOV.\n - Force aspect ratio.\n - Disable depth of field.\r\nFOV will be compensated when aspect fix is checked.";
const char* DONATION_URL = "https://buymeacoffee.com/k4sh44";
// Load and unload game core dll functions /!\ necessary
static void LoadFixDLL()
{
MessageBoxA(nullptr, "LoadFixDll", "Logger Error", MB_ICONERROR | MB_OK);
std::thread([]() {
std::this_thread::sleep_for(std::chrono::milliseconds(8000)); // Game process is not ready at launch and memory is not yet initialized
if (GetModuleHandleA("WuchangFFCore.dll") == nullptr) {
MessageBoxA(nullptr, "Appel dll", "Logger Error", MB_ICONERROR | MB_OK);
fixLib = LoadLibraryA("WuchangFFCore.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");
SetAspectRatioFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetAspectRatioFixEnabled");
SetDOFFixEnabled = (SetBoolFn)GetProcAddress(fixLib, "SetDOFFixEnabled");
SetFOV = (SetIntFn)GetProcAddress(fixLib, "SetFOV");
GetFOVIn = (GetFloatFn)GetProcAddress(fixLib, "GetFOVIn");
GetCompensadedFOV = (GetFloatFn)GetProcAddress(fixLib, "GetCompensatedFOV");
GetFOVOut = (GetFloatFn)GetProcAddress(fixLib, "GetFOVOut");;
// Apply initial values loaded from settings
if (SetFOV) SetFOV(worldFOVvalue);
//if (SetFOVFixEnabled) SetFOVFixEnabled(fov_fix_enabled, true);
//if (SetAspectRatioFixEnabled) SetAspectRatioFixEnabled(aspect_ratio_fix_enabled, true);
//if (SetDOFFixEnabled) SetDOFFixEnabled(DOF_fix_enabled, true);
if (SetFixEnabled) SetFixEnabled(fix_enabled, true);
}
}).detach(); // on le détache pour quil tourne indépendamment
}
// Addon 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 << ASPECT_FIX_SETTING << (aspect_ratio_fix_enabled ? "1" : "0") << "\n";
file << DOF_FIX_SETTING << (DOF_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(ASPECT_FIX_SETTING) == 0)
{
std::string val = line.substr(strlen(ASPECT_FIX_SETTING));
aspect_ratio_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(WORLD_FOV_SETTING) == 0)
worldFOVvalue = std::stoi(line.substr(strlen(WORLD_FOV_SETTING)));
}
file.close();
}
}
static void displayFixInformations() {
// Fix version
ImGui::Begin("Informations", &popup_Informations); //
ImGui::SetCursorPos(ImVec2(10, 36));
ImGui::Text("Version : %s", FIX_VERSION);
ImGui::SetCursorPos(ImVec2(10, 76));
ImGui::Text(FIX_INFORMATIONS);
ImGui::End();
}
// Initialize ImGui widgets for Reshade
static void on_overlay_draw(reshade::api::effect_runtime* runtime)
{
ImGui::SetNextWindowPos(ImVec2(100, 200), ImGuiCond_Once);
ImGui::SetNextWindowSize(ImVec2(350, 150), ImGuiCond_Once);
// Donation ?
ImGui::SetCursorPos(ImVec2(10, 36));
ImGui::Text("Like my work ?");
ImGui::SetCursorPos(ImVec2(130, 33));
if (ImGui::Button("consider donation"))
{
ShellExecuteA(NULL, "open", DONATION_URL, NULL, NULL, SW_SHOWNORMAL);
}
// Fix informations
ImGui::SetCursorPos(ImVec2(270, 33));
if (ImGui::Button("Fix informations"))
popup_Informations = true;
if (popup_Informations)
displayFixInformations();
// Generic fix
ImGui::SetCursorPos(ImVec2(10, 60));
ImGui::BeginChild("AllFixesHeader", ImVec2(220, 0), false); // true = border
if (ImGui::CollapsingHeader("Enable fixes", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::SetCursorPos(ImVec2(5, 30));
if (ImGui::Checkbox("Fix enabled", &fix_enabled)) {
if (SetFixEnabled) SetFixEnabled(fix_enabled, false);
SaveSettings();
}
}
ImGui::EndChild();
// FOV adjustment
ImGui::SetCursorPos(ImVec2(10, 120));
ImGui::BeginChild("FOVHeader", ImVec2(220, 0), false);
if (ImGui::CollapsingHeader("In game additional FOV", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::SetCursorPos(ImVec2(5, 30));
ImGui::SetNextItemWidth(150.0f);
if (ImGui::SliderInt("", &worldFOVvalue, -20, 50)) {}
if (ImGui::IsItemDeactivatedAfterEdit()) {
if (SetFOV) SetFOV(worldFOVvalue);
SaveSettings();
}
}
ImGui::EndChild();
// Individual fixes
ImGui::SetCursorPos(ImVec2(240, 60));
ImGui::BeginChild("IndividualFixesHeader", ImVec2(250, 0), false);
if (ImGui::CollapsingHeader("Individual fixes", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::SetCursorPos(ImVec2(5, 30));
if (ImGui::Checkbox("Enable FOV Fix", &fov_fix_enabled)) {
if (SetFOVFixEnabled) SetFOVFixEnabled(fov_fix_enabled, false);
SaveSettings();
}
ImGui::SetCursorPos(ImVec2(5, 55));
if (ImGui::Checkbox("Enable aspect Ratio Fix", &aspect_ratio_fix_enabled)) {
if (SetAspectRatioFixEnabled) SetAspectRatioFixEnabled(aspect_ratio_fix_enabled, false);
SaveSettings();
}
ImGui::SetCursorPos(ImVec2(5, 80));
if (ImGui::Checkbox("Depth of field Fix", &DOF_fix_enabled)) {
if (SetDOFFixEnabled) SetDOFFixEnabled(DOF_fix_enabled, false);
SaveSettings();
}
}
ImGui::EndChild();
// Fix status
ImGui::SetCursorPos(ImVec2(10, 200));
ImGui::BeginChild("INFOSHeader", ImVec2(480, 80), true); // true = border
if (ImGui::CollapsingHeader("Fix informations", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::SetCursorPos(ImVec2(5, 30));
if (GetFOVIn && GetCompensadedFOV && GetFOVOut)
ImGui::Text("FOV In: %.2f, Compensated : %.2f, Out : %.2f", GetFOVIn(), GetCompensadedFOV(), GetFOVOut());
}
ImGui::EndChild();
}
// 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("Wuchang Fallen Feathers", &on_overlay_draw);
reshade::register_event<reshade::addon_event::init_effect_runtime>(
[](reshade::api::effect_runtime* runtime) {
LoadFixDLL();
});
//reshade::register_event<reshade::addon_event::init_command_queue>(
// [](reshade::api::command_queue *queue) {
// LoadFixDLL();
// });
break;
case DLL_PROCESS_DETACH:
reshade::unregister_addon(hinstDLL);
break;
}
return TRUE;
}