mirror of
https://github.com/gwdevhub/gMod.git
synced 2026-07-24 03:56:34 +00:00
work with reshade (#15)
* use directxtex for dds textures * use d3dx sdk for wic texture loading until we figure out how to load volume/cube textures without it * update d3d9 loading
This commit is contained in:
+97
-73
@@ -6,6 +6,7 @@
|
||||
#include <Psapi.h>
|
||||
|
||||
#include "MinHook.h"
|
||||
#include <filesystem>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -20,31 +21,28 @@ namespace {
|
||||
Direct3DCreate9Ex_type Direct3DCreate9Ex_fn = nullptr;
|
||||
Direct3DCreate9Ex_type Direct3DCreate9Ex_ret = nullptr;
|
||||
|
||||
|
||||
static FILE* stdout_proxy;
|
||||
static FILE* stderr_proxy;
|
||||
|
||||
/*
|
||||
* global variable which are linked external
|
||||
*/
|
||||
unsigned int gl_ErrorState = 0u;
|
||||
|
||||
// If not nullptr, we're responsible for freeing this library on termination
|
||||
HMODULE gl_hOriginalDll = nullptr;
|
||||
HMODULE gMod_Loaded_d3d9_Module_Handle = nullptr;
|
||||
|
||||
// If this hModule called d3d9.dll?
|
||||
bool IsD3d9Module(HMODULE hModule, HANDLE hProcess)
|
||||
bool IsD3d9Dll(HMODULE hModule)
|
||||
{
|
||||
TCHAR szModuleName[MAX_PATH];
|
||||
GetModuleBaseName(hProcess, hModule, szModuleName, sizeof(szModuleName) / sizeof(TCHAR));
|
||||
return strcmp(szModuleName, TEXT("d3d9.dll")) == 0;
|
||||
}
|
||||
// Does this module contain exported function calls for creating a d3d9 device?
|
||||
bool HasD3d9Methods(HMODULE hModule, HANDLE hProcess)
|
||||
{
|
||||
return GetProcAddress(hModule, "Direct3DCreate9")
|
||||
&& GetProcAddress(hModule, "Direct3DCreate9Ex");
|
||||
ASSERT(GetModuleFileName(hModule, szModuleName, sizeof(szModuleName) / sizeof(*szModuleName)) > 0);
|
||||
const auto basename = strrchr(szModuleName, '\\');
|
||||
return basename && strcmp(basename + 1, "d3d9.dll") == 0;
|
||||
}
|
||||
|
||||
// Does this module contain exported function calls for creating a d3d9 device?
|
||||
bool HasD3d9Methods(HMODULE hModule)
|
||||
{
|
||||
return GetProcAddress(hModule, "Direct3DCreate9")
|
||||
&& GetProcAddress(hModule, "Direct3DCreate9Ex");
|
||||
}
|
||||
|
||||
HMODULE FindLoadedDll()
|
||||
{
|
||||
@@ -58,8 +56,9 @@ namespace {
|
||||
if (!EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded))
|
||||
return nullptr;
|
||||
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
|
||||
if (IsD3d9Module(hModules[i], hProcess)
|
||||
|| HasD3d9Methods(hModules[i], hProcess)) {
|
||||
if (hModules[i] == gl_hThisInstance)
|
||||
continue;
|
||||
if (IsD3d9Dll(hModules[i])) {
|
||||
return hModules[i];
|
||||
}
|
||||
}
|
||||
@@ -70,6 +69,36 @@ namespace {
|
||||
unsigned int gl_ErrorState = 0;
|
||||
HINSTANCE gl_hThisInstance = nullptr;
|
||||
|
||||
IDirect3D9* APIENTRY Direct3DCreate9(UINT SDKVersion)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9: original %p, uMod %p\n", Direct3DCreate9_fn, Direct3DCreate9);
|
||||
|
||||
ASSERT(Direct3DCreate9_ret);
|
||||
|
||||
IDirect3D9* pIDirect3D9_orig = Direct3DCreate9_ret(SDKVersion); //creating the original IDirect3D9 object
|
||||
ASSERT(pIDirect3D9_orig);
|
||||
|
||||
return new uMod_IDirect3D9(pIDirect3D9_orig); //return our object instead of the "real one"
|
||||
}
|
||||
|
||||
HRESULT APIENTRY Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9Ex: original %p, uMod %p\n", Direct3DCreate9Ex_fn, Direct3DCreate9Ex);
|
||||
|
||||
ASSERT(Direct3DCreate9Ex_ret);
|
||||
|
||||
IDirect3D9Ex* pIDirect3D9Ex_orig = nullptr;
|
||||
HRESULT ret = Direct3DCreate9Ex_ret(SDKVersion, &pIDirect3D9Ex_orig); //creating the original IDirect3D9 object
|
||||
|
||||
if (ret != S_OK)
|
||||
return ret;
|
||||
|
||||
// @Cleanup: should be we freeing pIDirect3D9Ex at the end of our own lifecycle?
|
||||
uMod_IDirect3D9Ex* pIDirect3D9Ex = new uMod_IDirect3D9Ex(pIDirect3D9Ex_orig);
|
||||
ppD3D = (IDirect3D9Ex**)&pIDirect3D9Ex;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* dll entry routine, here we initialize or clean up
|
||||
*/
|
||||
@@ -80,10 +109,10 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
#ifdef _DEBUG
|
||||
AllocConsole();
|
||||
SetConsoleTitleA("gMod Console");
|
||||
freopen_s(&stdout_proxy, "CONOUT$", "w", stdout);
|
||||
freopen_s(&stderr_proxy, "CONOUT$", "w", stderr);
|
||||
AllocConsole();
|
||||
SetConsoleTitleA("gMod Console");
|
||||
freopen_s(&stdout_proxy, "CONOUT$", "w", stdout);
|
||||
freopen_s(&stderr_proxy, "CONOUT$", "w", stderr);
|
||||
#endif
|
||||
InitInstance(hModule);
|
||||
break;
|
||||
@@ -100,45 +129,47 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
|
||||
void InitInstance(HINSTANCE hModule)
|
||||
{
|
||||
DisableThreadLibraryCalls(hModule); //reduce overhead
|
||||
gl_hThisInstance = hModule;
|
||||
Message("InitInstance: %p\n", hModule);
|
||||
DisableThreadLibraryCalls(hModule); //reduce overhead
|
||||
|
||||
// Store the handle to this module
|
||||
gl_hThisInstance = hModule;
|
||||
|
||||
const auto d3d9_dll = LoadOriginalDll();
|
||||
ASSERT(d3d9_dll);
|
||||
|
||||
Direct3DCreate9_fn = reinterpret_cast<Direct3DCreate9_type>(GetProcAddress(d3d9_dll, "Direct3DCreate9"));
|
||||
ASSERT(Direct3DCreate9_fn);
|
||||
|
||||
Direct3DCreate9Ex_fn = reinterpret_cast<Direct3DCreate9Ex_type>(GetProcAddress(d3d9_dll, "Direct3DCreate9Ex"));
|
||||
ASSERT(Direct3DCreate9Ex_fn);
|
||||
|
||||
MH_Initialize();
|
||||
|
||||
// Hook our loaded Dll's dx9 calls though to uMod's functions
|
||||
Direct3DCreate9_fn = reinterpret_cast<Direct3DCreate9_type>(GetProcAddress(d3d9_dll, "Direct3DCreate9"));
|
||||
ASSERT(Direct3DCreate9_fn);
|
||||
if (Direct3DCreate9_fn) {
|
||||
MH_CreateHook(Direct3DCreate9_fn, uMod_Direct3DCreate9, (void**)&Direct3DCreate9_ret);
|
||||
MH_CreateHook(Direct3DCreate9_fn, Direct3DCreate9, (void**)&Direct3DCreate9_ret);
|
||||
MH_EnableHook(Direct3DCreate9_fn);
|
||||
}
|
||||
|
||||
Direct3DCreate9Ex_fn = reinterpret_cast<Direct3DCreate9Ex_type>(GetProcAddress(d3d9_dll, "Direct3DCreate9Ex"));
|
||||
ASSERT(Direct3DCreate9Ex_fn);
|
||||
if (Direct3DCreate9Ex_fn) {
|
||||
MH_CreateHook(Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex, (void**)&Direct3DCreate9Ex_ret);
|
||||
MH_CreateHook(Direct3DCreate9Ex_fn, Direct3DCreate9Ex, (void**)&Direct3DCreate9Ex_ret);
|
||||
MH_EnableHook(Direct3DCreate9Ex_fn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ExitInstance()
|
||||
{
|
||||
if(Direct3DCreate9_fn)
|
||||
if (Direct3DCreate9_fn)
|
||||
MH_DisableHook(Direct3DCreate9_fn);
|
||||
if(Direct3DCreate9Ex_fn)
|
||||
if (Direct3DCreate9Ex_fn)
|
||||
MH_DisableHook(Direct3DCreate9Ex_fn);
|
||||
|
||||
MH_Uninitialize();
|
||||
|
||||
// Release the system's d3d9.dll
|
||||
if (gl_hOriginalDll != nullptr) {
|
||||
FreeLibrary(gl_hOriginalDll);
|
||||
gl_hOriginalDll = nullptr;
|
||||
if (gMod_Loaded_d3d9_Module_Handle != nullptr) {
|
||||
ASSERT(FreeLibrary(gMod_Loaded_d3d9_Module_Handle));
|
||||
gMod_Loaded_d3d9_Module_Handle = nullptr;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -146,7 +177,10 @@ void ExitInstance()
|
||||
fclose(stdout_proxy);
|
||||
if (stderr_proxy)
|
||||
fclose(stderr_proxy);
|
||||
FreeConsole();
|
||||
__try {
|
||||
FreeConsole();
|
||||
}
|
||||
__except (EXCEPTION_CONTINUE_EXECUTION) { }
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -156,14 +190,34 @@ HMODULE LoadOriginalDll()
|
||||
if (found)
|
||||
return found;
|
||||
|
||||
char buffer[MAX_PATH];
|
||||
GetSystemDirectory(buffer, MAX_PATH); //get the system directory, we need to open the original d3d9.dll
|
||||
char executable_path[MAX_PATH]{};
|
||||
ASSERT(GetModuleFileName(GetModuleHandle(nullptr), executable_path, _countof(executable_path)) > 0);
|
||||
|
||||
char gMod_path[MAX_PATH]{};
|
||||
ASSERT(GetModuleFileName(gl_hThisInstance, gMod_path, _countof(gMod_path)) > 0);
|
||||
|
||||
const auto exe_fs_path = std::filesystem::path(executable_path);
|
||||
const auto gMod_fs_path = std::filesystem::path(gMod_path);
|
||||
|
||||
if (exe_fs_path.parent_path() != gMod_fs_path.parent_path()
|
||||
|| gMod_fs_path.filename() != "d3d9.dll") {
|
||||
// Call basic LoadLibrary function; we're not in the same directory as the exe.
|
||||
gMod_Loaded_d3d9_Module_Handle = LoadLibrary("d3d9.dll");
|
||||
}
|
||||
else {
|
||||
// We're in the same directory as the exe, and we're called 'd3d9.dll'. Calling vanilla "LoadLibrary" will be recursive!
|
||||
char buffer[MAX_PATH];
|
||||
ASSERT(GetSystemDirectory(buffer, _countof(buffer) > 0)); //get the system directory, we need to open the original d3d9.dll
|
||||
|
||||
// Append dll name
|
||||
strcat_s(buffer, _countof(buffer), "\\d3d9.dll");
|
||||
gMod_Loaded_d3d9_Module_Handle = LoadLibrary(buffer);
|
||||
}
|
||||
|
||||
ASSERT(gMod_Loaded_d3d9_Module_Handle);
|
||||
|
||||
// Append dll name
|
||||
strcat_s(buffer, MAX_PATH, "\\d3d9.dll");
|
||||
gl_hOriginalDll = LoadLibrary(buffer);
|
||||
found = FindLoadedDll();
|
||||
ASSERT(found && found == gl_hOriginalDll);
|
||||
ASSERT(found && found == gMod_Loaded_d3d9_Module_Handle);
|
||||
|
||||
return found;
|
||||
}
|
||||
@@ -171,33 +225,3 @@ HMODULE LoadOriginalDll()
|
||||
/*
|
||||
* We inject the dll into the game, thus we retour the original Direct3DCreate9 function to our MyDirect3DCreate9 function
|
||||
*/
|
||||
|
||||
IDirect3D9* APIENTRY uMod_Direct3DCreate9(UINT SDKVersion)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9: original %p, uMod %p\n", Direct3DCreate9_fn, uMod_Direct3DCreate9);
|
||||
|
||||
ASSERT(Direct3DCreate9_ret);
|
||||
|
||||
IDirect3D9* pIDirect3D9_orig = Direct3DCreate9_ret(SDKVersion); //creating the original IDirect3D9 object
|
||||
ASSERT(pIDirect3D9_orig);
|
||||
|
||||
return new uMod_IDirect3D9(pIDirect3D9_orig); //return our object instead of the "real one"
|
||||
}
|
||||
|
||||
HRESULT APIENTRY uMod_Direct3DCreate9Ex(UINT SDKVersion, IDirect3D9Ex** ppD3D)
|
||||
{
|
||||
Message("uMod_Direct3DCreate9Ex: original %p, uMod %p\n", Direct3DCreate9Ex_fn, uMod_Direct3DCreate9Ex);
|
||||
|
||||
ASSERT(Direct3DCreate9Ex_ret);
|
||||
|
||||
IDirect3D9Ex* pIDirect3D9Ex_orig = nullptr;
|
||||
HRESULT ret = Direct3DCreate9Ex_ret(SDKVersion, &pIDirect3D9Ex_orig); //creating the original IDirect3D9 object
|
||||
|
||||
if (ret != S_OK)
|
||||
return ret;
|
||||
|
||||
// @Cleanup: should be we freeing pIDirect3D9Ex at the end of our own lifecycle?
|
||||
uMod_IDirect3D9Ex* pIDirect3D9Ex = new uMod_IDirect3D9Ex(pIDirect3D9Ex_orig);
|
||||
ppD3D = (IDirect3D9Ex**)&pIDirect3D9Ex;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user