aboutsummaryrefslogtreecommitdiff
path: root/Source.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source.cpp')
-rw-r--r--Source.cpp339
1 files changed, 339 insertions, 0 deletions
diff --git a/Source.cpp b/Source.cpp
new file mode 100644
index 0000000..d2ab0a1
--- /dev/null
+++ b/Source.cpp
@@ -0,0 +1,339 @@
+#include <Windows.h>
+#include <intrin.h>
+#include <d3d11.h>
+#include <D3Dcompiler.h>
+#pragma comment(lib, "D3dcompiler.lib")
+#pragma comment(lib, "d3d11.lib")
+#pragma comment(lib, "winmm.lib")
+
+#include "imgui\imgui.h"
+#include "imgui\imgui_impl_win32.h"
+#include "imgui\imgui_impl_dx11.h"
+
+#include "detours.h"
+#if defined _M_X64
+#pragma comment(lib, "detours.X64/detours.lib")
+#elif defined _M_IX86
+#pragma comment(lib, "detours.X86/detours.lib")
+#endif
+
+#pragma warning( disable : 4244 )
+
+#include "Core.h"
+#include "FeatureManager.h"
+
+
+typedef HRESULT(__stdcall *D3D11PresentHook) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
+
+D3D11PresentHook phookD3D11Present = NULL;
+
+ID3D11Device *pDevice = NULL;
+ID3D11DeviceContext *pContext = NULL;
+
+DWORD_PTR* pSwapChainVtable = NULL;
+
+
+#include "main.h" //helper funcs
+
+
+VOID WINAPI OnDllAttach(PVOID base)
+{
+ AllocConsole();
+ freopen_s((FILE**)stdin, "CONIN$", "r", stdin);
+ freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
+ SetConsoleTitleA("Age of Empires 2 DE - BDKPlayer");
+}
+
+VOID WINAPI OnDllDetach()
+{
+ fclose((FILE*)stdin);
+ fclose((FILE*)stdout);
+
+ HWND hw_ConsoleHwnd = GetConsoleWindow();
+ FreeConsole();
+ PostMessageW(hw_ConsoleHwnd, WM_CLOSE, 0, 0);
+}
+
+extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ ImGuiIO& io = ImGui::GetIO();
+ POINT mPos;
+ GetCursorPos(&mPos);
+ ScreenToClient(window, &mPos);
+ ImGui::GetIO().MousePos.x = mPos.x;
+ ImGui::GetIO().MousePos.y = mPos.y;
+
+ if (uMsg == WM_KEYUP)
+ {
+ if (wParam == VK_INSERT)
+ {
+ if(ShowMenu)
+ io.MouseDrawCursor = true;
+ else
+ io.MouseDrawCursor = false;
+ }
+ }
+
+ if (ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam))
+ {
+ return true;
+ }
+
+ return CallWindowProc(OriginalWndProcHandler, hWnd, uMsg, wParam, lParam);
+}
+
+HRESULT __stdcall hookD3D11Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
+{
+ if (firstTime)
+ {
+ firstTime = false; //only once
+
+ //get device
+ if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void **)&pDevice)))
+ {
+ //SwapChain = pSwapChain;
+ pSwapChain->GetDevice(__uuidof(pDevice), (void**)&pDevice);
+ pDevice->GetImmediateContext(&pContext);
+ }
+
+ //imgui
+ DXGI_SWAP_CHAIN_DESC sd;
+ pSwapChain->GetDesc(&sd);
+ ImGui::CreateContext();
+ ImGuiIO& io = ImGui::GetIO(); (void)io;
+ ImGui::GetIO().WantCaptureMouse || ImGui::GetIO().WantTextInput || ImGui::GetIO().WantCaptureKeyboard; //control menu with mouse
+ io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
+ window = sd.OutputWindow;
+
+ //wndprochandler
+ OriginalWndProcHandler = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)hWndProc);
+
+ ImGui_ImplWin32_Init(window);
+ ImGui_ImplDX11_Init(pDevice, pContext);
+ ImGui::GetIO().ImeWindowHandle = window;
+
+ // Create depthstencil state
+ D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
+ depthStencilDesc.DepthEnable = TRUE;
+ depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ depthStencilDesc.StencilEnable = FALSE;
+ depthStencilDesc.StencilReadMask = 0xFF;
+ depthStencilDesc.StencilWriteMask = 0xFF;
+ // Stencil operations if pixel is front-facing
+ depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
+ depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ // Stencil operations if pixel is back-facing
+ depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
+ depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ pDevice->CreateDepthStencilState(&depthStencilDesc, &DepthStencilState_FALSE);
+
+ //create depthbias rasterizer state
+ D3D11_RASTERIZER_DESC rasterizer_desc;
+ ZeroMemory(&rasterizer_desc, sizeof(rasterizer_desc));
+ rasterizer_desc.FillMode = D3D11_FILL_SOLID;
+ rasterizer_desc.CullMode = D3D11_CULL_NONE; //D3D11_CULL_FRONT;
+ rasterizer_desc.FrontCounterClockwise = false;
+ float bias = 1000.0f;
+ float bias_float = static_cast<float>(-bias);
+ bias_float /= 10000.0f;
+ rasterizer_desc.DepthBias = DEPTH_BIAS_D32_FLOAT(*(DWORD*)&bias_float);
+ rasterizer_desc.SlopeScaledDepthBias = 0.0f;
+ rasterizer_desc.DepthBiasClamp = 0.0f;
+ rasterizer_desc.DepthClipEnable = true;
+ rasterizer_desc.ScissorEnable = false;
+ rasterizer_desc.MultisampleEnable = false;
+ rasterizer_desc.AntialiasedLineEnable = false;
+ pDevice->CreateRasterizerState(&rasterizer_desc, &DEPTHBIASState_FALSE);
+
+ //create normal rasterizer state
+ D3D11_RASTERIZER_DESC nrasterizer_desc;
+ ZeroMemory(&nrasterizer_desc, sizeof(nrasterizer_desc));
+ nrasterizer_desc.FillMode = D3D11_FILL_SOLID;
+ //nrasterizer_desc.CullMode = D3D11_CULL_BACK; //flickering
+ nrasterizer_desc.CullMode = D3D11_CULL_NONE;
+ nrasterizer_desc.FrontCounterClockwise = false;
+ nrasterizer_desc.DepthBias = 0.0f;
+ nrasterizer_desc.SlopeScaledDepthBias = 0.0f;
+ nrasterizer_desc.DepthBiasClamp = 0.0f;
+ nrasterizer_desc.DepthClipEnable = true;
+ nrasterizer_desc.ScissorEnable = false;
+ nrasterizer_desc.MultisampleEnable = false;
+ nrasterizer_desc.AntialiasedLineEnable = false;
+ pDevice->CreateRasterizerState(&nrasterizer_desc, &DEPTHBIASState_TRUE);
+
+ //load cfg settings
+ LoadCfg();
+ }
+
+ //create rendertarget
+ if (RenderTargetView == NULL)
+ {
+ //viewport
+ pContext->RSGetViewports(&vps, &viewport);
+ ScreenCenterX = viewport.Width / 2.0f;
+ ScreenCenterY = viewport.Height / 2.0f;
+
+ //get backbuffer
+ ID3D11Texture2D* backbuffer = NULL;
+ hr = pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backbuffer);
+ if (FAILED(hr)) {
+ Log("Failed to get BackBuffer");
+ return hr;
+ }
+
+ //create rendertargetview
+ hr = pDevice->CreateRenderTargetView(backbuffer, NULL, &RenderTargetView);
+ backbuffer->Release();
+ if (FAILED(hr)) {
+ Log("Failed to get RenderTarget");
+ return hr;
+ }
+ }
+ else //call before you draw
+ pContext->OMSetRenderTargets(1, &RenderTargetView, NULL);
+
+
+ //imgui
+ ImGui_ImplWin32_NewFrame();
+ ImGui_ImplDX11_NewFrame();
+ ImGui::NewFrame();
+
+ static Core* core = new Core();
+ core->OnPresent();
+
+ ImGui::EndFrame();
+ ImGui::Render();
+ ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
+
+ return phookD3D11Present(pSwapChain, SyncInterval, Flags);
+}
+
+
+const int MultisampleCount = 1; // Set to 1 to disable multisampling
+LRESULT CALLBACK DXGIMsgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hwnd, uMsg, wParam, lParam); }
+DWORD __stdcall InitHooks(LPVOID hModule)
+{
+ //OnDllAttach(hModule);
+
+ HMODULE hDXGIDLL = 0;
+ do
+ {
+ hDXGIDLL = GetModuleHandleA("dxgi.dll");
+ Sleep(4000);
+ } while (!hDXGIDLL);
+ Sleep(100);
+
+ IDXGISwapChain* pSwapChain;
+
+ WNDCLASSEXA wc = { sizeof(WNDCLASSEX), CS_CLASSDC, DXGIMsgProc, 0L, 0L, GetModuleHandleA(NULL), NULL, NULL, NULL, NULL, "DX", NULL };
+ RegisterClassExA(&wc);
+ HWND hWnd = CreateWindowA("DX", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, wc.hInstance, NULL);
+
+ 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 = hWnd;
+ scd.SampleDesc.Count = MultisampleCount;
+ scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+ scd.Windowed = ((GetWindowLongPtr(hWnd, GWL_STYLE) & WS_POPUP) != 0) ? false : true;
+
+ scd.BufferDesc.Width = 1;
+ scd.BufferDesc.Height = 1;
+ scd.BufferDesc.RefreshRate.Numerator = 0;
+ scd.BufferDesc.RefreshRate.Denominator = 1;
+
+ UINT createFlags = 0;
+#ifdef _DEBUG
+ createFlags |= D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+ IDXGISwapChain* d3dSwapChain = 0;
+
+ if (FAILED(D3D11CreateDeviceAndSwapChain(
+ nullptr,
+ D3D_DRIVER_TYPE_HARDWARE,
+ nullptr,
+ createFlags,
+ requestedLevels,
+ sizeof(requestedLevels) / sizeof(D3D_FEATURE_LEVEL),
+ D3D11_SDK_VERSION,
+ &scd,
+ &pSwapChain,
+ &pDevice,
+ &obtainedLevel,
+ &pContext)))
+ {
+ MessageBoxA(hWnd, "Failed to create directX device and swapchain!", "Error", MB_ICONERROR);
+ return NULL;
+ }
+
+
+ pSwapChainVtable = (DWORD_PTR*)pSwapChain;
+ pSwapChainVtable = (DWORD_PTR*)pSwapChainVtable[0];
+
+ phookD3D11Present = (D3D11PresentHook)(DWORD_PTR*)pSwapChainVtable[8];
+
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourAttach(&(LPVOID&)phookD3D11Present, (PBYTE)hookD3D11Present);
+ DetourTransactionCommit();
+
+ DWORD dwOld;
+ VirtualProtect(phookD3D11Present, 2, PAGE_EXECUTE_READWRITE, &dwOld);
+
+ while (!(GetAsyncKeyState(VK_DELETE) & 0x8000)) {
+ Sleep(10);
+ }
+
+ pDevice->Release();
+ pContext->Release();
+ pSwapChain->Release();
+
+ FeatureManager::Get()->OnShutdown();
+
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+ DetourDetach(&(LPVOID&)phookD3D11Present, (PBYTE)hookD3D11Present);
+ DetourTransactionCommit();
+
+ (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)OriginalWndProcHandler);
+
+ FreeLibraryAndExitThread((HMODULE)hModule, 0);
+
+ return NULL;
+}
+
+BOOL __stdcall DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
+{
+ switch (dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hModule);
+ CreateThread(NULL, 0, InitHooks, hModule, 0, NULL);
+ break;
+
+ case DLL_PROCESS_DETACH:
+ Sleep(1000);
+ //OnDllDetach();
+ //Sleep(100);
+ break;
+ }
+ return TRUE;
+} \ No newline at end of file