From 24b9db9cf1954d33ba55f057e644c618654dfa58 Mon Sep 17 00:00:00 2001 From: X-rays5 <61073708+X-rays5@users.noreply.github.com> Date: Wed, 6 Sep 2023 20:34:57 +0200 Subject: [PATCH] Add D3D10.1 support and support for polyhook https://github.com/Rebzzel/kiero/pull/55 and https://github.com/Rebzzel/kiero/pull/45 --- kiero.cpp | 1410 ++++++++++++++++++++++++++++------------------------- kiero.h | 94 ++-- 2 files changed, 785 insertions(+), 719 deletions(-) diff --git a/kiero.cpp b/kiero.cpp index 73e87f0..a0a9cc3 100644 --- a/kiero.cpp +++ b/kiero.cpp @@ -1,719 +1,797 @@ #include "kiero.h" +#include +#include #include -#include -#if KIERO_INCLUDE_D3D9 -# include -#endif +#if KIERO_SUPPORT_D3D9 +#include -#if KIERO_INCLUDE_D3D10 -# include -# include -# include #endif -#if KIERO_INCLUDE_D3D11 -# include -# include -#endif +#if KIERO_SUPPORT_D3D10 || KIERO_SUPPORT_D3D10_1 +#include +#include +#include -#if KIERO_INCLUDE_D3D12 -# include -# include #endif -#if KIERO_INCLUDE_OPENGL -# include -#endif +#if KIERO_SUPPORT_D3D11 +#include -#if KIERO_INCLUDE_VULKAN -# include #endif -#if KIERO_USE_MINHOOK -# include "minhook/include/MinHook.h" -#endif +#if KIERO_SUPPORT_D3D12 +#include -#ifdef _UNICODE -# define KIERO_TEXT(text) L##text -#else -# define KIERO_TEXT(text) text #endif -#define KIERO_ARRAY_SIZE(arr) ((size_t)(sizeof(arr)/sizeof(arr[0]))) - -static kiero::RenderType::Enum g_renderType = kiero::RenderType::None; -static uint150_t* g_methodsTable = NULL; - -kiero::Status::Enum kiero::init(RenderType::Enum _renderType) -{ - if (g_renderType != RenderType::None) - { - return Status::AlreadyInitializedError; - } - - if (_renderType != RenderType::None) - { - if (_renderType >= RenderType::D3D9 && _renderType <= RenderType::D3D12) - { - WNDCLASSEX windowClass; - windowClass.cbSize = sizeof(WNDCLASSEX); - windowClass.style = CS_HREDRAW | CS_VREDRAW; - windowClass.lpfnWndProc = DefWindowProc; - windowClass.cbClsExtra = 0; - windowClass.cbWndExtra = 0; - windowClass.hInstance = GetModuleHandle(NULL); - windowClass.hIcon = NULL; - windowClass.hCursor = NULL; - windowClass.hbrBackground = NULL; - windowClass.lpszMenuName = NULL; - windowClass.lpszClassName = KIERO_TEXT("Kiero"); - windowClass.hIconSm = NULL; - - ::RegisterClassEx(&windowClass); - - HWND window = ::CreateWindow(windowClass.lpszClassName, KIERO_TEXT("Kiero DirectX Window"), WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, NULL, NULL, windowClass.hInstance, NULL); - - if (_renderType == RenderType::D3D9) - { -#if KIERO_INCLUDE_D3D9 - HMODULE libD3D9; - if ((libD3D9 = ::GetModuleHandle(KIERO_TEXT("d3d9.dll"))) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::ModuleNotFoundError; - } - - void* Direct3DCreate9; - if ((Direct3DCreate9 = ::GetProcAddress(libD3D9, "Direct3DCreate9")) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - LPDIRECT3D9 direct3D9; - if ((direct3D9 = ((LPDIRECT3D9(__stdcall*)(uint32_t))(Direct3DCreate9))(D3D_SDK_VERSION)) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - D3DPRESENT_PARAMETERS params; - params.BackBufferWidth = 0; - params.BackBufferHeight = 0; - params.BackBufferFormat = D3DFMT_UNKNOWN; - params.BackBufferCount = 0; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.MultiSampleQuality = NULL; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - params.hDeviceWindow = window; - params.Windowed = 1; - params.EnableAutoDepthStencil = 0; - params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - params.Flags = NULL; - params.FullScreen_RefreshRateInHz = 0; - params.PresentationInterval = 0; - - LPDIRECT3DDEVICE9 device; - if (direct3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT, ¶ms, &device) < 0) - { - direct3D9->Release(); - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - g_methodsTable = (uint150_t*)::calloc(119, sizeof(uint150_t)); - ::memcpy(g_methodsTable, *(uint150_t**)device, 119 * sizeof(uint150_t)); +#if KIERO_SUPPORT_OPENGL +#include -#if KIERO_USE_MINHOOK - MH_Initialize(); #endif - device->Release(); - device = NULL; - - direct3D9->Release(); - direct3D9 = NULL; - - g_renderType = RenderType::D3D9; +#if KIERO_SUPPORT_VULKAN +#include - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - - return Status::Success; #endif - } - else if (_renderType == RenderType::D3D10) - { -#if KIERO_INCLUDE_D3D10 - HMODULE libDXGI; - HMODULE libD3D10; - if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == NULL || (libD3D10 = ::GetModuleHandle(KIERO_TEXT("d3d10.dll"))) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::ModuleNotFoundError; - } - - void* CreateDXGIFactory; - if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - IDXGIFactory* factory; - if (((long(__stdcall*)(const IID&, void**))(CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**)&factory) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - IDXGIAdapter* adapter; - if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - void* D3D10CreateDeviceAndSwapChain; - if ((D3D10CreateDeviceAndSwapChain = ::GetProcAddress(libD3D10, "D3D10CreateDeviceAndSwapChain")) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - DXGI_RATIONAL refreshRate; - refreshRate.Numerator = 60; - refreshRate.Denominator = 1; - - DXGI_MODE_DESC bufferDesc; - bufferDesc.Width = 100; - bufferDesc.Height = 100; - bufferDesc.RefreshRate = refreshRate; - bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - - DXGI_SAMPLE_DESC sampleDesc; - sampleDesc.Count = 1; - sampleDesc.Quality = 0; - - DXGI_SWAP_CHAIN_DESC swapChainDesc; - swapChainDesc.BufferDesc = bufferDesc; - swapChainDesc.SampleDesc = sampleDesc; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = 1; - swapChainDesc.OutputWindow = window; - swapChainDesc.Windowed = 1; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - - IDXGISwapChain* swapChain; - ID3D10Device* device; - - if (((long(__stdcall*)( - IDXGIAdapter*, - D3D10_DRIVER_TYPE, - HMODULE, - UINT, - UINT, - DXGI_SWAP_CHAIN_DESC*, - IDXGISwapChain**, - ID3D10Device**))(D3D10CreateDeviceAndSwapChain))(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_SDK_VERSION, &swapChainDesc, &swapChain, &device) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - g_methodsTable = (uint150_t*)::calloc(116, sizeof(uint150_t)); - ::memcpy(g_methodsTable, *(uint150_t**)swapChain, 18 * sizeof(uint150_t)); - ::memcpy(g_methodsTable + 18, *(uint150_t**)device, 98 * sizeof(uint150_t)); #if KIERO_USE_MINHOOK - MH_Initialize(); -#endif - - swapChain->Release(); - swapChain = NULL; - - device->Release(); - device = NULL; - - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - - g_renderType = RenderType::D3D10; - - return Status::Success; -#endif - } - else if (_renderType == RenderType::D3D11) - { -#if KIERO_INCLUDE_D3D11 - HMODULE libD3D11; - if ((libD3D11 = ::GetModuleHandle(KIERO_TEXT("d3d11.dll"))) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::ModuleNotFoundError; - } - - void* D3D11CreateDeviceAndSwapChain; - if ((D3D11CreateDeviceAndSwapChain = ::GetProcAddress(libD3D11, "D3D11CreateDeviceAndSwapChain")) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - D3D_FEATURE_LEVEL featureLevel; - const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_11_0 }; - - DXGI_RATIONAL refreshRate; - refreshRate.Numerator = 60; - refreshRate.Denominator = 1; - - DXGI_MODE_DESC bufferDesc; - bufferDesc.Width = 100; - bufferDesc.Height = 100; - bufferDesc.RefreshRate = refreshRate; - bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - - DXGI_SAMPLE_DESC sampleDesc; - sampleDesc.Count = 1; - sampleDesc.Quality = 0; - - DXGI_SWAP_CHAIN_DESC swapChainDesc; - swapChainDesc.BufferDesc = bufferDesc; - swapChainDesc.SampleDesc = sampleDesc; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = 1; - swapChainDesc.OutputWindow = window; - swapChainDesc.Windowed = 1; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - - IDXGISwapChain* swapChain; - ID3D11Device* device; - ID3D11DeviceContext* context; - - if (((long(__stdcall*)( - IDXGIAdapter*, - D3D_DRIVER_TYPE, - HMODULE, - UINT, - const D3D_FEATURE_LEVEL*, - UINT, - UINT, - const DXGI_SWAP_CHAIN_DESC*, - IDXGISwapChain**, - ID3D11Device**, - D3D_FEATURE_LEVEL*, - ID3D11DeviceContext**))(D3D11CreateDeviceAndSwapChain))(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, 2, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, &featureLevel, &context) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - g_methodsTable = (uint150_t*)::calloc(205, sizeof(uint150_t)); - ::memcpy(g_methodsTable, *(uint150_t**)swapChain, 18 * sizeof(uint150_t)); - ::memcpy(g_methodsTable + 18, *(uint150_t**)device, 43 * sizeof(uint150_t)); - ::memcpy(g_methodsTable + 18 + 43, *(uint150_t**)context, 144 * sizeof(uint150_t)); +#include -#if KIERO_USE_MINHOOK - MH_Initialize(); #endif - swapChain->Release(); - swapChain = NULL; - - device->Release(); - device = NULL; - - context->Release(); - context = NULL; +#if KIERO_USE_POLYHOOK2 +#include - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); +#if KIERO_ARCH_X64 +#include - g_renderType = RenderType::D3D11; - - return Status::Success; #endif - } - else if (_renderType == RenderType::D3D12) - { -#if KIERO_INCLUDE_D3D12 - HMODULE libDXGI; - HMODULE libD3D12; - if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == NULL || (libD3D12 = ::GetModuleHandle(KIERO_TEXT("d3d12.dll"))) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::ModuleNotFoundError; - } - - void* CreateDXGIFactory; - if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - IDXGIFactory* factory; - if (((long(__stdcall*)(const IID&, void**))(CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**)&factory) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - IDXGIAdapter* adapter; - if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - void* D3D12CreateDevice; - if ((D3D12CreateDevice = ::GetProcAddress(libD3D12, "D3D12CreateDevice")) == NULL) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - ID3D12Device* device; - if (((long(__stdcall*)(IUnknown*, D3D_FEATURE_LEVEL, const IID&, void**))(D3D12CreateDevice))(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void**)&device) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - D3D12_COMMAND_QUEUE_DESC queueDesc; - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - queueDesc.Priority = 0; - queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - queueDesc.NodeMask = 0; - - ID3D12CommandQueue* commandQueue; - if (device->CreateCommandQueue(&queueDesc, __uuidof(ID3D12CommandQueue), (void**)&commandQueue) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - ID3D12CommandAllocator* commandAllocator; - if (device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&commandAllocator) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - ID3D12GraphicsCommandList* commandList; - if (device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator, NULL, __uuidof(ID3D12GraphicsCommandList), (void**)&commandList) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - DXGI_RATIONAL refreshRate; - refreshRate.Numerator = 60; - refreshRate.Denominator = 1; - - DXGI_MODE_DESC bufferDesc; - bufferDesc.Width = 100; - bufferDesc.Height = 100; - bufferDesc.RefreshRate = refreshRate; - bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - - DXGI_SAMPLE_DESC sampleDesc; - sampleDesc.Count = 1; - sampleDesc.Quality = 0; - - DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; - swapChainDesc.BufferDesc = bufferDesc; - swapChainDesc.SampleDesc = sampleDesc; - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.BufferCount = 2; - swapChainDesc.OutputWindow = window; - swapChainDesc.Windowed = 1; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - - IDXGISwapChain* swapChain; - if (factory->CreateSwapChain(commandQueue, &swapChainDesc, &swapChain) < 0) - { - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - return Status::UnknownError; - } - - g_methodsTable = (uint150_t*)::calloc(150, sizeof(uint150_t)); - ::memcpy(g_methodsTable, *(uint150_t**)device, 44 * sizeof(uint150_t)); - ::memcpy(g_methodsTable + 44, *(uint150_t**)commandQueue, 19 * sizeof(uint150_t)); - ::memcpy(g_methodsTable + 44 + 19, *(uint150_t**)commandAllocator, 9 * sizeof(uint150_t)); - ::memcpy(g_methodsTable + 44 + 19 + 9, *(uint150_t**)commandList, 60 * sizeof(uint150_t)); - ::memcpy(g_methodsTable + 44 + 19 + 9 + 60, *(uint150_t**)swapChain, 18 * sizeof(uint150_t)); - -#if KIERO_USE_MINHOOK - MH_Initialize(); +#if KIERO_ARCH_X86 +#include #endif - - device->Release(); - device = NULL; - - commandQueue->Release(); - commandQueue = NULL; - - commandAllocator->Release(); - commandAllocator = NULL; - - commandList->Release(); - commandList = NULL; - - swapChain->Release(); - swapChain = NULL; - - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - - g_renderType = RenderType::D3D12; - - return Status::Success; #endif - } - - ::DestroyWindow(window); - ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); - - return Status::NotSupportedError; - } - else if (_renderType != RenderType::Auto) - { - if (_renderType == RenderType::OpenGL) - { -#if KIERO_INCLUDE_OPENGL - HMODULE libOpenGL32; - if ((libOpenGL32 = ::GetModuleHandle(KIERO_TEXT("opengl32.dll"))) == NULL) - { - return Status::ModuleNotFoundError; - } - - const char* const methodsNames[] = { - "glAccum", "glAlphaFunc", "glAreTexturesResident", "glArrayElement", "glBegin", "glBindTexture", "glBitmap", "glBlendFunc", "glCallList", "glCallLists", "glClear", "glClearAccum", - "glClearColor", "glClearDepth", "glClearIndex", "glClearStencil", "glClipPlane", "glColor3b", "glColor3bv", "glColor3d", "glColor3dv", "glColor3f", "glColor3fv", "glColor3i", "glColor3iv", - "glColor3s", "glColor3sv", "glColor3ub", "glColor3ubv", "glColor3ui", "glColor3uiv", "glColor3us", "glColor3usv", "glColor4b", "glColor4bv", "glColor4d", "glColor4dv", "glColor4f", - "glColor4fv", "glColor4i", "glColor4iv", "glColor4s", "glColor4sv", "glColor4ub", "glColor4ubv", "glColor4ui", "glColor4uiv", "glColor4us", "glColor4usv", "glColorMask", "glColorMaterial", - "glColorPointer", "glCopyPixels", "glCopyTexImage1D", "glCopyTexImage2D", "glCopyTexSubImage1D", "glCopyTexSubImage2D", "glCullFaceglCullFace", "glDeleteLists", "glDeleteTextures", - "glDepthFunc", "glDepthMask", "glDepthRange", "glDisable", "glDisableClientState", "glDrawArrays", "glDrawBuffer", "glDrawElements", "glDrawPixels", "glEdgeFlag", "glEdgeFlagPointer", - "glEdgeFlagv", "glEnable", "glEnableClientState", "glEnd", "glEndList", "glEvalCoord1d", "glEvalCoord1dv", "glEvalCoord1f", "glEvalCoord1fv", "glEvalCoord2d", "glEvalCoord2dv", - "glEvalCoord2f", "glEvalCoord2fv", "glEvalMesh1", "glEvalMesh2", "glEvalPoint1", "glEvalPoint2", "glFeedbackBuffer", "glFinish", "glFlush", "glFogf", "glFogfv", "glFogi", "glFogiv", - "glFrontFace", "glFrustum", "glGenLists", "glGenTextures", "glGetBooleanv", "glGetClipPlane", "glGetDoublev", "glGetError", "glGetFloatv", "glGetIntegerv", "glGetLightfv", "glGetLightiv", - "glGetMapdv", "glGetMapfv", "glGetMapiv", "glGetMaterialfv", "glGetMaterialiv", "glGetPixelMapfv", "glGetPixelMapuiv", "glGetPixelMapusv", "glGetPointerv", "glGetPolygonStipple", - "glGetString", "glGetTexEnvfv", "glGetTexEnviv", "glGetTexGendv", "glGetTexGenfv", "glGetTexGeniv", "glGetTexImage", "glGetTexLevelParameterfv", "glGetTexLevelParameteriv", - "glGetTexParameterfv", "glGetTexParameteriv", "glHint", "glIndexMask", "glIndexPointer", "glIndexd", "glIndexdv", "glIndexf", "glIndexfv", "glIndexi", "glIndexiv", "glIndexs", "glIndexsv", - "glIndexub", "glIndexubv", "glInitNames", "glInterleavedArrays", "glIsEnabled", "glIsList", "glIsTexture", "glLightModelf", "glLightModelfv", "glLightModeli", "glLightModeliv", "glLightf", - "glLightfv", "glLighti", "glLightiv", "glLineStipple", "glLineWidth", "glListBase", "glLoadIdentity", "glLoadMatrixd", "glLoadMatrixf", "glLoadName", "glLogicOp", "glMap1d", "glMap1f", - "glMap2d", "glMap2f", "glMapGrid1d", "glMapGrid1f", "glMapGrid2d", "glMapGrid2f", "glMaterialf", "glMaterialfv", "glMateriali", "glMaterialiv", "glMatrixMode", "glMultMatrixd", - "glMultMatrixf", "glNewList", "glNormal3b", "glNormal3bv", "glNormal3d", "glNormal3dv", "glNormal3f", "glNormal3fv", "glNormal3i", "glNormal3iv", "glNormal3s", "glNormal3sv", - "glNormalPointer", "glOrtho", "glPassThrough", "glPixelMapfv", "glPixelMapuiv", "glPixelMapusv", "glPixelStoref", "glPixelStorei", "glPixelTransferf", "glPixelTransferi", "glPixelZoom", - "glPointSize", "glPolygonMode", "glPolygonOffset", "glPolygonStipple", "glPopAttrib", "glPopClientAttrib", "glPopMatrix", "glPopName", "glPrioritizeTextures", "glPushAttrib", - "glPushClientAttrib", "glPushMatrix", "glPushName", "glRasterPos2d", "glRasterPos2dv", "glRasterPos2f", "glRasterPos2fv", "glRasterPos2i", "glRasterPos2iv", "glRasterPos2s", - "glRasterPos2sv", "glRasterPos3d", "glRasterPos3dv", "glRasterPos3f", "glRasterPos3fv", "glRasterPos3i", "glRasterPos3iv", "glRasterPos3s", "glRasterPos3sv", "glRasterPos4d", - "glRasterPos4dv", "glRasterPos4f", "glRasterPos4fv", "glRasterPos4i", "glRasterPos4iv", "glRasterPos4s", "glRasterPos4sv", "glReadBuffer", "glReadPixels", "glRectd", "glRectdv", "glRectf", - "glRectfv", "glRecti", "glRectiv", "glRects", "glRectsv", "glRenderMode", "glRotated", "glRotatef", "glScaled", "glScalef", "glScissor", "glSelectBuffer", "glShadeModel", "glStencilFunc", - "glStencilMask", "glStencilOp", "glTexCoord1d", "glTexCoord1dv", "glTexCoord1f", "glTexCoord1fv", "glTexCoord1i", "glTexCoord1iv", "glTexCoord1s", "glTexCoord1sv", "glTexCoord2d", - "glTexCoord2dv", "glTexCoord2f", "glTexCoord2fv", "glTexCoord2i", "glTexCoord2iv", "glTexCoord2s", "glTexCoord2sv", "glTexCoord3d", "glTexCoord3dv", "glTexCoord3f", "glTexCoord3fv", - "glTexCoord3i", "glTexCoord3iv", "glTexCoord3s", "glTexCoord3sv", "glTexCoord4d", "glTexCoord4dv", "glTexCoord4f", "glTexCoord4fv", "glTexCoord4i", "glTexCoord4iv", "glTexCoord4s", - "glTexCoord4sv", "glTexCoordPointer", "glTexEnvf", "glTexEnvfv", "glTexEnvi", "glTexEnviv", "glTexGend", "glTexGendv", "glTexGenf", "glTexGenfv", "glTexGeni", "glTexGeniv", "glTexImage1D", - "glTexImage2D", "glTexParameterf", "glTexParameterfv", "glTexParameteri", "glTexParameteriv", "glTexSubImage1D", "glTexSubImage2D", "glTranslated", "glTranslatef", "glVertex2d", - "glVertex2dv", "glVertex2f", "glVertex2fv", "glVertex2i", "glVertex2iv", "glVertex2s", "glVertex2sv", "glVertex3d", "glVertex3dv", "glVertex3f", "glVertex3fv", "glVertex3i", "glVertex3iv", - "glVertex3s", "glVertex3sv", "glVertex4d", "glVertex4dv", "glVertex4f", "glVertex4fv", "glVertex4i", "glVertex4iv", "glVertex4s", "glVertex4sv", "glVertexPointer", "glViewport" - }; - - size_t size = KIERO_ARRAY_SIZE(methodsNames); - - g_methodsTable = (uint150_t*)::calloc(size, sizeof(uint150_t)); - - for (int i = 0; i < size; i++) - { - g_methodsTable[i] = (uint150_t)::GetProcAddress(libOpenGL32, methodsNames[i]); - } -#if KIERO_USE_MINHOOK - MH_Initialize(); +#ifdef _UNICODE +# define KIERO_TEXT(text) L##text +#else +# define KIERO_TEXT(text) text #endif - g_renderType = RenderType::OpenGL; +#define KIERO_ARRAY_SIZE(arr) ((size_t)(sizeof(arr)/sizeof(arr[0]))) - return Status::Success; +static kiero::RenderType::Enum g_renderType = kiero::RenderType::None; +static uint150_t* g_methodsTable = nullptr; +#if KIERO_USE_POLYHOOK2 +static std::unordered_map> g_detours; #endif - } - else if (_renderType == RenderType::Vulkan) - { -#if KIERO_INCLUDE_VULKAN - HMODULE libVulkan; - if ((libVulkan = GetModuleHandle(KIERO_TEXT("vulkan-1.dll"))) == NULL) - { - return Status::ModuleNotFoundError; - } - - const char* const methodsNames[] = { - "vkCreateInstance", "vkDestroyInstance", "vkEnumeratePhysicalDevices", "vkGetPhysicalDeviceFeatures", "vkGetPhysicalDeviceFormatProperties", "vkGetPhysicalDeviceImageFormatProperties", - "vkGetPhysicalDeviceProperties", "vkGetPhysicalDeviceQueueFamilyProperties", "vkGetPhysicalDeviceMemoryProperties", "vkGetInstanceProcAddr", "vkGetDeviceProcAddr", "vkCreateDevice", - "vkDestroyDevice", "vkEnumerateInstanceExtensionProperties", "vkEnumerateDeviceExtensionProperties", "vkEnumerateDeviceLayerProperties", "vkGetDeviceQueue", "vkQueueSubmit", "vkQueueWaitIdle", - "vkDeviceWaitIdle", "vkAllocateMemory", "vkFreeMemory", "vkMapMemory", "vkUnmapMemory", "vkFlushMappedMemoryRanges", "vkInvalidateMappedMemoryRanges", "vkGetDeviceMemoryCommitment", - "vkBindBufferMemory", "vkBindImageMemory", "vkGetBufferMemoryRequirements", "vkGetImageMemoryRequirements", "vkGetImageSparseMemoryRequirements", "vkGetPhysicalDeviceSparseImageFormatProperties", - "vkQueueBindSparse", "vkCreateFence", "vkDestroyFence", "vkResetFences", "vkGetFenceStatus", "vkWaitForFences", "vkCreateSemaphore", "vkDestroySemaphore", "vkCreateEvent", "vkDestroyEvent", - "vkGetEventStatus", "vkSetEvent", "vkResetEvent", "vkCreateQueryPool", "vkDestroyQueryPool", "vkGetQueryPoolResults", "vkCreateBuffer", "vkDestroyBuffer", "vkCreateBufferView", "vkDestroyBufferView", - "vkCreateImage", "vkDestroyImage", "vkGetImageSubresourceLayout", "vkCreateImageView", "vkDestroyImageView", "vkCreateShaderModule", "vkDestroyShaderModule", "vkCreatePipelineCache", - "vkDestroyPipelineCache", "vkGetPipelineCacheData", "vkMergePipelineCaches", "vkCreateGraphicsPipelines", "vkCreateComputePipelines", "vkDestroyPipeline", "vkCreatePipelineLayout", - "vkDestroyPipelineLayout", "vkCreateSampler", "vkDestroySampler", "vkCreateDescriptorSetLayout", "vkDestroyDescriptorSetLayout", "vkCreateDescriptorPool", "vkDestroyDescriptorPool", - "vkResetDescriptorPool", "vkAllocateDescriptorSets", "vkFreeDescriptorSets", "vkUpdateDescriptorSets", "vkCreateFramebuffer", "vkDestroyFramebuffer", "vkCreateRenderPass", "vkDestroyRenderPass", - "vkGetRenderAreaGranularity", "vkCreateCommandPool", "vkDestroyCommandPool", "vkResetCommandPool", "vkAllocateCommandBuffers", "vkFreeCommandBuffers", "vkBeginCommandBuffer", "vkEndCommandBuffer", - "vkResetCommandBuffer", "vkCmdBindPipeline", "vkCmdSetViewport", "vkCmdSetScissor", "vkCmdSetLineWidth", "vkCmdSetDepthBias", "vkCmdSetBlendConstants", "vkCmdSetDepthBounds", - "vkCmdSetStencilCompareMask", "vkCmdSetStencilWriteMask", "vkCmdSetStencilReference", "vkCmdBindDescriptorSets", "vkCmdBindIndexBuffer", "vkCmdBindVertexBuffers", "vkCmdDraw", "vkCmdDrawIndexed", - "vkCmdDrawIndirect", "vkCmdDrawIndexedIndirect", "vkCmdDispatch", "vkCmdDispatchIndirect", "vkCmdCopyBuffer", "vkCmdCopyImage", "vkCmdBlitImage", "vkCmdCopyBufferToImage", "vkCmdCopyImageToBuffer", - "vkCmdUpdateBuffer", "vkCmdFillBuffer", "vkCmdClearColorImage", "vkCmdClearDepthStencilImage", "vkCmdClearAttachments", "vkCmdResolveImage", "vkCmdSetEvent", "vkCmdResetEvent", "vkCmdWaitEvents", - "vkCmdPipelineBarrier", "vkCmdBeginQuery", "vkCmdEndQuery", "vkCmdResetQueryPool", "vkCmdWriteTimestamp", "vkCmdCopyQueryPoolResults", "vkCmdPushConstants", "vkCmdBeginRenderPass", "vkCmdNextSubpass", - "vkCmdEndRenderPass", "vkCmdExecuteCommands" - }; - - size_t size = KIERO_ARRAY_SIZE(methodsNames); - - g_methodsTable = (uint150_t*)::calloc(size, sizeof(uint150_t)); - - for (int i = 0; i < size; i++) - { - g_methodsTable[i] = (uint150_t)::GetProcAddress(libVulkan, methodsNames[i]); - } -#if KIERO_USE_MINHOOK - MH_Initialize(); -#endif +kiero::Status::Enum kiero::init(RenderType::Enum _renderType) { + if (g_renderType != RenderType::None) { + return Status::AlreadyInitializedError; + } + + if (_renderType != RenderType::None) { + if (_renderType >= RenderType::D3D9 && _renderType <= RenderType::D3D12) { + WNDCLASSEX windowClass; + windowClass.cbSize = sizeof(WNDCLASSEX); + windowClass.style = CS_HREDRAW | CS_VREDRAW; + windowClass.lpfnWndProc = DefWindowProc; + windowClass.cbClsExtra = 0; + windowClass.cbWndExtra = 0; + windowClass.hInstance = GetModuleHandle(nullptr); + windowClass.hIcon = nullptr; + windowClass.hCursor = nullptr; + windowClass.hbrBackground = nullptr; + windowClass.lpszMenuName = nullptr; + windowClass.lpszClassName = KIERO_TEXT("Kiero"); + windowClass.hIconSm = nullptr; + + ::RegisterClassEx(&windowClass); + + HWND window = ::CreateWindow(windowClass.lpszClassName, KIERO_TEXT("Kiero DirectX Window"), WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, nullptr, nullptr, windowClass.hInstance, nullptr); + + if (_renderType == RenderType::D3D9) { + #if KIERO_SUPPORT_D3D9 + HMODULE libD3D9; + if ((libD3D9 = ::GetModuleHandle(KIERO_TEXT("d3d9.dll"))) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::ModuleNotFoundError; + } + + void* Direct3DCreate9; + if ((Direct3DCreate9 = ::GetProcAddress(libD3D9, "Direct3DCreate9")) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + LPDIRECT3D9 direct3D9; + if ((direct3D9 = ((LPDIRECT3D9(__stdcall*)(uint32_t)) (Direct3DCreate9))(D3D_SDK_VERSION)) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + D3DPRESENT_PARAMETERS params; + params.BackBufferWidth = 0; + params.BackBufferHeight = 0; + params.BackBufferFormat = D3DFMT_UNKNOWN; + params.BackBufferCount = 0; + params.MultiSampleType = D3DMULTISAMPLE_NONE; + params.MultiSampleQuality = NULL; + params.SwapEffect = D3DSWAPEFFECT_DISCARD; + params.hDeviceWindow = window; + params.Windowed = 1; + params.EnableAutoDepthStencil = 0; + params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + params.Flags = NULL; + params.FullScreen_RefreshRateInHz = 0; + params.PresentationInterval = 0; + + LPDIRECT3DDEVICE9 device; + if (direct3D9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT, ¶ms, &device) < 0) { + direct3D9->Release(); + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + g_methodsTable = (uint150_t*) ::calloc(119, sizeof(uint150_t)); + ::memcpy(g_methodsTable, *(uint150_t**) device, 119 * sizeof(uint150_t)); + + #if KIERO_USE_MINHOOK + MH_Initialize(); + #endif + + device->Release(); + device = nullptr; + + direct3D9->Release(); + direct3D9 = nullptr; + + g_renderType = RenderType::D3D9; + + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + + return Status::Success; + #endif + } else if (_renderType == RenderType::D3D10) { + #if KIERO_SUPPORT_D3D10 + HMODULE libDXGI; + HMODULE libD3D10; + if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == nullptr || (libD3D10 = ::GetModuleHandle(KIERO_TEXT("d3d10.dll"))) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::ModuleNotFoundError; + } + + void* CreateDXGIFactory; + if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + IDXGIFactory* factory; + if (((long (__stdcall*)(const IID&, void**)) (CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**) &factory) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + IDXGIAdapter* adapter; + if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + void* D3D10CreateDeviceAndSwapChain; + if ((D3D10CreateDeviceAndSwapChain = ::GetProcAddress(libD3D10, "D3D10CreateDeviceAndSwapChain")) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + DXGI_RATIONAL refreshRate; + refreshRate.Numerator = 60; + refreshRate.Denominator = 1; + + DXGI_MODE_DESC bufferDesc; + bufferDesc.Width = 100; + bufferDesc.Height = 100; + bufferDesc.RefreshRate = refreshRate; + bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + + DXGI_SAMPLE_DESC sampleDesc; + sampleDesc.Count = 1; + sampleDesc.Quality = 0; + + DXGI_SWAP_CHAIN_DESC swapChainDesc; + swapChainDesc.BufferDesc = bufferDesc; + swapChainDesc.SampleDesc = sampleDesc; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 1; + swapChainDesc.OutputWindow = window; + swapChainDesc.Windowed = 1; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + IDXGISwapChain* swapChain; + ID3D10Device* device; + + if (((long (__stdcall*)( + IDXGIAdapter*, + D3D10_DRIVER_TYPE, + HMODULE, + UINT, + UINT, + DXGI_SWAP_CHAIN_DESC*, + IDXGISwapChain**, + ID3D10Device**)) (D3D10CreateDeviceAndSwapChain))(adapter, D3D10_DRIVER_TYPE_HARDWARE, nullptr, 0, D3D10_SDK_VERSION, &swapChainDesc, &swapChain, &device) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + g_methodsTable = (uint150_t*) ::calloc(116, sizeof(uint150_t)); + ::memcpy(g_methodsTable, *(uint150_t**) swapChain, 18 * sizeof(uint150_t)); + ::memcpy(g_methodsTable + 18, *(uint150_t**) device, 98 * sizeof(uint150_t)); + + #if KIERO_USE_MINHOOK + MH_Initialize(); + #endif + + swapChain->Release(); + swapChain = nullptr; + + device->Release(); + device = nullptr; + + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + + g_renderType = RenderType::D3D10; + + return Status::Success; + #endif + } else if (_renderType == RenderType::D3D10_1) { + #if KIERO_SUPPORT_D3D10_1 + HMODULE libDXGI; + HMODULE libD3D10; + if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == nullptr || (libD3D10 = ::GetModuleHandle(KIERO_TEXT("d3d10_1.dll"))) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::ModuleNotFoundError; + } + + void* CreateDXGIFactory; + if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + IDXGIFactory* factory; + if (((long (__stdcall*)(const IID&, void**)) (CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**) &factory) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + IDXGIAdapter* adapter; + if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + void* D3D10CreateDeviceAndSwapChain; + if ((D3D10CreateDeviceAndSwapChain = ::GetProcAddress(libD3D10, "D3D10CreateDeviceAndSwapChain1")) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + DXGI_RATIONAL refreshRate; + refreshRate.Numerator = 60; + refreshRate.Denominator = 1; + + DXGI_MODE_DESC bufferDesc; + bufferDesc.Width = 100; + bufferDesc.Height = 100; + bufferDesc.RefreshRate = refreshRate; + bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + + DXGI_SAMPLE_DESC sampleDesc; + sampleDesc.Count = 1; + sampleDesc.Quality = 0; + + DXGI_SWAP_CHAIN_DESC swapChainDesc; + swapChainDesc.BufferDesc = bufferDesc; + swapChainDesc.SampleDesc = sampleDesc; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 1; + swapChainDesc.OutputWindow = window; + swapChainDesc.Windowed = 1; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + IDXGISwapChain* swapChain; + ID3D10Device1* device; + + auto d3D101CreateDeviceAndSwapChain = reinterpret_cast(D3D10CreateDeviceAndSwapChain); + if (d3D101CreateDeviceAndSwapChain(adapter, D3D10_DRIVER_TYPE_HARDWARE, nullptr, 0, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, &swapChainDesc, &swapChain, &device) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + g_methodsTable = (uint150_t*) ::calloc(116, sizeof(uint150_t)); + ::memcpy(g_methodsTable, *(uint150_t**) swapChain, 18 * sizeof(uint150_t)); + ::memcpy(g_methodsTable + 18, *(uint150_t**) device, 98 * sizeof(uint150_t)); + + #if KIERO_USE_MINHOOK + MH_Initialize(); + #endif + + swapChain->Release(); + swapChain = nullptr; + + device->Release(); + device = nullptr; + + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + + g_renderType = RenderType::D3D10; + + return Status::Success; + #endif + } else if (_renderType == RenderType::D3D11) { + #if KIERO_SUPPORT_D3D11 + HMODULE libD3D11; + if ((libD3D11 = ::GetModuleHandle(KIERO_TEXT("d3d11.dll"))) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::ModuleNotFoundError; + } + + void* D3D11CreateDeviceAndSwapChain; + if ((D3D11CreateDeviceAndSwapChain = ::GetProcAddress(libD3D11, "D3D11CreateDeviceAndSwapChain")) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + D3D_FEATURE_LEVEL featureLevel; + const D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_11_0}; + + DXGI_RATIONAL refreshRate; + refreshRate.Numerator = 60; + refreshRate.Denominator = 1; + + DXGI_MODE_DESC bufferDesc; + bufferDesc.Width = 100; + bufferDesc.Height = 100; + bufferDesc.RefreshRate = refreshRate; + bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + + DXGI_SAMPLE_DESC sampleDesc; + sampleDesc.Count = 1; + sampleDesc.Quality = 0; + + DXGI_SWAP_CHAIN_DESC swapChainDesc; + swapChainDesc.BufferDesc = bufferDesc; + swapChainDesc.SampleDesc = sampleDesc; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 1; + swapChainDesc.OutputWindow = window; + swapChainDesc.Windowed = 1; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + IDXGISwapChain* swapChain; + ID3D11Device* device; + ID3D11DeviceContext* context; + + if (((long (__stdcall*)( + IDXGIAdapter*, + D3D_DRIVER_TYPE, + HMODULE, + UINT, + const D3D_FEATURE_LEVEL*, + UINT, + UINT, + const DXGI_SWAP_CHAIN_DESC*, + IDXGISwapChain**, + ID3D11Device**, + D3D_FEATURE_LEVEL*, + ID3D11DeviceContext**)) (D3D11CreateDeviceAndSwapChain))(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, featureLevels, 2, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, &featureLevel, &context) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + g_methodsTable = (uint150_t*) ::calloc(205, sizeof(uint150_t)); + ::memcpy(g_methodsTable, *(uint150_t**) swapChain, 18 * sizeof(uint150_t)); + ::memcpy(g_methodsTable + 18, *(uint150_t**) device, 43 * sizeof(uint150_t)); + ::memcpy(g_methodsTable + 18 + 43, *(uint150_t**) context, 144 * sizeof(uint150_t)); + + #if KIERO_USE_MINHOOK + MH_Initialize(); + #endif + + swapChain->Release(); + swapChain = nullptr; + + device->Release(); + device = nullptr; + + context->Release(); + context = nullptr; + + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + + g_renderType = RenderType::D3D11; + + return Status::Success; + #endif + } else if (_renderType == RenderType::D3D12) { + #if KIERO_SUPPORT_D3D12 + HMODULE libDXGI; + HMODULE libD3D12; + if ((libDXGI = ::GetModuleHandle(KIERO_TEXT("dxgi.dll"))) == nullptr || (libD3D12 = ::GetModuleHandle(KIERO_TEXT("d3d12.dll"))) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::ModuleNotFoundError; + } + + void* CreateDXGIFactory; + if ((CreateDXGIFactory = ::GetProcAddress(libDXGI, "CreateDXGIFactory")) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + IDXGIFactory* factory; + if (((long (__stdcall*)(const IID&, void**)) (CreateDXGIFactory))(__uuidof(IDXGIFactory), (void**) &factory) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + IDXGIAdapter* adapter; + if (factory->EnumAdapters(0, &adapter) == DXGI_ERROR_NOT_FOUND) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + void* D3D12CreateDevice; + if ((D3D12CreateDevice = ::GetProcAddress(libD3D12, "D3D12CreateDevice")) == nullptr) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + ID3D12Device* device; + if (((long (__stdcall*)(IUnknown*, D3D_FEATURE_LEVEL, const IID&, void**)) (D3D12CreateDevice))(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void**) &device) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + D3D12_COMMAND_QUEUE_DESC queueDesc; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.Priority = 0; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.NodeMask = 0; + + ID3D12CommandQueue* commandQueue; + if (device->CreateCommandQueue(&queueDesc, __uuidof(ID3D12CommandQueue), (void**) &commandQueue) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + ID3D12CommandAllocator* commandAllocator; + if (device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**) &commandAllocator) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + ID3D12GraphicsCommandList* commandList; + if (device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, commandAllocator, nullptr, __uuidof(ID3D12GraphicsCommandList), (void**) &commandList) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + DXGI_RATIONAL refreshRate; + refreshRate.Numerator = 60; + refreshRate.Denominator = 1; + + DXGI_MODE_DESC bufferDesc; + bufferDesc.Width = 100; + bufferDesc.Height = 100; + bufferDesc.RefreshRate = refreshRate; + bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + + DXGI_SAMPLE_DESC sampleDesc; + sampleDesc.Count = 1; + sampleDesc.Quality = 0; + + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferDesc = bufferDesc; + swapChainDesc.SampleDesc = sampleDesc; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 2; + swapChainDesc.OutputWindow = window; + swapChainDesc.Windowed = 1; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + + IDXGISwapChain* swapChain; + if (factory->CreateSwapChain(commandQueue, &swapChainDesc, &swapChain) < 0) { + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + return Status::UnknownError; + } + + g_methodsTable = (uint150_t*) ::calloc(150, sizeof(uint150_t)); + ::memcpy(g_methodsTable, *(uint150_t**) device, 44 * sizeof(uint150_t)); + ::memcpy(g_methodsTable + 44, *(uint150_t**) commandQueue, 19 * sizeof(uint150_t)); + ::memcpy(g_methodsTable + 44 + 19, *(uint150_t**) commandAllocator, 9 * sizeof(uint150_t)); + ::memcpy(g_methodsTable + 44 + 19 + 9, *(uint150_t**) commandList, 60 * sizeof(uint150_t)); + ::memcpy(g_methodsTable + 44 + 19 + 9 + 60, *(uint150_t**) swapChain, 18 * sizeof(uint150_t)); + + #if KIERO_USE_MINHOOK + MH_Initialize(); + #endif + + device->Release(); + device = nullptr; + + commandQueue->Release(); + commandQueue = nullptr; + + commandAllocator->Release(); + commandAllocator = nullptr; + + commandList->Release(); + commandList = nullptr; + + swapChain->Release(); + swapChain = nullptr; + + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + + g_renderType = RenderType::D3D12; + + return Status::Success; + #endif + } + + ::DestroyWindow(window); + ::UnregisterClass(windowClass.lpszClassName, windowClass.hInstance); + + return Status::NotSupportedError; + } else if (_renderType != RenderType::Auto) { + if (_renderType == RenderType::OpenGL) { + #if KIERO_SUPPORT_OPENGL + HMODULE libOpenGL32; + if ((libOpenGL32 = ::GetModuleHandle(KIERO_TEXT("opengl32.dll"))) == NULL) + { + return Status::ModuleNotFoundError; + } + + const char* const methodsNames[] = { + "glAccum", "glAlphaFunc", "glAreTexturesResident", "glArrayElement", "glBegin", "glBindTexture", "glBitmap", "glBlendFunc", "glCallList", "glCallLists", "glClear", "glClearAccum", + "glClearColor", "glClearDepth", "glClearIndex", "glClearStencil", "glClipPlane", "glColor3b", "glColor3bv", "glColor3d", "glColor3dv", "glColor3f", "glColor3fv", "glColor3i", "glColor3iv", + "glColor3s", "glColor3sv", "glColor3ub", "glColor3ubv", "glColor3ui", "glColor3uiv", "glColor3us", "glColor3usv", "glColor4b", "glColor4bv", "glColor4d", "glColor4dv", "glColor4f", + "glColor4fv", "glColor4i", "glColor4iv", "glColor4s", "glColor4sv", "glColor4ub", "glColor4ubv", "glColor4ui", "glColor4uiv", "glColor4us", "glColor4usv", "glColorMask", "glColorMaterial", + "glColorPointer", "glCopyPixels", "glCopyTexImage1D", "glCopyTexImage2D", "glCopyTexSubImage1D", "glCopyTexSubImage2D", "glCullFaceglCullFace", "glDeleteLists", "glDeleteTextures", + "glDepthFunc", "glDepthMask", "glDepthRange", "glDisable", "glDisableClientState", "glDrawArrays", "glDrawBuffer", "glDrawElements", "glDrawPixels", "glEdgeFlag", "glEdgeFlagPointer", + "glEdgeFlagv", "glEnable", "glEnableClientState", "glEnd", "glEndList", "glEvalCoord1d", "glEvalCoord1dv", "glEvalCoord1f", "glEvalCoord1fv", "glEvalCoord2d", "glEvalCoord2dv", + "glEvalCoord2f", "glEvalCoord2fv", "glEvalMesh1", "glEvalMesh2", "glEvalPoint1", "glEvalPoint2", "glFeedbackBuffer", "glFinish", "glFlush", "glFogf", "glFogfv", "glFogi", "glFogiv", + "glFrontFace", "glFrustum", "glGenLists", "glGenTextures", "glGetBooleanv", "glGetClipPlane", "glGetDoublev", "glGetError", "glGetFloatv", "glGetIntegerv", "glGetLightfv", "glGetLightiv", + "glGetMapdv", "glGetMapfv", "glGetMapiv", "glGetMaterialfv", "glGetMaterialiv", "glGetPixelMapfv", "glGetPixelMapuiv", "glGetPixelMapusv", "glGetPointerv", "glGetPolygonStipple", + "glGetString", "glGetTexEnvfv", "glGetTexEnviv", "glGetTexGendv", "glGetTexGenfv", "glGetTexGeniv", "glGetTexImage", "glGetTexLevelParameterfv", "glGetTexLevelParameteriv", + "glGetTexParameterfv", "glGetTexParameteriv", "glHint", "glIndexMask", "glIndexPointer", "glIndexd", "glIndexdv", "glIndexf", "glIndexfv", "glIndexi", "glIndexiv", "glIndexs", "glIndexsv", + "glIndexub", "glIndexubv", "glInitNames", "glInterleavedArrays", "glIsEnabled", "glIsList", "glIsTexture", "glLightModelf", "glLightModelfv", "glLightModeli", "glLightModeliv", "glLightf", + "glLightfv", "glLighti", "glLightiv", "glLineStipple", "glLineWidth", "glListBase", "glLoadIdentity", "glLoadMatrixd", "glLoadMatrixf", "glLoadName", "glLogicOp", "glMap1d", "glMap1f", + "glMap2d", "glMap2f", "glMapGrid1d", "glMapGrid1f", "glMapGrid2d", "glMapGrid2f", "glMaterialf", "glMaterialfv", "glMateriali", "glMaterialiv", "glMatrixMode", "glMultMatrixd", + "glMultMatrixf", "glNewList", "glNormal3b", "glNormal3bv", "glNormal3d", "glNormal3dv", "glNormal3f", "glNormal3fv", "glNormal3i", "glNormal3iv", "glNormal3s", "glNormal3sv", + "glNormalPointer", "glOrtho", "glPassThrough", "glPixelMapfv", "glPixelMapuiv", "glPixelMapusv", "glPixelStoref", "glPixelStorei", "glPixelTransferf", "glPixelTransferi", "glPixelZoom", + "glPointSize", "glPolygonMode", "glPolygonOffset", "glPolygonStipple", "glPopAttrib", "glPopClientAttrib", "glPopMatrix", "glPopName", "glPrioritizeTextures", "glPushAttrib", + "glPushClientAttrib", "glPushMatrix", "glPushName", "glRasterPos2d", "glRasterPos2dv", "glRasterPos2f", "glRasterPos2fv", "glRasterPos2i", "glRasterPos2iv", "glRasterPos2s", + "glRasterPos2sv", "glRasterPos3d", "glRasterPos3dv", "glRasterPos3f", "glRasterPos3fv", "glRasterPos3i", "glRasterPos3iv", "glRasterPos3s", "glRasterPos3sv", "glRasterPos4d", + "glRasterPos4dv", "glRasterPos4f", "glRasterPos4fv", "glRasterPos4i", "glRasterPos4iv", "glRasterPos4s", "glRasterPos4sv", "glReadBuffer", "glReadPixels", "glRectd", "glRectdv", "glRectf", + "glRectfv", "glRecti", "glRectiv", "glRects", "glRectsv", "glRenderMode", "glRotated", "glRotatef", "glScaled", "glScalef", "glScissor", "glSelectBuffer", "glShadeModel", "glStencilFunc", + "glStencilMask", "glStencilOp", "glTexCoord1d", "glTexCoord1dv", "glTexCoord1f", "glTexCoord1fv", "glTexCoord1i", "glTexCoord1iv", "glTexCoord1s", "glTexCoord1sv", "glTexCoord2d", + "glTexCoord2dv", "glTexCoord2f", "glTexCoord2fv", "glTexCoord2i", "glTexCoord2iv", "glTexCoord2s", "glTexCoord2sv", "glTexCoord3d", "glTexCoord3dv", "glTexCoord3f", "glTexCoord3fv", + "glTexCoord3i", "glTexCoord3iv", "glTexCoord3s", "glTexCoord3sv", "glTexCoord4d", "glTexCoord4dv", "glTexCoord4f", "glTexCoord4fv", "glTexCoord4i", "glTexCoord4iv", "glTexCoord4s", + "glTexCoord4sv", "glTexCoordPointer", "glTexEnvf", "glTexEnvfv", "glTexEnvi", "glTexEnviv", "glTexGend", "glTexGendv", "glTexGenf", "glTexGenfv", "glTexGeni", "glTexGeniv", "glTexImage1D", + "glTexImage2D", "glTexParameterf", "glTexParameterfv", "glTexParameteri", "glTexParameteriv", "glTexSubImage1D", "glTexSubImage2D", "glTranslated", "glTranslatef", "glVertex2d", + "glVertex2dv", "glVertex2f", "glVertex2fv", "glVertex2i", "glVertex2iv", "glVertex2s", "glVertex2sv", "glVertex3d", "glVertex3dv", "glVertex3f", "glVertex3fv", "glVertex3i", "glVertex3iv", + "glVertex3s", "glVertex3sv", "glVertex4d", "glVertex4dv", "glVertex4f", "glVertex4fv", "glVertex4i", "glVertex4iv", "glVertex4s", "glVertex4sv", "glVertexPointer", "glViewport" + }; + + size_t size = KIERO_ARRAY_SIZE(methodsNames); + + g_methodsTable = (uint150_t*)::calloc(size, sizeof(uint150_t)); + + for (int i = 0; i < size; i++) + { + g_methodsTable[i] = (uint150_t)::GetProcAddress(libOpenGL32, methodsNames[i]); + } + + #if KIERO_USE_MINHOOK + MH_Initialize(); + #endif + + g_renderType = RenderType::OpenGL; + + return Status::Success; + #endif + } else if (_renderType == RenderType::Vulkan) { + #if KIERO_SUPPORT_VULKAN + HMODULE libVulkan; + if ((libVulkan = GetModuleHandle(KIERO_TEXT("vulkan-1.dll"))) == NULL) + { + return Status::ModuleNotFoundError; + } + + const char* const methodsNames[] = { + "vkCreateInstance", "vkDestroyInstance", "vkEnumeratePhysicalDevices", "vkGetPhysicalDeviceFeatures", "vkGetPhysicalDeviceFormatProperties", "vkGetPhysicalDeviceImageFormatProperties", + "vkGetPhysicalDeviceProperties", "vkGetPhysicalDeviceQueueFamilyProperties", "vkGetPhysicalDeviceMemoryProperties", "vkGetInstanceProcAddr", "vkGetDeviceProcAddr", "vkCreateDevice", + "vkDestroyDevice", "vkEnumerateInstanceExtensionProperties", "vkEnumerateDeviceExtensionProperties", "vkEnumerateDeviceLayerProperties", "vkGetDeviceQueue", "vkQueueSubmit", "vkQueueWaitIdle", + "vkDeviceWaitIdle", "vkAllocateMemory", "vkFreeMemory", "vkMapMemory", "vkUnmapMemory", "vkFlushMappedMemoryRanges", "vkInvalidateMappedMemoryRanges", "vkGetDeviceMemoryCommitment", + "vkBindBufferMemory", "vkBindImageMemory", "vkGetBufferMemoryRequirements", "vkGetImageMemoryRequirements", "vkGetImageSparseMemoryRequirements", "vkGetPhysicalDeviceSparseImageFormatProperties", + "vkQueueBindSparse", "vkCreateFence", "vkDestroyFence", "vkResetFences", "vkGetFenceStatus", "vkWaitForFences", "vkCreateSemaphore", "vkDestroySemaphore", "vkCreateEvent", "vkDestroyEvent", + "vkGetEventStatus", "vkSetEvent", "vkResetEvent", "vkCreateQueryPool", "vkDestroyQueryPool", "vkGetQueryPoolResults", "vkCreateBuffer", "vkDestroyBuffer", "vkCreateBufferView", "vkDestroyBufferView", + "vkCreateImage", "vkDestroyImage", "vkGetImageSubresourceLayout", "vkCreateImageView", "vkDestroyImageView", "vkCreateShaderModule", "vkDestroyShaderModule", "vkCreatePipelineCache", + "vkDestroyPipelineCache", "vkGetPipelineCacheData", "vkMergePipelineCaches", "vkCreateGraphicsPipelines", "vkCreateComputePipelines", "vkDestroyPipeline", "vkCreatePipelineLayout", + "vkDestroyPipelineLayout", "vkCreateSampler", "vkDestroySampler", "vkCreateDescriptorSetLayout", "vkDestroyDescriptorSetLayout", "vkCreateDescriptorPool", "vkDestroyDescriptorPool", + "vkResetDescriptorPool", "vkAllocateDescriptorSets", "vkFreeDescriptorSets", "vkUpdateDescriptorSets", "vkCreateFramebuffer", "vkDestroyFramebuffer", "vkCreateRenderPass", "vkDestroyRenderPass", + "vkGetRenderAreaGranularity", "vkCreateCommandPool", "vkDestroyCommandPool", "vkResetCommandPool", "vkAllocateCommandBuffers", "vkFreeCommandBuffers", "vkBeginCommandBuffer", "vkEndCommandBuffer", + "vkResetCommandBuffer", "vkCmdBindPipeline", "vkCmdSetViewport", "vkCmdSetScissor", "vkCmdSetLineWidth", "vkCmdSetDepthBias", "vkCmdSetBlendConstants", "vkCmdSetDepthBounds", + "vkCmdSetStencilCompareMask", "vkCmdSetStencilWriteMask", "vkCmdSetStencilReference", "vkCmdBindDescriptorSets", "vkCmdBindIndexBuffer", "vkCmdBindVertexBuffers", "vkCmdDraw", "vkCmdDrawIndexed", + "vkCmdDrawIndirect", "vkCmdDrawIndexedIndirect", "vkCmdDispatch", "vkCmdDispatchIndirect", "vkCmdCopyBuffer", "vkCmdCopyImage", "vkCmdBlitImage", "vkCmdCopyBufferToImage", "vkCmdCopyImageToBuffer", + "vkCmdUpdateBuffer", "vkCmdFillBuffer", "vkCmdClearColorImage", "vkCmdClearDepthStencilImage", "vkCmdClearAttachments", "vkCmdResolveImage", "vkCmdSetEvent", "vkCmdResetEvent", "vkCmdWaitEvents", + "vkCmdPipelineBarrier", "vkCmdBeginQuery", "vkCmdEndQuery", "vkCmdResetQueryPool", "vkCmdWriteTimestamp", "vkCmdCopyQueryPoolResults", "vkCmdPushConstants", "vkCmdBeginRenderPass", "vkCmdNextSubpass", + "vkCmdEndRenderPass", "vkCmdExecuteCommands" + }; + + size_t size = KIERO_ARRAY_SIZE(methodsNames); + + g_methodsTable = (uint150_t*)::calloc(size, sizeof(uint150_t)); + + for (int i = 0; i < size; i++) + { + g_methodsTable[i] = (uint150_t)::GetProcAddress(libVulkan, methodsNames[i]); + } + + #if KIERO_USE_MINHOOK + MH_Initialize(); + #endif + + g_renderType = RenderType::Vulkan; + + return Status::Success; + #endif + } + + return Status::NotSupportedError; + } else { + RenderType::Enum type = RenderType::None; + + if (::GetModuleHandle(KIERO_TEXT("d3d9.dll")) != nullptr) { + type = RenderType::D3D9; + } else if (::GetModuleHandle(KIERO_TEXT("d3d10.dll")) != nullptr) { + type = RenderType::D3D10; + } else if (::GetModuleHandle(KIERO_TEXT("d3d10_1.dll")) != nullptr) { + type = RenderType::D3D10_1; + } else if (::GetModuleHandle(KIERO_TEXT("d3d11.dll")) != nullptr) { + type = RenderType::D3D11; + } else if (::GetModuleHandle(KIERO_TEXT("d3d12.dll")) != nullptr) { + type = RenderType::D3D12; + } else if (::GetModuleHandle(KIERO_TEXT("opengl32.dll")) != nullptr) { + type = RenderType::OpenGL; + } else if (::GetModuleHandle(KIERO_TEXT("vulkan-1.dll")) != nullptr) { + type = RenderType::Vulkan; + } else { + return Status::NotSupportedError; + } + + return init(type); + } + } + + return Status::Success; +} - g_renderType = RenderType::Vulkan; +void kiero::shutdown() { + if (g_renderType != RenderType::None) { + #if KIERO_USE_MINHOOK + MH_DisableHook(MH_ALL_HOOKS); + #endif - return Status::Success; -#endif - } - - return Status::NotSupportedError; - } - else - { - RenderType::Enum type = RenderType::None; - - if (::GetModuleHandle(KIERO_TEXT("d3d9.dll")) != NULL) - { - type = RenderType::D3D9; - } - else if (::GetModuleHandle(KIERO_TEXT("d3d10.dll")) != NULL) - { - type = RenderType::D3D10; - } - else if (::GetModuleHandle(KIERO_TEXT("d3d11.dll")) != NULL) - { - type = RenderType::D3D11; - } - else if (::GetModuleHandle(KIERO_TEXT("d3d12.dll")) != NULL) - { - type = RenderType::D3D12; - } - else if (::GetModuleHandle(KIERO_TEXT("opengl32.dll")) != NULL) - { - type = RenderType::OpenGL; - } - else if (::GetModuleHandle(KIERO_TEXT("vulkan-1.dll")) != NULL) - { - type = RenderType::Vulkan; - } - else - { - return Status::NotSupportedError; - } - - return init(type); - } - } - - return Status::Success; + #if KIERO_USE_POLYHOOK2 + g_detours.clear(); + #endif + + ::free(g_methodsTable); + g_methodsTable = nullptr; + g_renderType = RenderType::None; + } } -void kiero::shutdown() -{ - if (g_renderType != RenderType::None) - { -#if KIERO_USE_MINHOOK - MH_DisableHook(MH_ALL_HOOKS); -#endif +kiero::Status::Enum kiero::bind(uint16_t _index, void** _original, void* _function) { + // TODO: Need own detour function - ::free(g_methodsTable); - g_methodsTable = NULL; - g_renderType = RenderType::None; - } -} + assert(_original != nullptr && _function != nullptr); -kiero::Status::Enum kiero::bind(uint16_t _index, void** _original, void* _function) -{ - // TODO: Need own detour function + if (g_renderType != RenderType::None) { + #if KIERO_USE_MINHOOK + void* target = (void*) g_methodsTable[_index]; + if (MH_CreateHook(target, _function, _original) != MH_OK || MH_EnableHook(target) != MH_OK) { + return Status::UnknownError; + } + #endif - assert(_original != NULL && _function != NULL); + #if KIERO_USE_POLYHOOK2 + void* target = (void*) g_methodsTable[_index]; - if (g_renderType != RenderType::None) - { -#if KIERO_USE_MINHOOK - void* target = (void*)g_methodsTable[_index]; - if (MH_CreateHook(target, _function, _original) != MH_OK || MH_EnableHook(target) != MH_OK) - { - return Status::UnknownError; - } -#endif + #if KIERO_ARCH_X64 + g_detours[_index] = std::move(std::make_unique(reinterpret_cast(target), reinterpret_cast(_function), reinterpret_cast(_original))); + #endif + #if KIERO_ARCH_X86 + g_detours[_index] = std::move(std::make_unique(reinterpret_cast(target), reinterpret_cast(_function), reinterpret_cast(_original)); + #endif + + if (!g_detours[_index]->hook()) { + return Status::UnknownError; + } + #endif - return Status::Success; - } + return Status::Success; + } - return Status::NotInitializedError; + return Status::NotInitializedError; } -void kiero::unbind(uint16_t _index) -{ - if (g_renderType != RenderType::None) - { -#if KIERO_USE_MINHOOK - MH_DisableHook((void*)g_methodsTable[_index]); -#endif - } +void kiero::unbind(uint16_t _index) { + if (g_renderType != RenderType::None) { + #if KIERO_USE_MINHOOK + MH_DisableHook((void*) g_methodsTable[_index]); + #endif + + #if KIERO_USE_POLYHOOK2 + g_detours.erase(_index); + #endif + } } -kiero::RenderType::Enum kiero::getRenderType() -{ - return g_renderType; +kiero::RenderType::Enum kiero::getRenderType() { + return g_renderType; } -uint150_t* kiero::getMethodsTable() -{ - return g_methodsTable; +uint150_t* kiero::getMethodsTable() { + return g_methodsTable; } \ No newline at end of file diff --git a/kiero.h b/kiero.h index 4aba3d4..36172a9 100644 --- a/kiero.h +++ b/kiero.h @@ -1,22 +1,14 @@ #ifndef __KIERO_H__ #define __KIERO_H__ -#include +#include #define KIERO_VERSION "1.2.12" -#define KIERO_INCLUDE_D3D9 0 // 1 if you need D3D9 hook -#define KIERO_INCLUDE_D3D10 0 // 1 if you need D3D10 hook -#define KIERO_INCLUDE_D3D11 0 // 1 if you need D3D11 hook -#define KIERO_INCLUDE_D3D12 0 // 1 if you need D3D12 hook -#define KIERO_INCLUDE_OPENGL 0 // 1 if you need OpenGL hook -#define KIERO_INCLUDE_VULKAN 0 // 1 if you need Vulkan hook -#define KIERO_USE_MINHOOK 0 // 1 if you will use kiero::bind function - #define KIERO_ARCH_X64 0 #define KIERO_ARCH_X86 0 -#if defined(_M_X64) +#if defined(_M_X64) # undef KIERO_ARCH_X64 # define KIERO_ARCH_X64 1 #else @@ -30,49 +22,45 @@ typedef uint64_t uint150_t; typedef uint32_t uint150_t; #endif -namespace kiero -{ - struct Status - { - enum Enum - { - UnknownError = -1, - NotSupportedError = -2, - ModuleNotFoundError = -3, - - AlreadyInitializedError = -4, - NotInitializedError = -5, - - Success = 0, - }; - }; - - struct RenderType - { - enum Enum - { - None, - - D3D9, - D3D10, - D3D11, - D3D12, - - OpenGL, - Vulkan, - - Auto - }; - }; - - Status::Enum init(RenderType::Enum renderType); - void shutdown(); - - Status::Enum bind(uint16_t index, void** original, void* function); - void unbind(uint16_t index); - - RenderType::Enum getRenderType(); - uint150_t* getMethodsTable(); +namespace kiero { + struct Status { + enum Enum { + UnknownError = -1, + NotSupportedError = -2, + ModuleNotFoundError = -3, + + AlreadyInitializedError = -4, + NotInitializedError = -5, + + Success = 0, + }; + }; + + struct RenderType { + enum Enum { + None, + + D3D9, + D3D10, + D3D10_1, + D3D11, + D3D12, + + OpenGL, + Vulkan, + + Auto + }; + }; + + Status::Enum init(RenderType::Enum renderType); + void shutdown(); + + [[maybe_unused]] Status::Enum bind(uint16_t index, void** original, void* function); + [[maybe_unused]] void unbind(uint16_t index); + + [[maybe_unused]] RenderType::Enum getRenderType(); + [[maybe_unused]] uint150_t* getMethodsTable(); } #endif // __KIERO_H__ \ No newline at end of file