2021-12-25 22:36:38 +01:00
# include "core/stdafx.h"
# ifndef DEDICATED // This file should not be compiled for DEDICATED!
//------------------------------
# define STB_IMAGE_IMPLEMENTATION
2022-08-21 19:35:06 +02:00
# include "tier0/threadtools.h"
2022-04-09 16:16:40 +02:00
# include "tier1/cvar.h"
2021-12-25 22:36:38 +01:00
# include "windows/id3dx.h"
# include "windows/input.h"
2023-09-12 11:06:16 +02:00
# include "geforce/reflex.h"
2021-12-25 22:36:38 +01:00
# include "gameui/IConsole.h"
# include "gameui/IBrowser.h"
2023-09-11 22:20:24 +02:00
# include "engine/framelimit.h"
2023-01-30 20:18:11 +01:00
# include "engine/sys_mainwind.h"
2021-12-25 22:36:38 +01:00
# include "inputsystem/inputsystem.h"
2023-12-26 01:42:54 +01:00
# include "materialsystem/cmaterialsystem.h"
2022-08-09 17:18:07 +02:00
# include "public/bitmap/stb_image.h"
2023-05-13 18:03:48 +02:00
# include "public/rendersystem/schema/texture.g.h"
2021-12-25 22:36:38 +01:00
/**********************************************************************************
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
File : id3dx . cpp
Date : 15 : 06 : 2021
Author : Kawe Mazidjatari
Purpose : Microsoft DirectX 11 ' IDXGISwapChain : : Present ' hook implementation
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
History :
- 15 : 06 : 2021 | 14 : 56 : Created by Kawe Mazidjatari
- 17 : 06 : 2021 | 13 : 12 : Destroy / release objects with ' GetResizeBuffers ' callback
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
///////////////////////////////////////////////////////////////////////////////////
typedef BOOL ( WINAPI * IPostMessageA ) ( HWND hWnd , UINT Msg , WPARAM wParam , LPARAM lParam ) ;
typedef BOOL ( WINAPI * IPostMessageW ) ( HWND hWnd , UINT Msg , WPARAM wParam , LPARAM lParam ) ;
///////////////////////////////////////////////////////////////////////////////////
2023-06-19 14:03:23 +02:00
extern BOOL g_bImGuiInitialized = FALSE ;
extern UINT g_nWindowRect [ 2 ] = { NULL , NULL } ;
2021-12-25 22:36:38 +01:00
///////////////////////////////////////////////////////////////////////////////////
2023-01-30 20:18:11 +01:00
static IPostMessageA s_oPostMessageA = NULL ;
static IPostMessageW s_oPostMessageW = NULL ;
2021-12-25 22:36:38 +01:00
///////////////////////////////////////////////////////////////////////////////////
2023-01-30 22:08:01 +01:00
static IDXGIResizeBuffers s_fnResizeBuffers = NULL ;
2023-01-30 20:18:11 +01:00
static IDXGISwapChainPresent s_fnSwapChainPresent = NULL ;
2021-12-25 22:36:38 +01:00
2024-02-24 02:15:09 +01:00
///////////////////////////////////////////////////////////////////////////////////
static CFrameLimit s_FrameLimiter ;
2021-12-25 22:36:38 +01:00
//#################################################################################
// WINDOW PROCEDURE
//#################################################################################
LRESULT CALLBACK DXGIMsgProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
return DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
}
//#################################################################################
// POST MESSAGE
//#################################################################################
BOOL WINAPI HPostMessageA ( HWND hWnd , UINT Msg , WPARAM wParam , LPARAM lParam )
{
if ( g_bBlockInput & & Msg = = WM_MOUSEMOVE )
{
return TRUE ;
}
2022-10-20 12:29:21 +02:00
return s_oPostMessageA ( hWnd , Msg , wParam , lParam ) ;
2021-12-25 22:36:38 +01:00
}
BOOL WINAPI HPostMessageW ( HWND hWnd , UINT Msg , WPARAM wParam , LPARAM lParam )
{
if ( g_bBlockInput & & Msg = = WM_MOUSEMOVE )
{
return TRUE ;
}
2022-10-20 12:29:21 +02:00
return s_oPostMessageW ( hWnd , Msg , wParam , lParam ) ;
2021-12-25 22:36:38 +01:00
}
//#################################################################################
2023-01-30 20:18:11 +01:00
// IMGUI
2021-12-25 22:36:38 +01:00
//#################################################################################
2023-06-18 17:50:11 +02:00
void ImGui_Init ( )
2021-12-25 22:36:38 +01:00
{
///////////////////////////////////////////////////////////////////////////////
IMGUI_CHECKVERSION ( ) ;
ImGui : : CreateContext ( ) ;
2024-02-25 01:47:46 +01:00
ImGuiViewport * const vp = ImGui : : GetMainViewport ( ) ;
vp - > PlatformHandleRaw = g_pGame - > GetWindow ( ) ;
2022-10-20 12:29:21 +02:00
ImGuiIO & io = ImGui : : GetIO ( ) ;
2021-12-25 22:36:38 +01:00
io . ConfigFlags | = ImGuiConfigFlags_IsSRGB ;
2023-06-18 22:16:43 +02:00
2023-09-11 20:38:18 +02:00
ImGui_ImplWin32_Init ( g_pGame - > GetWindow ( ) ) ;
2023-09-11 01:28:17 +02:00
ImGui_ImplDX11_Init ( D3D11Device ( ) , D3D11DeviceContext ( ) ) ;
2021-12-25 22:36:38 +01:00
}
2023-06-18 17:50:11 +02:00
void ImGui_Shutdown ( )
{
ImGui_ImplDX11_Shutdown ( ) ;
ImGui_ImplWin32_Shutdown ( ) ;
ImGui : : DestroyContext ( ) ;
}
2021-12-25 22:36:38 +01:00
void DrawImGui ( )
{
2023-06-16 23:16:02 +02:00
ImGui_ImplDX11_NewFrame ( ) ;
ImGui_ImplWin32_NewFrame ( ) ;
2021-12-25 22:36:38 +01:00
2023-06-16 23:16:02 +02:00
ImGui : : NewFrame ( ) ;
2021-12-25 22:36:38 +01:00
2023-06-16 23:16:02 +02:00
// This is required to disable the ctrl+tab menu as some users use this shortcut for other things in-game.
// See https://github.com/ocornut/imgui/issues/5641 for more details.
if ( GImGui - > ConfigNavWindowingKeyNext )
ImGui : : SetShortcutRouting ( GImGui - > ConfigNavWindowingKeyNext , ImGuiKeyOwner_None ) ;
if ( GImGui - > ConfigNavWindowingKeyPrev )
ImGui : : SetShortcutRouting ( GImGui - > ConfigNavWindowingKeyPrev , ImGuiKeyOwner_None ) ;
2023-01-29 19:07:02 +01:00
2024-01-21 21:29:23 +01:00
g_Browser . RunTask ( ) ;
g_Browser . RunFrame ( ) ;
2022-08-20 01:48:42 +02:00
2024-01-21 21:29:23 +01:00
g_Console . RunTask ( ) ;
g_Console . RunFrame ( ) ;
2021-12-25 22:36:38 +01:00
2023-06-16 23:16:02 +02:00
ImGui : : EndFrame ( ) ;
ImGui : : Render ( ) ;
2021-12-25 22:36:38 +01:00
2023-06-16 23:16:02 +02:00
ImGui_ImplDX11_RenderDrawData ( ImGui : : GetDrawData ( ) ) ;
2021-12-25 22:36:38 +01:00
}
//#################################################################################
2023-01-30 20:18:11 +01:00
// IDXGI
2021-12-25 22:36:38 +01:00
//#################################################################################
2024-02-24 02:15:09 +01:00
static ConVar fps_max_rt ( " fps_max_rt " , " 0 " , FCVAR_RELEASE , " Frame rate limiter within the render thread. -1 indicates the use of desktop refresh. 0 is disabled. " , true , - 1.f , true , 295.f ) ;
static ConVar fps_max_rt_tolerance ( " fps_max_rt_tolerance " , " 0.25 " , FCVAR_RELEASE , " Maximum amount of frame time before frame limiter restarts. " , true , 0.f , false , 0.f ) ;
static ConVar fps_max_rt_sleep_threshold ( " fps_max_rt_sleep_threshold " , " 0.016666667 " , FCVAR_RELEASE , " Frame limiter starts to sleep when frame time exceeds this threshold. " , true , 0.f , false , 0.f ) ;
2021-12-25 22:36:38 +01:00
HRESULT __stdcall Present ( IDXGISwapChain * pSwapChain , UINT nSyncInterval , UINT nFlags )
{
2024-02-24 02:15:09 +01:00
float targetFps = fps_max_rt . GetFloat ( ) ;
if ( targetFps > 0.0f )
{
const float globalFps = fps_max - > GetFloat ( ) ;
// Make sure the global fps limiter is 'unlimited'
// before we let the rt frame limiter cap it to
// the desktop's refresh rate; not adhering to
// this will result in a major performance drop.
if ( globalFps = = 0.0f & & targetFps = = - 1 )
targetFps = g_pGame - > GetTVRefreshRate ( ) ;
if ( targetFps > 0.0f )
{
const float sleepThreshold = fps_max_rt_sleep_threshold . GetFloat ( ) ;
const float maxTolerance = fps_max_rt_tolerance . GetFloat ( ) ;
s_FrameLimiter . Run ( targetFps , sleepThreshold , maxTolerance ) ;
}
}
2023-10-20 19:11:12 +02:00
2021-12-25 22:36:38 +01:00
///////////////////////////////////////////////////////////////////////////////
2023-12-26 01:42:54 +01:00
// NOTE: -1 since we need to sync this with its corresponding frame, g_FrameNum
// gets incremented in CMaterialSystem::SwapBuffers, which is after the markers
// for simulation start/end and render submit start. The render thread (here)
// continues after to finish the frame.
const NvU64 frameID = ( NvU64 ) MaterialSystem ( ) - > GetCurrentFrameCount ( ) - 1 ;
GFX_SetLatencyMarker ( D3D11Device ( ) , RENDERSUBMIT_END , frameID ) ;
GFX_SetLatencyMarker ( D3D11Device ( ) , PRESENT_START , frameID ) ;
const HRESULT result = s_fnSwapChainPresent ( pSwapChain , nSyncInterval , nFlags ) ;
GFX_SetLatencyMarker ( D3D11Device ( ) , PRESENT_END , frameID ) ;
2023-09-12 11:06:16 +02:00
2023-09-11 20:38:18 +02:00
return result ;
2021-12-25 22:36:38 +01:00
}
2023-01-30 22:08:01 +01:00
HRESULT __stdcall ResizeBuffers ( IDXGISwapChain * pSwapChain , UINT nBufferCount , UINT nWidth , UINT nHeight , DXGI_FORMAT dxFormat , UINT nSwapChainFlags )
{
g_nWindowRect [ 0 ] = nWidth ;
g_nWindowRect [ 1 ] = nHeight ;
///////////////////////////////////////////////////////////////////////////////
return s_fnResizeBuffers ( pSwapChain , nBufferCount , nWidth , nHeight , dxFormat , nSwapChainFlags ) ;
}
2023-01-30 20:18:11 +01:00
//#################################################################################
// INTERNALS
//#################################################################################
2023-05-13 18:03:48 +02:00
# pragma warning( push )
// Disable stack warning, tells us to move more data to the heap instead. Not really possible with 'initialData' here. Since its parallel processed.
// Also disable 6378, complains that there is no control path where it would use 'nullptr', if that happens 'Error' will be called though.
# pragma warning( disable : 6262 6387)
2023-07-02 23:01:29 +02:00
void ( * v_CreateTextureResource ) ( TextureHeader_t * , INT_PTR ) ;
2023-05-13 18:03:48 +02:00
constexpr uint32_t ALIGNMENT_SIZE = 15 ; // Creates 2D texture and shader resource from textureHeader and imageData.
2023-05-13 19:40:41 +02:00
void CreateTextureResource ( TextureHeader_t * textureHeader , INT_PTR imageData )
2023-05-13 18:03:48 +02:00
{
if ( textureHeader - > m_nDepth & & ! textureHeader - > m_nHeight ) // Return never gets hit. Maybe its some debug check?
return ;
__int64 initialData [ 4096 ] { } ;
textureHeader - > m_nTextureMipLevels = textureHeader - > m_nPermanentMipCount ;
const int totalStreamedMips = textureHeader - > m_nOptStreamedMipCount + textureHeader - > m_nStreamedMipCount ;
int mipLevel = textureHeader - > m_nPermanentMipCount + totalStreamedMips ;
if ( mipLevel ! = totalStreamedMips )
{
do
{
- - mipLevel ;
if ( textureHeader - > m_nArraySize )
{
int mipWidth = 0 ;
if ( textureHeader - > m_nWidth > > mipLevel > 1 )
mipWidth = ( textureHeader - > m_nWidth > > mipLevel ) - 1 ;
int mipHeight = 0 ;
if ( textureHeader - > m_nHeight > > mipLevel > 1 )
mipHeight = ( textureHeader - > m_nHeight > > mipLevel ) - 1 ;
uint8_t x = s_pBytesPerPixel [ textureHeader - > m_nImageFormat ] . first ;
uint8_t y = s_pBytesPerPixel [ textureHeader - > m_nImageFormat ] . second ;
uint32_t bppWidth = ( y + mipWidth ) > > ( y > > 1 ) ;
uint32_t bppHeight = ( y + mipHeight ) > > ( y > > 1 ) ;
uint32_t sliceWidth = x * ( y > > ( y > > 1 ) ) ;
uint32_t rowPitch = sliceWidth * bppWidth ;
uint32_t slicePitch = x * bppWidth * bppHeight ;
uint32_t subResourceEntry = mipLevel ;
for ( int i = 0 ; i < textureHeader - > m_nArraySize ; i + + )
{
uint32_t offsetCurrentResourceData = subResourceEntry < < 4u ;
* ( int64_t * ) ( ( uint8_t * ) initialData + offsetCurrentResourceData ) = imageData ;
* ( uint32_t * ) ( ( uint8_t * ) & initialData [ 1 ] + offsetCurrentResourceData ) = rowPitch ;
* ( uint32_t * ) ( ( uint8_t * ) & initialData [ 1 ] + offsetCurrentResourceData + 4 ) = slicePitch ;
imageData + = ( slicePitch + ALIGNMENT_SIZE ) & ~ ALIGNMENT_SIZE ;
subResourceEntry + = textureHeader - > m_nPermanentMipCount ;
}
}
} while ( mipLevel ! = totalStreamedMips ) ;
}
const DXGI_FORMAT dxgiFormat = g_TxtrAssetToDxgiFormat [ textureHeader - > m_nImageFormat ] ; // Get dxgi format
D3D11_TEXTURE2D_DESC textureDesc { } ;
textureDesc . Width = textureHeader - > m_nWidth > > mipLevel ;
textureDesc . Height = textureHeader - > m_nHeight > > mipLevel ;
textureDesc . MipLevels = textureHeader - > m_nPermanentMipCount ;
textureDesc . ArraySize = textureHeader - > m_nArraySize ;
textureDesc . Format = dxgiFormat ;
textureDesc . SampleDesc . Count = 1 ;
textureDesc . SampleDesc . Quality = 0 ;
textureDesc . Usage = textureHeader - > m_nCPUAccessFlag ! = 2 ? D3D11_USAGE_IMMUTABLE : D3D11_USAGE_DEFAULT ;
textureDesc . BindFlags = D3D11_BIND_SHADER_RESOURCE ;
textureDesc . MiscFlags = 0 ;
const uint32_t offsetStartResourceData = mipLevel < < 4u ;
const D3D11_SUBRESOURCE_DATA * subResData = ( D3D11_SUBRESOURCE_DATA * ) ( ( uint8_t * ) initialData + offsetStartResourceData ) ;
2023-09-11 01:28:17 +02:00
const HRESULT createTextureRes = D3D11Device ( ) - > CreateTexture2D ( & textureDesc , subResData , & textureHeader - > m_ppTexture ) ;
2023-05-13 18:03:48 +02:00
if ( createTextureRes < S_OK )
Error ( eDLL_T : : RTECH , EXIT_FAILURE , " Couldn't create texture \" %s \" : error code = %08x \n " , textureHeader - > m_pDebugName , createTextureRes ) ;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResource { } ;
shaderResource . Format = dxgiFormat ;
shaderResource . Texture2D . MipLevels = textureHeader - > m_nTextureMipLevels ;
if ( textureHeader - > m_nArraySize > 1 ) // Do we have a texture array?
{
shaderResource . Texture2DArray . FirstArraySlice = 0 ;
shaderResource . Texture2DArray . ArraySize = textureHeader - > m_nArraySize ;
shaderResource . ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY ;
}
else
{
shaderResource . ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D ;
}
2023-09-11 01:28:17 +02:00
const HRESULT createShaderResourceRes = D3D11Device ( ) - > CreateShaderResourceView ( textureHeader - > m_ppTexture , & shaderResource , & textureHeader - > m_ppShaderResourceView ) ;
2023-05-13 18:03:48 +02:00
if ( createShaderResourceRes < S_OK )
Error ( eDLL_T : : RTECH , EXIT_FAILURE , " Couldn't create shader resource view for texture \" %s \" : error code = %08x \n " , textureHeader - > m_pDebugName , createShaderResourceRes ) ;
}
# pragma warning( pop )
2021-12-25 22:36:38 +01:00
bool LoadTextureBuffer ( unsigned char * buffer , int len , ID3D11ShaderResourceView * * out_srv , int * out_width , int * out_height )
{
// Load PNG buffer to a raw RGBA buffer
2023-01-30 20:18:11 +01:00
int nImageWidth = 0 ;
int nImageHeight = 0 ;
unsigned char * pImageData = stbi_load_from_memory ( buffer , len , & nImageWidth , & nImageHeight , NULL , 4 ) ;
2021-12-25 22:36:38 +01:00
2023-01-30 20:18:11 +01:00
if ( ! pImageData )
2021-12-25 22:36:38 +01:00
{
2023-01-30 20:18:11 +01:00
assert ( pImageData ) ;
2021-12-25 22:36:38 +01:00
return false ;
}
///////////////////////////////////////////////////////////////////////////////
2023-01-30 20:18:11 +01:00
ID3D11Texture2D * pTexture = nullptr ;
2021-12-25 22:36:38 +01:00
D3D11_TEXTURE2D_DESC desc ;
2022-10-20 12:29:21 +02:00
D3D11_SUBRESOURCE_DATA subResource ;
2021-12-25 22:36:38 +01:00
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc ;
///////////////////////////////////////////////////////////////////////////////
ZeroMemory ( & desc , sizeof ( desc ) ) ;
2023-01-30 20:18:11 +01:00
desc . Width = nImageWidth ;
desc . Height = nImageHeight ;
desc . MipLevels = 1 ;
desc . ArraySize = 1 ;
desc . Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ;
desc . SampleDesc . Count = 1 ;
desc . Usage = D3D11_USAGE_DEFAULT ;
desc . BindFlags = D3D11_BIND_SHADER_RESOURCE ;
desc . CPUAccessFlags = 0 ;
2021-12-25 22:36:38 +01:00
///////////////////////////////////////////////////////////////////////////////
2023-01-30 20:18:11 +01:00
subResource . pSysMem = pImageData ;
subResource . SysMemPitch = desc . Width * 4 ;
subResource . SysMemSlicePitch = 0 ;
2023-09-11 01:28:17 +02:00
D3D11Device ( ) - > CreateTexture2D ( & desc , & subResource , & pTexture ) ;
2021-12-25 22:36:38 +01:00
// Create texture view
ZeroMemory ( & srvDesc , sizeof ( srvDesc ) ) ;
2023-01-30 20:18:11 +01:00
srvDesc . Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ;
srvDesc . ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D ;
srvDesc . Texture2D . MipLevels = desc . MipLevels ;
2021-12-25 22:36:38 +01:00
srvDesc . Texture2D . MostDetailedMip = 0 ;
if ( pTexture )
{
2023-09-11 01:28:17 +02:00
D3D11Device ( ) - > CreateShaderResourceView ( pTexture , & srvDesc , out_srv ) ;
2021-12-25 22:36:38 +01:00
pTexture - > Release ( ) ;
}
2023-01-30 20:18:11 +01:00
* out_width = nImageWidth ;
* out_height = nImageHeight ;
stbi_image_free ( pImageData ) ;
2021-12-25 22:36:38 +01:00
return true ;
}
2022-10-20 01:17:51 +02:00
void ResetInput ( )
{
g_pInputSystem - > EnableInput ( // Enables the input system when both are not drawn.
2024-01-21 21:29:23 +01:00
! g_Browser . m_bActivate & & ! g_Console . m_bActivate ) ;
2022-10-20 01:17:51 +02:00
}
2023-01-26 20:00:52 +01:00
bool PanelsVisible ( )
{
2024-01-21 21:29:23 +01:00
if ( g_Browser . m_bActivate | | g_Console . m_bActivate )
2023-01-26 20:00:52 +01:00
{
return true ;
}
return false ;
}
2021-12-25 22:36:38 +01:00
//#################################################################################
2023-01-30 20:18:11 +01:00
// ENTRYPOINT
2021-12-25 22:36:38 +01:00
//#################################################################################
2023-01-30 20:18:11 +01:00
void DirectX_Init ( )
2021-12-25 22:36:38 +01:00
{
///////////////////////////////////////////////////////////////////////////////
2022-10-20 12:29:21 +02:00
s_oPostMessageA = ( IPostMessageA ) DetourFindFunction ( " user32.dll " , " PostMessageA " ) ;
s_oPostMessageW = ( IPostMessageW ) DetourFindFunction ( " user32.dll " , " PostMessageW " ) ;
2021-12-25 22:36:38 +01:00
// Begin the detour transaction
DetourTransactionBegin ( ) ;
DetourUpdateThread ( GetCurrentThread ( ) ) ;
// Hook PostMessage
2022-10-20 12:29:21 +02:00
DetourAttach ( & ( LPVOID & ) s_oPostMessageA , ( PBYTE ) HPostMessageA ) ;
DetourAttach ( & ( LPVOID & ) s_oPostMessageW , ( PBYTE ) HPostMessageW ) ;
2021-12-25 22:36:38 +01:00
// Hook SwapChain
2023-01-30 20:18:11 +01:00
DWORD_PTR * pSwapChainVtable = * reinterpret_cast < DWORD_PTR * * > ( g_ppSwapChain [ 0 ] ) ;
int pIDX = static_cast < int > ( DXGISwapChainVTbl : : Present ) ;
s_fnSwapChainPresent = reinterpret_cast < IDXGISwapChainPresent > ( pSwapChainVtable [ pIDX ] ) ;
2023-01-30 22:08:01 +01:00
int rIDX = static_cast < int > ( DXGISwapChainVTbl : : ResizeBuffers ) ;
s_fnResizeBuffers = reinterpret_cast < IDXGIResizeBuffers > ( pSwapChainVtable [ rIDX ] ) ;
2022-10-20 12:29:21 +02:00
DetourAttach ( & ( LPVOID & ) s_fnSwapChainPresent , ( PBYTE ) Present ) ;
2023-01-30 22:08:01 +01:00
DetourAttach ( & ( LPVOID & ) s_fnResizeBuffers , ( PBYTE ) ResizeBuffers ) ;
2021-12-25 22:36:38 +01:00
// Commit the transaction
2022-09-14 01:14:51 +02:00
HRESULT hr = DetourTransactionCommit ( ) ;
if ( hr ! = NO_ERROR )
2021-12-25 22:36:38 +01:00
{
// Failed to hook into the process, terminate
2024-01-02 15:21:36 +01:00
Assert ( 0 ) ;
2022-09-14 00:39:38 +02:00
Error ( eDLL_T : : COMMON , 0xBAD0C0DE , " Failed to detour process: error code = %08x \n " , hr ) ;
2021-12-25 22:36:38 +01:00
}
}
void DirectX_Shutdown ( )
{
// Begin the detour transaction
DetourTransactionBegin ( ) ;
DetourUpdateThread ( GetCurrentThread ( ) ) ;
// Unhook PostMessage
2022-10-20 12:29:21 +02:00
DetourDetach ( & ( LPVOID & ) s_oPostMessageA , ( PBYTE ) HPostMessageA ) ;
DetourDetach ( & ( LPVOID & ) s_oPostMessageW , ( PBYTE ) HPostMessageW ) ;
2021-12-25 22:36:38 +01:00
// Unhook SwapChain
2022-10-20 12:29:21 +02:00
DetourDetach ( & ( LPVOID & ) s_fnSwapChainPresent , ( PBYTE ) Present ) ;
2023-01-30 22:08:01 +01:00
DetourDetach ( & ( LPVOID & ) s_fnResizeBuffers , ( PBYTE ) ResizeBuffers ) ;
2021-12-25 22:36:38 +01:00
// Commit the transaction
DetourTransactionCommit ( ) ;
///////////////////////////////////////////////////////////////////////////////
// Shutdown ImGui
2023-06-19 14:03:23 +02:00
if ( g_bImGuiInitialized )
2022-05-07 17:13:37 +02:00
{
2023-06-18 17:50:11 +02:00
ImGui_Shutdown ( ) ;
2023-06-19 14:03:23 +02:00
g_bImGuiInitialized = false ;
2022-05-07 17:13:37 +02:00
}
2021-12-25 22:36:38 +01:00
}
2022-07-21 16:56:25 +02:00
void VDXGI : : GetAdr ( void ) const
2021-12-25 22:36:38 +01:00
{
///////////////////////////////////////////////////////////////////////////////
2024-01-02 15:21:36 +01:00
LogFunAdr ( " IDXGISwapChain::Present " , s_fnSwapChainPresent ) ;
LogFunAdr ( " CreateTextureResource " , v_CreateTextureResource ) ;
LogVarAdr ( " g_pSwapChain " , g_ppSwapChain ) ;
LogVarAdr ( " g_pGameDevice " , g_ppGameDevice ) ;
LogVarAdr ( " g_pImmediateContext " , g_ppImmediateContext ) ;
2021-12-25 22:36:38 +01:00
}
2023-05-13 18:03:48 +02:00
void VDXGI : : GetFun ( void ) const
{
2024-01-02 15:21:36 +01:00
g_GameDll . FindPatternSIMD ( " E8 ?? ?? ?? ?? 4C 8B C7 48 8B D5 48 8B CB 48 83 C4 60 " ) . FollowNearCallSelf ( ) . GetPtr ( v_CreateTextureResource ) ;
2023-05-13 18:03:48 +02:00
}
2023-01-30 20:18:11 +01:00
void VDXGI : : GetVar ( void ) const
2021-12-25 22:36:38 +01:00
{
2024-01-02 15:21:36 +01:00
CMemory base = g_GameDll . FindPatternSIMD ( " 4C 8B DC 49 89 4B 08 48 83 EC 58 " ) ;
2023-01-30 20:18:11 +01:00
// Grab device pointers..
2024-01-02 15:21:36 +01:00
g_ppGameDevice = base . FindPattern ( " 48 8D 05 " ) . ResolveRelativeAddressSelf ( 0x3 , 0x7 ) . RCast < ID3D11Device * * > ( ) ;
g_ppImmediateContext = base . FindPattern ( " 48 89 0D " , CMemory : : Direction : : DOWN , 512 , 3 ) . ResolveRelativeAddressSelf ( 0x3 , 0x7 ) . RCast < ID3D11DeviceContext * * > ( ) ;
2023-01-30 20:18:11 +01:00
// Grab swap chain..
2024-01-02 15:21:36 +01:00
base = g_GameDll . FindPatternSIMD ( " 48 83 EC 28 48 8B 0D ?? ?? ?? ?? 45 33 C0 33 D2 " ) ;
g_ppSwapChain = base . FindPattern ( " 48 8B 0D " ) . ResolveRelativeAddressSelf ( 0x3 , 0x7 ) . RCast < IDXGISwapChain * * > ( ) ;
2021-12-25 22:36:38 +01:00
}
2023-11-26 13:21:20 +01:00
void VDXGI : : Detour ( const bool bAttach ) const
2023-05-13 18:03:48 +02:00
{
2023-11-26 13:21:20 +01:00
DetourSetup ( & v_CreateTextureResource , & CreateTextureResource , bAttach ) ;
2023-05-13 18:03:48 +02:00
}
2021-12-25 22:36:38 +01:00
# endif // !DEDICATED