Files
2025-09-29 00:52:08 +02:00

205 lines
6.7 KiB
C++
Executable File

// DX11Hook.cpp
#include "stdafx.h"
float DX11Hook::ScrX = 0, DX11Hook::ScrY = 0;
float DX11Hook::ScrWidth = 0, DX11Hook::ScrHeight = 0;
static BOOLEAN MenuInitialized = FALSE;
//==========================================================================================================================
typedef HRESULT(WINAPI *D3D11PresentHook) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
D3D11PresentHook originalD3D11PresentHook = NULL;
HRESULT WINAPI detourD3D11PresentHook(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
static BOOLEAN Initialized = FALSE;
if (!Initialized) Initialized = DX11->InitDX11RenderStuff(pSwapChain);
DX11->DX11RenderScene();
return originalD3D11PresentHook(pSwapChain, SyncInterval, Flags);
}
//==========================================================================================================================
void DX11Hook::DX11RenderScene()
{
try
{
// if (Hooking::GetGameState() == GameStatePlaying)
{
// Init Menu
// if (!MenuInitialized) MenuInitialized = Menu::Init();
// Render Menu
Menu::Render();
}
}
catch (const std::exception &e)
{
DEBUGMSG(e.what());
}
}
//==========================================================================================================================
DWORD DX11Hook::InitDevice(HWND hWindow)
{
// Get window size
RECT rc;
GetWindowRect(hWindow, &rc);
ScrX = (float)rc.left;
ScrY = (float)rc.top;
ScrWidth = (float)(rc.right - rc.left);
ScrHeight = (float)(rc.bottom - rc.top);
IDXGISwapChain* pSwapChain;
D3D_FEATURE_LEVEL requestedLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 };
D3D_FEATURE_LEVEL obtainedLevel;
ID3D11Device* d3dDevice = nullptr;
ID3D11DeviceContext* d3dContext = nullptr;
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(scd));
scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
scd.OutputWindow = hWindow;
scd.SampleDesc.Count = 1; // Set to 1 to disable multisampling
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
scd.Windowed = true; // ((GetWindowLongPtr(hWindow, GWL_STYLE) & WS_POPUP) != 0) ? false : true;
// LibOVR 0.4.3 requires that the width and height for the backbuffer is set even if
// you use windowed mode, despite being optional according to the D3D11 documentation.
scd.BufferDesc.Width = 1;
scd.BufferDesc.Height = 1;
scd.BufferDesc.RefreshRate.Numerator = 0;
scd.BufferDesc.RefreshRate.Denominator = 1;
UINT createFlags = 0;
#ifdef _DEBUG
// This flag gives you some quite wonderful debug text. Not wonderful for performance, though!
createFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
IDXGISwapChain* d3dSwapChain = 0;
HRESULT x = D3D11CreateDeviceAndSwapChain(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
createFlags,
requestedLevels,
sizeof(requestedLevels) / sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION,
&scd,
&pSwapChain,
&DX11Device,
&obtainedLevel,
&DX11DeviceContext);
if (FAILED(x))
{
if (x == DXGI_ERROR_SDK_COMPONENT_MISSING)
{
MessageBox(hWindow, L"Failed to create directX device and swapchain: DXGI_ERROR_SDK_COMPONENT_MISSING\n\nYou seem to be missing some DirectX SDKs. If you are on Windows 8 or 10, see this article for information on enabling DirectX debug: https://goo.gl/tSeSif", L"Error", MB_ICONERROR);
}
else
{
MessageBox(hWindow, L"Failed to create directX device and swapchain!", L"Error", MB_ICONERROR);
}
Log::Msg("Failed DirectX with %d", x);
return NULL;
}
Log::Msg("Created Device / Swap Chain");
SwapChainVtable = (DWORD_PTR*)pSwapChain;
Log::Msg("Swap Chain VTable: 0x%I64X", SwapChainVtable);
SwapChainVtable = (DWORD_PTR*)SwapChainVtable[0];
Log::Msg("Swap Chain VTable: 0x%I64X", SwapChainVtable);
Log::Msg("Hooking Present Hook");
Log::Msg("Hooking From: 0x%I64X", (DWORD_PTR*)SwapChainVtable[8]);
Log::Msg("Hooking From: 0x%I64X", (DWORD64)&SwapChainVtable[8]);
Log::Msg("Hooking To : 0x%I64X", reinterpret_cast<void**>(&originalD3D11PresentHook));
Log::Msg("Hooking To : 0x%I64X", &originalD3D11PresentHook);
if (MH_CreateHook((DWORD_PTR*)SwapChainVtable[8], detourD3D11PresentHook, reinterpret_cast<void**>(&originalD3D11PresentHook)) != MH_OK) { return 1; }
if (MH_EnableHook((DWORD_PTR*)SwapChainVtable[8]) != MH_OK) { return 1; }
DWORD dwOld;
VirtualProtect(originalD3D11PresentHook, 2, PAGE_EXECUTE_READWRITE, &dwOld);
Log::Msg("Hooked!");
while (true) {
Sleep(10);
}
DX11Device->Release();
DX11DeviceContext->Release();
pSwapChain->Release();
return NULL;
}
void DX11Hook::CreateRenderTarget()
{
DXGI_SWAP_CHAIN_DESC sd;
DX11SwapChain->GetDesc(&sd);
// Create the render target
ID3D11Texture2D* pBackBuffer;
D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc;
ZeroMemory(&render_target_view_desc, sizeof(render_target_view_desc));
render_target_view_desc.Format = sd.BufferDesc.Format;
render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
DX11SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
DX11Device->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &DX11RenderTargetView);
DX11DeviceContext->OMSetRenderTargets(1, &DX11RenderTargetView, NULL);
pBackBuffer->Release();
}
BOOLEAN DX11Hook::InitDX11RenderStuff(IDXGISwapChain* _SwapChain)
{
DX11SwapChain = _SwapChain;
DX11SwapChain->GetDevice(__uuidof(DX11Device), (void**)&DX11Device);
DX11Device->GetImmediateContext(&DX11DeviceContext);
CreateRenderTarget();
// Setup ImGui binding
ImGui_ImplDX11_Init(Hooking::getWindow(), DX11Device, DX11DeviceContext);
Initialized = TRUE;
return TRUE;
}
void DX11Hook::CleanupRenderTarget()
{
if (DX11RenderTargetView) { DX11RenderTargetView->Release(); DX11RenderTargetView = NULL; }
}
void DX11Hook::CleanupDeviceD3D()
{
CleanupRenderTarget();
if (DX11SwapChain) { DX11SwapChain->Release(); DX11SwapChain = NULL; }
if (DX11DeviceContext) { DX11DeviceContext->Release(); DX11DeviceContext = NULL; }
if (DX11Device) { DX11Device->Release(); DX11Device = NULL; }
if (MH_DisableHook((DWORD_PTR*)SwapChainVtable[8]) != MH_OK) { return; }
}
void DX11Hook::ResizeBuffers(UINT width, UINT height)
{
if (DX11Device != NULL)
{
ImGui_ImplDX11_InvalidateDeviceObjects();
CleanupRenderTarget();
DX11SwapChain->ResizeBuffers(0, width, height, DXGI_FORMAT_UNKNOWN, 0);
CreateRenderTarget();
ImGui_ImplDX11_CreateDeviceObjects();
}
}
std::unique_ptr<DX11Hook> DX11;