diff options
Diffstat (limited to 'Source.cpp')
-rw-r--r-- | Source.cpp | 339 |
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 |