diff --git a/overlay_experimental/Base_Hook.cpp b/overlay_experimental/Base_Hook.cpp index 452309e..3c73584 100644 --- a/overlay_experimental/Base_Hook.cpp +++ b/overlay_experimental/Base_Hook.cpp @@ -45,6 +45,11 @@ void Base_Hook::UnhookAll() } } +const char* Base_Hook::get_lib_name() const +{ + return ""; +} + void Base_Hook::HookFunc(std::pair hook) { if( DetourAttach(hook.first, hook.second) == 0 ) diff --git a/overlay_experimental/Base_Hook.h b/overlay_experimental/Base_Hook.h index bb0c2dd..55fbfae 100644 --- a/overlay_experimental/Base_Hook.h +++ b/overlay_experimental/Base_Hook.h @@ -29,6 +29,7 @@ public: void EndHook(); void UnhookAll(); + virtual const char* get_lib_name() const; void HookFunc(std::pair hook); template diff --git a/overlay_experimental/DX10_Hook.cpp b/overlay_experimental/DX10_Hook.cpp index 54e43b7..6f5db63 100644 --- a/overlay_experimental/DX10_Hook.cpp +++ b/overlay_experimental/DX10_Hook.cpp @@ -18,56 +18,21 @@ bool DX10_Hook::start_hook() if (!Windows_Hook::Inst().start_hook()) return false; - HWND hWnd = GetGameWindow(); - if (!hWnd) - return false; + PRINT_DEBUG("Hooked DirectX 10\n"); + _hooked = true; - IDXGISwapChain* pSwapChain; - ID3D10Device* pDevice; - DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; - decltype(D3D10CreateDeviceAndSwapChain)* D3D10CreateDeviceAndSwapChain = - (decltype(D3D10CreateDeviceAndSwapChain))GetProcAddress(reinterpret_cast(_library), "D3D10CreateDeviceAndSwapChain"); - SwapChainDesc.BufferCount = 1; - SwapChainDesc.BufferDesc.Width = 1; - SwapChainDesc.BufferDesc.Height = 1; - SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; - SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; - SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - SwapChainDesc.OutputWindow = hWnd; - SwapChainDesc.SampleDesc.Count = 1; - SwapChainDesc.SampleDesc.Quality = 0; - SwapChainDesc.Windowed = TRUE; + Hook_Manager::Inst().FoundRenderer(this); - D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_NULL, NULL, 0, D3D10_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDevice); + UnhookAll(); + BeginHook(); + HookFuncs( + std::make_pair(&(PVOID&)DX10_Hook::Present, &DX10_Hook::MyPresent), + std::make_pair(&(PVOID&)DX10_Hook::ResizeTarget, &DX10_Hook::MyResizeTarget), + std::make_pair(&(PVOID&)DX10_Hook::ResizeBuffers, &DX10_Hook::MyResizeBuffers) + ); + EndHook(); - if (pDevice != nullptr && pSwapChain != nullptr) - { - PRINT_DEBUG("Hooked DirectX 10\n"); - - _hooked = true; - Hook_Manager::Inst().FoundRenderer(this); - - loadFunctions(pDevice, pSwapChain); - - UnhookAll(); - BeginHook(); - HookFuncs( - std::make_pair(&(PVOID&)DX10_Hook::Present, &DX10_Hook::MyPresent), - std::make_pair(&(PVOID&)DX10_Hook::ResizeTarget, &DX10_Hook::MyResizeTarget), - std::make_pair(&(PVOID&)DX10_Hook::ResizeBuffers, &DX10_Hook::MyResizeBuffers) - ); - EndHook(); - - get_steam_client()->steam_overlay->HookReady(); - } - else - { - PRINT_DEBUG("Failed to hook DirectX 10\n"); - res = false; - } - if(pDevice)pDevice->Release(); - if(pSwapChain)pSwapChain->Release(); + get_steam_client()->steam_overlay->HookReady(); } return res; } @@ -220,6 +185,11 @@ DX10_Hook* DX10_Hook::Inst() return _inst; } +const char* DX10_Hook::get_lib_name() const +{ + return DLL_NAME; +} + void DX10_Hook::loadFunctions(ID3D10Device *pDevice, IDXGISwapChain *pSwapChain) { void** vTable = *reinterpret_cast(pDevice); diff --git a/overlay_experimental/DX10_Hook.h b/overlay_experimental/DX10_Hook.h index e66e840..4979e74 100644 --- a/overlay_experimental/DX10_Hook.h +++ b/overlay_experimental/DX10_Hook.h @@ -46,6 +46,7 @@ private: public: bool start_hook(); static DX10_Hook* Inst(); + virtual const char* get_lib_name() const; void loadFunctions(ID3D10Device *pDevice, IDXGISwapChain *pSwapChain); }; diff --git a/overlay_experimental/DX11_Hook.cpp b/overlay_experimental/DX11_Hook.cpp index c27ede6..9cda270 100644 --- a/overlay_experimental/DX11_Hook.cpp +++ b/overlay_experimental/DX11_Hook.cpp @@ -28,57 +28,21 @@ bool DX11_Hook::start_hook() if (!Windows_Hook::Inst().start_hook()) return false; - HWND hWnd = GetGameWindow(); - if (!hWnd) - return false; + PRINT_DEBUG("Hooked DirectX 11\n"); + _hooked = true; - IDXGISwapChain* pSwapChain; - ID3D11Device* pDevice; - DXGI_SWAP_CHAIN_DESC SwapChainDesc = {}; - decltype(D3D11CreateDeviceAndSwapChain)* D3D11CreateDeviceAndSwapChain = - (decltype(D3D11CreateDeviceAndSwapChain))GetProcAddress(reinterpret_cast(_library), "D3D11CreateDeviceAndSwapChain"); - SwapChainDesc.BufferCount = 1; - SwapChainDesc.BufferDesc.Width = 1; - SwapChainDesc.BufferDesc.Height = 1; - SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; - SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0; - SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - SwapChainDesc.OutputWindow = hWnd; - SwapChainDesc.SampleDesc.Count = 1; - SwapChainDesc.SampleDesc.Quality = 0; - SwapChainDesc.Windowed = TRUE; + Hook_Manager::Inst().FoundRenderer(this); - D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, NULL, D3D11_SDK_VERSION, &SwapChainDesc, &pSwapChain, &pDevice, NULL, NULL); + UnhookAll(); + BeginHook(); + HookFuncs( + std::make_pair(&(PVOID&)DX11_Hook::Present, &DX11_Hook::MyPresent), + std::make_pair(&(PVOID&)DX11_Hook::ResizeTarget, &DX11_Hook::MyResizeTarget), + std::make_pair(&(PVOID&)DX11_Hook::ResizeBuffers, &DX11_Hook::MyResizeBuffers) + ); + EndHook(); - if (pDevice != nullptr && pSwapChain != nullptr) - { - PRINT_DEBUG("Hooked DirectX 11\n"); - - _hooked = true; - Hook_Manager::Inst().FoundRenderer(this); - - loadFunctions(pDevice, pSwapChain); - - UnhookAll(); - BeginHook(); - HookFuncs( - std::make_pair(&(PVOID&)DX11_Hook::Present, &DX11_Hook::MyPresent), - std::make_pair(&(PVOID&)DX11_Hook::ResizeTarget, &DX11_Hook::MyResizeTarget), - std::make_pair(&(PVOID&)DX11_Hook::ResizeBuffers, &DX11_Hook::MyResizeBuffers) - ); - EndHook(); - - get_steam_client()->steam_overlay->HookReady(); - } - else - { - PRINT_DEBUG("Failed to hook DirectX 11\n"); - res = false; - } - - if(pDevice) pDevice->Release(); - if(pSwapChain) pSwapChain->Release(); + get_steam_client()->steam_overlay->HookReady(); } return res; } @@ -239,6 +203,11 @@ DX11_Hook* DX11_Hook::Inst() return _inst; } +const char* DX11_Hook::get_lib_name() const +{ + return DLL_NAME; +} + void DX11_Hook::loadFunctions(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain) { void** vTable = *reinterpret_cast(pDevice); diff --git a/overlay_experimental/DX11_Hook.h b/overlay_experimental/DX11_Hook.h index 207252f..83de88d 100644 --- a/overlay_experimental/DX11_Hook.h +++ b/overlay_experimental/DX11_Hook.h @@ -46,6 +46,7 @@ private: public: bool start_hook(); static DX11_Hook* Inst(); + virtual const char* get_lib_name() const; void loadFunctions(ID3D11Device *pDevice, IDXGISwapChain *pSwapChain); }; diff --git a/overlay_experimental/DX9_Hook.cpp b/overlay_experimental/DX9_Hook.cpp index 1842493..e5a0113 100644 --- a/overlay_experimental/DX9_Hook.cpp +++ b/overlay_experimental/DX9_Hook.cpp @@ -14,60 +14,34 @@ DX9_Hook* DX9_Hook::_inst = nullptr; bool DX9_Hook::start_hook() { - bool res = true; if (!_hooked) { if (!Windows_Hook::Inst().start_hook()) return false; - HWND hWnd = GetGameWindow(); - if (!hWnd) - return false; + PRINT_DEBUG("Hooked DirectX 9\n"); + _hooked = true; - IDirect3D9Ex* pD3D; - IDirect3DDevice9Ex* pDeviceEx; - decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(reinterpret_cast(_library), "Direct3DCreate9Ex"); - - Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D); - - D3DPRESENT_PARAMETERS params = {}; - params.BackBufferWidth = 1; - params.BackBufferHeight = 1; - params.hDeviceWindow = hWnd; - - pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, &pDeviceEx); - - if (pDeviceEx != nullptr) + Hook_Manager::Inst().FoundRenderer(this); + + UnhookAll(); + BeginHook(); + HookFuncs( + std::make_pair(&(PVOID&)Reset, &DX9_Hook::MyReset), + std::make_pair(&(PVOID&)Present, &DX9_Hook::MyPresent) + ); + if (PresentEx != nullptr) { - PRINT_DEBUG("Hooked DirectX 9\n"); - - _hooked = true; - Hook_Manager::Inst().FoundRenderer(this); - - loadFunctions(pDeviceEx); - - UnhookAll(); - BeginHook(); HookFuncs( - std::make_pair(&(PVOID&)Reset, &DX9_Hook::MyReset), - std::make_pair(&(PVOID&)Present, &DX9_Hook::MyPresent), std::make_pair(&(PVOID&)PresentEx, &DX9_Hook::MyPresentEx) //std::make_pair(&(PVOID&)EndScene, &DX9_Hook::MyEndScene) ); - EndHook(); - - get_steam_client()->steam_overlay->HookReady(); - } - else - { - PRINT_DEBUG("Failed to DirectX 9\n"); - res = false; } + EndHook(); - if(pDeviceEx)pDeviceEx->Release(); - if(pD3D)pD3D->Release(); + get_steam_client()->steam_overlay->HookReady(); } - return res; + return true; } void DX9_Hook::resetRenderState() @@ -220,15 +194,21 @@ DX9_Hook* DX9_Hook::Inst() return _inst; } -void DX9_Hook::loadFunctions(IDirect3DDevice9Ex* pDeviceEx) +const char* DX9_Hook::get_lib_name() const { - void** vTable = *reinterpret_cast(pDeviceEx); + return DLL_NAME; +} + +void DX9_Hook::loadFunctions(IDirect3DDevice9* pDevice, bool ex) +{ + void** vTable = *reinterpret_cast(pDevice); #define LOAD_FUNC(X) (void*&)X = vTable[(int)IDirect3DDevice9VTable::X] LOAD_FUNC(Reset); LOAD_FUNC(EndScene); LOAD_FUNC(Present); - LOAD_FUNC(PresentEx); + if (ex) + LOAD_FUNC(PresentEx); #undef LOAD_FUNC } diff --git a/overlay_experimental/DX9_Hook.h b/overlay_experimental/DX9_Hook.h index c795fe3..6239f1b 100644 --- a/overlay_experimental/DX9_Hook.h +++ b/overlay_experimental/DX9_Hook.h @@ -47,8 +47,9 @@ private: public: bool start_hook(); static DX9_Hook* Inst(); + virtual const char* get_lib_name() const; - void loadFunctions(IDirect3DDevice9Ex *pDeviceEx); + void loadFunctions(IDirect3DDevice9 *pDevice, bool ex); }; #endif//NO_OVERLAY diff --git a/overlay_experimental/DirectX_VTables.h b/overlay_experimental/DirectX_VTables.h index 73a2847..46f0497 100644 --- a/overlay_experimental/DirectX_VTables.h +++ b/overlay_experimental/DirectX_VTables.h @@ -44,6 +44,111 @@ enum class IDXGISwapChainVTable GetRotation, }; +enum class ID3D12CommandQueueVTable +{ + // IUnknown + QueryInterface, + AddRef, + Release, + + // ID3D12Object + GetPrivateData, + SetPrivateData, + SetPrivateDataInterface, + SetName, + + // ID3D12DeviceChild + GetDevice, + + // ID3D12Pageable + + // ID3D12CommandQueue + UpdateTileMappings, + CopyTileMappings, + ExecuteCommandLists, + SetMarker, + BeginEvent, + EndEvent, + Signal, + Wait, + GetTimestampFrequency, + GetClockCalibration, + GetDesc, +}; + +enum class ID3D12GraphicsCommandListVTable +{ + // IUnknown + QueryInterface, + AddRef, + Release, + + // ID3D12Object + GetPrivateData, + SetPrivateData, + SetPrivateDataInterface, + SetName, + + // ID3D12DeviceChild + GetDevice, + + // ID3D12CommandList + GetType, + + // ID3D12GraphicsCommandList + Close, + Reset, + ClearState, + DrawInstanced, + DrawIndexedInstanced, + Dispatch, + CopyBufferRegion, + CopyTextureRegion, + CopyResource, + CopyTiles, + ResolveSubresource, + IASetPrimitiveTopology, + RSSetViewports, + RSSetScissorRects, + OMSetBlendFactor, + OMSetStencilRef, + SetPipelineState, + ResourceBarrier, + ExecuteBundle, + SetDescriptorHeaps, + SetComputeRootSignature, + SetGraphicsRootSignature, + SetComputeRootDescriptorTable, + SetGraphicsRootDescriptorTable, + SetComputeRoot32BitConstant, + SetGraphicsRoot32BitConstant, + SetComputeRoot32BitConstants, + SetGraphicsRoot32BitConstants, + SetComputeRootConstantBufferView, + SetGraphicsRootConstantBufferView, + SetComputeRootShaderResourceView, + SetGraphicsRootShaderResourceView, + SetComputeRootUnorderedAccessView, + SetGraphicsRootUnorderedAccessView, + IASetIndexBuffer, + IASetVertexBuffers, + SOSetTargets, + OMSetRenderTargets, + ClearDepthStencilView, + ClearRenderTargetView, + ClearUnorderedAccessViewUint, + ClearUnorderedAccessViewFloat, + DiscardResource, + BeginQuery, + EndQuery, + ResolveQueryData, + SetPredication, + SetMarker, + BeginEvent, + EndEvent, + ExecuteIndirect, +}; + enum class ID3D11DeviceVTable { // IUnknown diff --git a/overlay_experimental/Hook_Manager.cpp b/overlay_experimental/Hook_Manager.cpp index a6458e7..4b18fa6 100644 --- a/overlay_experimental/Hook_Manager.cpp +++ b/overlay_experimental/Hook_Manager.cpp @@ -20,10 +20,10 @@ constexpr int max_hook_retries = 500; #ifdef STEAM_WIN32 -static decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present; -static decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present; -static decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx; -static decltype(wglMakeCurrent)* _wglMakeCurrent; +static decltype(&IDXGISwapChain::Present) _IDXGISwapChain_Present = nullptr; +static decltype(&IDirect3DDevice9::Present) _IDirect3DDevice9_Present = nullptr; +static decltype(&IDirect3DDevice9Ex::PresentEx) _IDirect3DDevice9Ex_PresentEx = nullptr; +static decltype(wglMakeCurrent)* _wglMakeCurrent = nullptr; HRESULT STDMETHODCALLTYPE Hook_Manager::MyIDXGISwapChain_Present(IDXGISwapChain* _this, UINT SyncInterval, UINT Flags) { @@ -100,11 +100,13 @@ BOOL WINAPI Hook_Manager::MywglMakeCurrent(HDC hDC, HGLRC hGLRC) return _wglMakeCurrent(hDC, hGLRC); } -void Hook_Manager::HookDXGIPresent() +void Hook_Manager::HookDXGIPresent(IDXGISwapChain *pSwapChain) { if (!_dxgi_hooked) { _dxgi_hooked = true; + (void*&)_IDXGISwapChain_Present = (*reinterpret_cast(pSwapChain))[(int)IDXGISwapChainVTable::Present]; + rendererdetect_hook->BeginHook(); rendererdetect_hook->HookFuncs( @@ -115,17 +117,26 @@ void Hook_Manager::HookDXGIPresent() } } -void Hook_Manager::HookDX9Present() +void Hook_Manager::HookDX9Present(IDirect3DDevice9* pDevice, bool ex) { if (!_dx9_hooked) { _dx9_hooked = true; + (void*&)_IDirect3DDevice9_Present = (*reinterpret_cast(pDevice))[(int)IDirect3DDevice9VTable::Present]; + if (ex) + (void*&)_IDirect3DDevice9Ex_PresentEx = (*reinterpret_cast(pDevice))[(int)IDirect3DDevice9VTable::PresentEx]; + rendererdetect_hook->BeginHook(); rendererdetect_hook->HookFuncs( - std::pair((PVOID*)& _IDirect3DDevice9_Present, &Hook_Manager::MyPresent), - std::pair((PVOID*)& _IDirect3DDevice9Ex_PresentEx, &Hook_Manager::MyPresentEx) + std::pair((PVOID*)& _IDirect3DDevice9_Present, &Hook_Manager::MyPresent) ); + if (ex) + { + rendererdetect_hook->HookFuncs( + std::pair((PVOID*)& _IDirect3DDevice9Ex_PresentEx, &Hook_Manager::MyPresentEx) + ); + } rendererdetect_hook->EndHook(); } @@ -154,33 +165,48 @@ void Hook_Manager::hook_dx9() if (!hWnd) return; - IDirect3D9Ex* pD3D; - IDirect3DDevice9Ex* pDeviceEx; - decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(GetModuleHandle(DX9_Hook::DLL_NAME), "Direct3DCreate9Ex"); - - Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D); + IDirect3D9Ex* pD3D = nullptr; + IUnknown* pDevice = nullptr; D3DPRESENT_PARAMETERS params = {}; params.BackBufferWidth = 1; params.BackBufferHeight = 1; params.hDeviceWindow = hWnd; + params.BackBufferCount = 1; + params.Windowed = TRUE; + params.SwapEffect = D3DSWAPEFFECT_DISCARD; - pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, &pDeviceEx); - - if (pDeviceEx) + decltype(Direct3DCreate9Ex)* Direct3DCreate9Ex = (decltype(Direct3DCreate9Ex))GetProcAddress(GetModuleHandle(DX9_Hook::DLL_NAME), "Direct3DCreate9Ex"); + if (Direct3DCreate9Ex != nullptr) + { + Direct3DCreate9Ex(D3D_SDK_VERSION, &pD3D); + pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, NULL, reinterpret_cast(&pDevice)); + } + else + { + decltype(Direct3DCreate9)* Direct3DCreate9 = (decltype(Direct3DCreate9))GetProcAddress(GetModuleHandle(DX9_Hook::DLL_NAME), "Direct3DCreate9"); + if (Direct3DCreate9) + { + pD3D = reinterpret_cast(Direct3DCreate9(D3D_SDK_VERSION)); + pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, reinterpret_cast(&pDevice)); + } + } + + if (pDevice != nullptr) { PRINT_DEBUG("Hooked D3D9::Present to detect DX Version\n"); - (void*&)_IDirect3DDevice9_Present = (*reinterpret_cast(pDeviceEx))[(int)IDirect3DDevice9VTable::Present]; - (void*&)_IDirect3DDevice9Ex_PresentEx = (*reinterpret_cast(pDeviceEx))[(int)IDirect3DDevice9VTable::PresentEx]; - HookDX9Present(); + auto h = DX9_Hook::Inst(); + h->loadFunctions(reinterpret_cast(pDevice), Direct3DCreate9Ex != nullptr); + _hooks.insert(h); + HookDX9Present(reinterpret_cast(pDevice), Direct3DCreate9Ex != nullptr); } else { PRINT_DEBUG("Failed to hook D3D9::Present to detect DX Version\n"); } - if (pDeviceEx)pDeviceEx->Release(); - if (pD3D)pD3D->Release(); + if (pDevice) pDevice->Release(); + if (pD3D) pD3D->Release(); } } @@ -214,8 +240,10 @@ void Hook_Manager::hook_dx10() if (pDevice != nullptr && pSwapChain != nullptr) { PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); - (void*&)_IDXGISwapChain_Present = (*reinterpret_cast(pSwapChain))[(int)IDXGISwapChainVTable::Present]; - HookDXGIPresent(); + auto h = DX10_Hook::Inst(); + h->loadFunctions(pDevice, pSwapChain); + _hooks.insert(h); + HookDXGIPresent(pSwapChain); } else { @@ -256,8 +284,10 @@ void Hook_Manager::hook_dx11() if (pDevice != nullptr && pSwapChain != nullptr) { PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); - (void*&)_IDXGISwapChain_Present = (*reinterpret_cast(pSwapChain))[(int)IDXGISwapChainVTable::Present]; - HookDXGIPresent(); + auto h = DX11_Hook::Inst(); + h->loadFunctions(pDevice, pSwapChain); + _hooks.insert(h); + HookDXGIPresent(pSwapChain); } else { @@ -282,6 +312,7 @@ void Hook_Manager::hook_dx12() D3D12_COMMAND_QUEUE_DESC queueDesc = {}; ID3D12CommandQueue* pCommandQueue = nullptr; ID3D12Device* pDevice = nullptr; + decltype(D3D12CreateDevice)* D3D12CreateDevice = (decltype(D3D12CreateDevice))GetProcAddress(GetModuleHandle(DX12_Hook::DLL_NAME), "D3D12CreateDevice"); @@ -290,14 +321,14 @@ void Hook_Manager::hook_dx12() if (pDevice) { DXGI_SWAP_CHAIN_DESC1 SwapChainDesc = {}; - SwapChainDesc.Width = 0; - SwapChainDesc.Height = 0; + SwapChainDesc.BufferCount = 2; + SwapChainDesc.Width = 1; + SwapChainDesc.Height = 1; SwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; SwapChainDesc.Stereo = FALSE; SwapChainDesc.SampleDesc = { 1, 0 }; SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - SwapChainDesc.BufferCount = 3; - SwapChainDesc.Scaling = DXGI_SCALING_STRETCH; + SwapChainDesc.Scaling = DXGI_SCALING_NONE; SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; @@ -312,8 +343,11 @@ void Hook_Manager::hook_dx12() if (pSwapChain != nullptr) { PRINT_DEBUG("Hooked IDXGISwapChain::Present to detect DX Version\n"); - (void*&)_IDXGISwapChain_Present = (*reinterpret_cast(pSwapChain))[(int)IDXGISwapChainVTable::Present]; - HookDXGIPresent(); + + auto h = DX12_Hook::Inst(); + h->loadFunctions(pDevice, pCommandQueue, pSwapChain); + _hooks.insert(h); + HookDXGIPresent(pSwapChain); } else { @@ -472,6 +506,7 @@ void Hook_Manager::FoundRenderer(Base_Hook* hook) if (!_renderer_found) { _renderer_found = true; + game_renderer = hook; if (hook == nullptr) PRINT_DEBUG("We found a renderer but couldn't hook it, aborting overlay hook.\n"); @@ -480,16 +515,15 @@ void Hook_Manager::FoundRenderer(Base_Hook* hook) _hook_thread->join(); delete _hook_thread; + _hook_thread = nullptr; // Remove all hooks that are unused - _hooks.erase(std::remove_if(_hooks.begin(), _hooks.end(), [&hook](Base_Hook* it_hook) { - if (hook != it_hook) - { - delete it_hook; - return true; - } - return false; - }), _hooks.end()); + std::set::iterator item; + while ((item = std::find_if(_hooks.begin(), _hooks.end(), [hook](Base_Hook* item) {return item != hook; })) != _hooks.end()) + { + delete *item; + _hooks.erase(item); + } } } diff --git a/overlay_experimental/Hook_Manager.h b/overlay_experimental/Hook_Manager.h index ec0318e..8f1e367 100644 --- a/overlay_experimental/Hook_Manager.h +++ b/overlay_experimental/Hook_Manager.h @@ -5,7 +5,7 @@ #ifndef NO_OVERLAY -#include +#include #include #if defined(_WIN32) || defined(WIN32) @@ -30,13 +30,14 @@ protected: // TODO: If needed, create a second vector with only the renderers hook // Cause actually, a call to FoundRenderer will unhook everything registered except the renderer hook // If you do that, you should consider moving the renderer hooks to its own class and keep this one generic ? - std::vector _hooks; + std::set _hooks; std::thread *_hook_thread; unsigned int _hook_retries; bool _renderer_found; // Is the renderer hooked ? bool _ogl_hooked; // wglMakeCurrent is hooked ? (opengl) Base_Hook* rendererdetect_hook; + Base_Hook* game_renderer; class Steam_Overlay* overlay; Hook_Manager(); @@ -54,9 +55,9 @@ protected: bool _dxgi_hooked; // DXGI Present is hooked ? (DX10, DX11, DX12) // DXGIPresent will be used to detect if DX10, DX11 or DX12 should be used for overlay - void HookDXGIPresent(); + void HookDXGIPresent(IDXGISwapChain* pSwapChain); // DX9 Present and PresentEx will be used to detect if DX9 should be used for overlay - void HookDX9Present(); + void HookDX9Present(IDirect3DDevice9* pDevice, bool ex); // wglMakeCurrent will be used to detect if OpenGL3 should be used for overlay void HookwglMakeCurrent(); // Setup DX9 Device and get vtable @@ -97,7 +98,9 @@ public: // Set the found hook and free all other hooks void FoundRenderer(Base_Hook *hook); - inline void AddHook(Base_Hook* hook) { _hooks.push_back(hook); } + inline void AddHook(Base_Hook* hook) { _hooks.insert(hook); } + + inline Base_Hook* get_renderer() const { return game_renderer; } }; #endif//NO_OVERLAY diff --git a/overlay_experimental/OpenGL_Hook.cpp b/overlay_experimental/OpenGL_Hook.cpp index de3071b..0b77924 100644 --- a/overlay_experimental/OpenGL_Hook.cpp +++ b/overlay_experimental/OpenGL_Hook.cpp @@ -152,4 +152,9 @@ OpenGL_Hook* OpenGL_Hook::Inst() return _inst; } +const char* OpenGL_Hook::get_lib_name() const +{ + return DLL_NAME; +} + #endif//NO_OVERLAY \ No newline at end of file diff --git a/overlay_experimental/OpenGL_Hook.h b/overlay_experimental/OpenGL_Hook.h index f6e2a9f..a0bdb2c 100644 --- a/overlay_experimental/OpenGL_Hook.h +++ b/overlay_experimental/OpenGL_Hook.h @@ -38,6 +38,7 @@ private: public: bool start_hook(); static OpenGL_Hook* Inst(); + virtual const char* get_lib_name() const; }; #endif//NO_OVERLAY diff --git a/overlay_experimental/Windows_Hook.cpp b/overlay_experimental/Windows_Hook.cpp index 4483a14..b7e5731 100644 --- a/overlay_experimental/Windows_Hook.cpp +++ b/overlay_experimental/Windows_Hook.cpp @@ -188,4 +188,9 @@ Windows_Hook& Windows_Hook::Inst() { static Windows_Hook _inst; return _inst; +} + +const char* Windows_Hook::get_lib_name() const +{ + return DLL_NAME; } \ No newline at end of file diff --git a/overlay_experimental/Windows_Hook.h b/overlay_experimental/Windows_Hook.h index be2a0e4..e4c03d3 100644 --- a/overlay_experimental/Windows_Hook.h +++ b/overlay_experimental/Windows_Hook.h @@ -40,6 +40,7 @@ public: WNDPROC GetGameWndProc() const; static Windows_Hook& Inst(); + virtual const char* get_lib_name() const; }; HWND GetGameWindow(); diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index 62c144e..f22712d 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -30,12 +30,13 @@ void Steam_Overlay::steam_overlay_callback(void* object, Common_Message* msg) _this->Callback(msg); } -Steam_Overlay::Steam_Overlay(Settings* settings, SteamCallResults* callback_results, SteamCallBacks* callbacks, RunEveryRunCB* run_every_runcb, Networking *network) : +Steam_Overlay::Steam_Overlay(Settings* settings, SteamCallResults* callback_results, SteamCallBacks* callbacks, RunEveryRunCB* run_every_runcb, Networking* network) : settings(settings), callback_results(callback_results), callbacks(callbacks), run_every_runcb(run_every_runcb), network(network), + setup_overlay_called(false), show_overlay(false), is_ready(false), notif_position(ENotificationPosition::k_EPositionBottomLeft), @@ -75,7 +76,12 @@ void Steam_Overlay::SetNotificationInset(int nHorizontalInset, int nVerticalInse void Steam_Overlay::SetupOverlay() { - Hook_Manager::Inst().HookRenderer(); + std::lock_guard lock(global_mutex); + if (!setup_overlay_called) + { + setup_overlay_called = true; + Hook_Manager::Inst().HookRenderer(); + } } void Steam_Overlay::HookReady() @@ -390,6 +396,9 @@ void Steam_Overlay::OverlayProc( int width, int height ) settings->get_local_name(), settings->get_local_steam_id().ConvertToUint64(), settings->get_local_game_id().AppID()); + ImGui::SameLine(); + Base_Hook *hook = Hook_Manager::Inst().get_renderer(); + ImGui::LabelText("##label", "Renderer: %s", (hook == nullptr ? "Unknown" : hook->get_lib_name())); ImGui::Spacing(); diff --git a/overlay_experimental/steam_overlay.h b/overlay_experimental/steam_overlay.h index c5dee4b..c3337f5 100644 --- a/overlay_experimental/steam_overlay.h +++ b/overlay_experimental/steam_overlay.h @@ -52,6 +52,7 @@ class Steam_Overlay // friend id, show client window (to chat and accept invite maybe) std::map friends; + bool setup_overlay_called; bool is_ready; bool show_overlay; ENotificationPosition notif_position;