From 8bf08af7b9a3d794a43246a56e787a5177b7f4ce Mon Sep 17 00:00:00 2001 From: PixieCore <41352111+IcePixelx@users.noreply.github.com> Date: Sun, 19 Jun 2022 18:07:43 +0200 Subject: [PATCH] Start of RTech::CreateDXTexture rebuild. * Currently crashes due to stack corruption. --- r5dev/core/init.cpp | 2 + r5dev/rtech/rtech_utils.cpp | 173 ++++++++++++++++++++++++++++++++++ r5dev/rtech/rtech_utils.h | 181 +++++++++++++++++++++++++++++++++++- r5dev/windows/id3dx.h | 9 +- 4 files changed, 363 insertions(+), 2 deletions(-) diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index 3d553e04..b311a3fe 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -192,6 +192,7 @@ void Systems_Init() SQAUX_Attach(); RTech_Game_Attach(); + RTech_Utils_Attach(); #ifndef DEDICATED Rui_Attach(); #endif // !DEDICATED @@ -309,6 +310,7 @@ void Systems_Shutdown() SQAUX_Detach(); RTech_Game_Detach(); + RTech_Utils_Detach(); #ifndef DEDICATED Rui_Detach(); #endif // !DEDICATED diff --git a/r5dev/rtech/rtech_utils.cpp b/r5dev/rtech/rtech_utils.cpp index d4454a87..dbcc59c6 100644 --- a/r5dev/rtech/rtech_utils.cpp +++ b/r5dev/rtech/rtech_utils.cpp @@ -1,5 +1,9 @@ #include "core/stdafx.h" #include "rtech/rtech_utils.h" +#ifndef DEDICATED +#include "windows/id3dx.h" +#endif // !DEDICATED + /****************************************************************************** ------------------------------------------------------------------------------- @@ -496,6 +500,160 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std:: return result; } +#if not defined DEDICATED && defined (GAMEDLL_S3) + +void RTech::CreateDXTexture(RPakTextureHeader_t* textureHeader, int64_t imageData) +{ + RPakTextureHeader_t* v2; // rbx + uint16_t v4; // cx + int v5; // esi + UINT v6; // edi + uint8_t v7; // r15 + UINT v8; // er14 + unsigned int v9; // er8 + unsigned int v10; // er11 + unsigned int v11; // er10 + unsigned int v12; // er13 + int v13; // ebx + int v14; // er12 + int v15; // eax + int v16; // edx + int v17; // eax + unsigned int v18; // edx + int v19; // er11 + int v20; // er8 + UINT v21; // eax + unsigned int v22; // er8 + __int64 v23; // rdx + __int64 v24; // rcx + unsigned int v25; // er8 + DXGI_FORMAT v26; // esi + unsigned int v27; // edx + unsigned int v28; // er8 + UINT v29; // eax + unsigned int v30; // edx + UINT v31; // eax + bool v32; // zf + int create_texture_err_var; // eax + uint8_t v34; // al + int v35; // ecx + int create_shader_resource_view_err; // eax + unsigned int v37; // [rsp+20h] [rbp-E0h] + unsigned int v38; // [rsp+24h] [rbp-DCh] + DXGI_FORMAT v39; // [rsp+28h] [rbp-D8h] BYREF + __int64 v40; // [rsp+2Ch] [rbp-D4h] + int v41; // [rsp+34h] [rbp-CCh] + int v42; // [rsp+38h] [rbp-C8h] + int v43; // [rsp+3Ch] [rbp-C4h] + D3D11_TEXTURE2D_DESC p_texture_desc_var; // [rsp+40h] [rbp-C0h] BYREF + D3D11_SUBRESOURCE_DATA p_initial_data_var; // [rsp+70h] [rbp-90h] BYREF + RPakTextureHeader_t* v46; // [rsp+80B0h] [rbp+7FB0h] + unsigned int v47; // [rsp+80C0h] [rbp+7FC0h] + + ZeroMemory(&p_texture_desc_var, sizeof(p_texture_desc_var)); + ZeroMemory(&p_initial_data_var, sizeof(p_initial_data_var)); + + v2 = textureHeader; + v4 = textureHeader->m_nFormat; + if (!v2->unk0 && v2->m_nHeight) + { + v5 = v2->m_nMipLevelsStreamedOpt + v2->m_nMipLevelsStreamed; + v6 = v2->m_nMipLevels; + v7 = v2->m_nArraySize; + v8 = v6 + v5; + if (v6 + v5 != v5) + { + v9 = v2->m_nWidth; + v10 = v2->m_nHeight; + v37 = v9; + v38 = v10; + v11 = HIBYTE(s_pBitsPerPixelWord[v4]); + v12 = v11 >> 1; + v47 = v11; + v13 = LOBYTE(s_pBitsPerPixelWord[v4]); + v14 = v13 * (v11 >> (v11 >> 1)); + do + { + --v8; + v15 = 1; + if (v9 >> v8 > 1) + v15 = v9 >> v8; + v16 = v15 - 1; + v17 = 1; + v18 = (v11 + v16) >> v12; + if (v10 >> v8 > 1) + v17 = v10 >> v8; + v19 = v18 * v14; + v20 = v17 - 1; + v21 = v8; + v22 = v13 * v18 * ((v11 + v20) >> v12); + if (v7) + { + v23 = v7; + do + { + v24 = v21; + v21 += v6; + v24 *= 16i64; + *(const void**)((char*)&p_initial_data_var.pSysMem + v24) = (const void*)imageData; + imageData += (v22 + 15) & 0xFFFFFFF0; + *(UINT*)((char*)&p_initial_data_var.SysMemPitch + v24) = v19; + *(UINT*)((char*)&p_initial_data_var.SysMemSlicePitch + v24) = v22; + --v23; + } while (v23); + v11 = v47; + } + v9 = v37; + v10 = v38; + } while (v8 != v5); + } + LOBYTE(v2[1].m_nNameHash) = v6; + v25 = v2->m_nWidth; + p_texture_desc_var.MipLevels = v6; + v26 = rpakToDxgiFormat[v4]; + v27 = v2->m_nHeight; + p_texture_desc_var.Format = v26; + v28 = v25 >> v8; + v29 = 1; + v30 = v27 >> v8; + p_texture_desc_var.SampleDesc.Count = 1; + if (v28 > 1) + v29 = v28; + *(_QWORD*)&p_texture_desc_var.BindFlags = 8; + p_texture_desc_var.Width = v29; + v31 = 1; + if (v30 > 1) + v31 = v30; + p_texture_desc_var.Height = v31; + v32 = v2->unk2 == 2; + p_texture_desc_var.ArraySize = v7; + p_texture_desc_var.MiscFlags = 0; + p_texture_desc_var.Usage = (D3D11_USAGE)!v32; + create_texture_err_var = (*g_ppGameDevice)->CreateTexture2D(&p_texture_desc_var, &p_initial_data_var + v8, &v2->m_ppTexture); + if (create_texture_err_var < 0) + Error(eDLL_T::RTECH, "Couldn't create texture \"%s\": error code %08x\n", *(const char**)&v2->m_nNameIndex, (unsigned int)create_texture_err_var); + v34 = v2->m_nArraySize; + v35 = LOBYTE(v2[1].m_nNameHash); + v39 = v26; + v41 = v35; + if (v34 <= 1u) + { + v40 = 4i64; + } + else + { + v43 = v34; + v40 = 5i64; + v42 = 0; + } + create_shader_resource_view_err = (*g_ppGameDevice)->CreateShaderResourceView((ID3D11Resource*)v2->m_ppTexture, (D3D11_SHADER_RESOURCE_VIEW_DESC*)&v39, &v2->m_ppShaderResourceView); + if (create_shader_resource_view_err < 0) + Error(eDLL_T::RTECH, "Couldn't create shader resource view for texture \"%s\": error code %08x\n", *(const char**)&v2->m_nNameIndex, (unsigned int)create_shader_resource_view_err); + } +} + +#endif + //----------------------------------------------------------------------------- // Purpose: gets information about loaded pak file via pak ID //----------------------------------------------------------------------------- @@ -540,5 +698,20 @@ RPakLoadedInfo_t* RTech::GetPakLoadedInfo(const char* szPakName) Warning(eDLL_T::RTECH, "%s - Failed getting RPakLoadInfo_t for Pak '%s'\n", __FUNCTION__, szPakName); return nullptr; } + +void RTech_Utils_Attach() +{ +#ifndef DEDICATED + //DetourAttach((LPVOID*)&RTech_CreateDXTexture, &RTech::CreateDXTexture); +#endif +} + +void RTech_Utils_Detach() +{ +#ifndef DEDICATED + //DetourDetach((LPVOID*)&RTech_CreateDXTexture, &RTech::CreateDXTexture); +#endif +} + /////////////////////////////////////////////////////////////////////////////// RTech* g_pRTech = new RTech(); diff --git a/r5dev/rtech/rtech_utils.h b/r5dev/rtech/rtech_utils.h index 0e5f18af..b1644e09 100644 --- a/r5dev/rtech/rtech_utils.h +++ b/r5dev/rtech/rtech_utils.h @@ -144,6 +144,164 @@ struct __declspec(align(8)) RPakDecompState_t std::uint64_t m_nDecompStreamSize; }; +#if not defined DEDICATED && defined (GAMEDLL_S3) + +struct RPakTextureHeader_t +{ + uint64_t m_nNameHash; + uint32_t m_nNameIndex; + uint32_t m_nNameOffset; + uint16_t m_nWidth; + uint16_t m_nHeight; + uint16_t unk0; + uint16_t m_nFormat; + uint32_t m_nDataSize; + uint8_t unk1; + uint8_t m_nMipLevelsStreamedOpt; + uint8_t m_nArraySize; + uint8_t m_nLayerCount; + uint8_t unk2; + uint8_t m_nMipLevels; + uint8_t m_nMipLevelsStreamed; + uint8_t unk3[310]; + ID3D11Texture2D* m_ppTexture; + ID3D11ShaderResourceView* m_ppShaderResourceView; +}; + +// Map of dxgi format to txtr asset format +static std::map dxgiToRPakFormat { + { DXGI_FORMAT_BC1_UNORM, 0 }, + { DXGI_FORMAT_BC1_UNORM_SRGB, 1 }, + { DXGI_FORMAT_BC2_UNORM, 2 }, + { DXGI_FORMAT_BC2_UNORM_SRGB, 3 }, + { DXGI_FORMAT_BC3_UNORM, 4 }, + { DXGI_FORMAT_BC3_UNORM_SRGB, 5 }, + { DXGI_FORMAT_BC4_UNORM, 6 }, + { DXGI_FORMAT_BC4_SNORM, 7 }, + { DXGI_FORMAT_BC5_UNORM, 8 }, + { DXGI_FORMAT_BC5_SNORM, 9 }, + { DXGI_FORMAT_BC6H_UF16, 10 }, + { DXGI_FORMAT_BC6H_SF16, 11 }, + { DXGI_FORMAT_BC7_UNORM, 12 }, + { DXGI_FORMAT_BC7_UNORM_SRGB, 13 }, + { DXGI_FORMAT_R32G32B32A32_FLOAT, 14 }, + { DXGI_FORMAT_R32G32B32A32_UINT, 15 }, + { DXGI_FORMAT_R32G32B32A32_SINT, 16 }, + { DXGI_FORMAT_R32G32B32_FLOAT, 17 }, + { DXGI_FORMAT_R32G32B32_UINT, 18 }, + { DXGI_FORMAT_R32G32B32_SINT, 19 }, + { DXGI_FORMAT_R16G16B16A16_FLOAT, 20 }, + { DXGI_FORMAT_R16G16B16A16_UNORM, 21 }, + { DXGI_FORMAT_R16G16B16A16_UINT, 22 }, + { DXGI_FORMAT_R16G16B16A16_SNORM, 23 }, + { DXGI_FORMAT_R16G16B16A16_SINT, 24 }, + { DXGI_FORMAT_R32G32_FLOAT, 25 }, + { DXGI_FORMAT_R32G32_UINT, 26 }, + { DXGI_FORMAT_R32G32_SINT, 27 }, + { DXGI_FORMAT_R10G10B10A2_UNORM, 28 }, + { DXGI_FORMAT_R10G10B10A2_UINT, 29 }, + { DXGI_FORMAT_R11G11B10_FLOAT, 30 }, + { DXGI_FORMAT_R8G8B8A8_UNORM, 31 }, + { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 32 }, + { DXGI_FORMAT_R8G8B8A8_UINT, 33 }, + { DXGI_FORMAT_R8G8B8A8_SNORM, 34 }, + { DXGI_FORMAT_R8G8B8A8_SINT, 35 }, + { DXGI_FORMAT_R16G16_FLOAT, 36 }, + { DXGI_FORMAT_R16G16_UNORM, 37 }, + { DXGI_FORMAT_R16G16_UINT, 38 }, + { DXGI_FORMAT_R16G16_SNORM, 39 }, + { DXGI_FORMAT_R16G16_SINT, 40 }, + { DXGI_FORMAT_R32_FLOAT, 41 }, + { DXGI_FORMAT_R32_UINT, 42 }, + { DXGI_FORMAT_R32_SINT, 43 }, + { DXGI_FORMAT_R8G8_UNORM, 44 }, + { DXGI_FORMAT_R8G8_UINT, 45 }, + { DXGI_FORMAT_R8G8_SNORM, 46 }, + { DXGI_FORMAT_R8G8_SINT, 47 }, + { DXGI_FORMAT_R16_FLOAT, 48 }, + { DXGI_FORMAT_R16_UNORM, 49 }, + { DXGI_FORMAT_R16_UINT, 50 }, + { DXGI_FORMAT_R16_SNORM, 51 }, + { DXGI_FORMAT_R16_SINT, 52 }, + { DXGI_FORMAT_R8_UNORM, 53 }, + { DXGI_FORMAT_R8_UINT, 54 }, + { DXGI_FORMAT_R8_SNORM, 55 }, + { DXGI_FORMAT_R8_SINT, 56 }, + { DXGI_FORMAT_A8_UNORM, 57 }, + { DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 58 }, + { DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, 59 }, + { DXGI_FORMAT_D32_FLOAT, 60 }, + { DXGI_FORMAT_D16_UNORM, 61 }, +}; + +// Map of txtr asset format to dxgi format +static std::map rpakToDxgiFormat { + { 0, DXGI_FORMAT_BC1_UNORM }, + { 1, DXGI_FORMAT_BC1_UNORM_SRGB }, + { 2, DXGI_FORMAT_BC2_UNORM }, + { 3, DXGI_FORMAT_BC2_UNORM_SRGB }, + { 4, DXGI_FORMAT_BC3_UNORM }, + { 5, DXGI_FORMAT_BC3_UNORM_SRGB}, + { 6, DXGI_FORMAT_BC4_UNORM }, + { 7, DXGI_FORMAT_BC4_SNORM }, + { 8, DXGI_FORMAT_BC5_UNORM }, + { 9, DXGI_FORMAT_BC5_SNORM }, + { 10, DXGI_FORMAT_BC6H_UF16 }, + { 11, DXGI_FORMAT_BC6H_SF16 }, + { 12, DXGI_FORMAT_BC7_UNORM }, + { 13, DXGI_FORMAT_BC7_UNORM_SRGB }, + { 14, DXGI_FORMAT_R32G32B32A32_FLOAT }, + { 15, DXGI_FORMAT_R32G32B32A32_UINT }, + { 16, DXGI_FORMAT_R32G32B32A32_SINT }, + { 17, DXGI_FORMAT_R32G32B32_FLOAT }, + { 18, DXGI_FORMAT_R32G32B32_UINT }, + { 19, DXGI_FORMAT_R32G32B32_SINT }, + { 20, DXGI_FORMAT_R16G16B16A16_FLOAT }, + { 21, DXGI_FORMAT_R16G16B16A16_UNORM }, + { 22, DXGI_FORMAT_R16G16B16A16_UINT }, + { 23, DXGI_FORMAT_R16G16B16A16_SNORM }, + { 24, DXGI_FORMAT_R16G16B16A16_SINT }, + { 25, DXGI_FORMAT_R32G32_FLOAT }, + { 26, DXGI_FORMAT_R32G32_UINT }, + { 27, DXGI_FORMAT_R32G32_SINT }, + { 28, DXGI_FORMAT_R10G10B10A2_UNORM }, + { 29, DXGI_FORMAT_R10G10B10A2_UINT }, + { 30, DXGI_FORMAT_R11G11B10_FLOAT }, + { 31, DXGI_FORMAT_R8G8B8A8_UNORM }, + { 32, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB }, + { 33, DXGI_FORMAT_R8G8B8A8_UINT }, + { 34, DXGI_FORMAT_R8G8B8A8_SNORM }, + { 35, DXGI_FORMAT_R8G8B8A8_SINT }, + { 36, DXGI_FORMAT_R16G16_FLOAT }, + { 37, DXGI_FORMAT_R16G16_UNORM }, + { 38, DXGI_FORMAT_R16G16_UINT }, + { 39, DXGI_FORMAT_R16G16_SNORM }, + { 40, DXGI_FORMAT_R16G16_SINT }, + { 41, DXGI_FORMAT_R32_FLOAT }, + { 42, DXGI_FORMAT_R32_UINT }, + { 43, DXGI_FORMAT_R32_SINT }, + { 44, DXGI_FORMAT_R8G8_UNORM }, + { 45, DXGI_FORMAT_R8G8_UINT }, + { 46, DXGI_FORMAT_R8G8_SNORM }, + { 47, DXGI_FORMAT_R8G8_SINT }, + { 48, DXGI_FORMAT_R16_FLOAT }, + { 49, DXGI_FORMAT_R16_UNORM }, + { 50, DXGI_FORMAT_R16_UINT }, + { 51, DXGI_FORMAT_R16_SNORM }, + { 52, DXGI_FORMAT_R16_SINT }, + { 53, DXGI_FORMAT_R8_UNORM }, + { 54, DXGI_FORMAT_R8_UINT }, + { 55, DXGI_FORMAT_R8_SNORM }, + { 56, DXGI_FORMAT_R8_SINT }, + { 57, DXGI_FORMAT_A8_UNORM}, + { 58, DXGI_FORMAT_R9G9B9E5_SHAREDEXP }, + { 59, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, + { 60, DXGI_FORMAT_D32_FLOAT }, + { 61, DXGI_FORMAT_D16_UNORM }, +}; + +#endif + class RPakLoadedInfo_t { public: @@ -163,8 +321,14 @@ public: }; //Size: 0x00B8/0x00E8 /* ==== RTECH =========================================================================================================================================================== */ +#if not defined DEDICATED && defined (GAMEDLL_S3) +inline CMemory p_RTech_CreateDXTexture; +inline auto RTech_CreateDXTexture = p_RTech_CreateDXTexture.RCast(); +#endif + inline RPakLoadedInfo_t* g_pLoadedPakInfo; inline std::int16_t* s_pLoadedPakCount; +inline int16_t* s_pBitsPerPixelWord; class RTech { @@ -174,8 +338,14 @@ public: std::uint64_t __fastcall DecompressPakFileInit(RPakDecompState_t* state, std::uint8_t* fileBuffer, std::uint64_t fileSize, std::uint64_t offNoHeader, std::uint64_t headerSize); RPakLoadedInfo_t* GetPakLoadedInfo(int nPakId); RPakLoadedInfo_t* GetPakLoadedInfo(const char* szPakName); + +#if not defined DEDICATED && defined (GAMEDLL_S3) + static void __fastcall CreateDXTexture(RPakTextureHeader_t* textureHeader, int64_t cpuArg); +#endif }; +void RTech_Utils_Attach(); +void RTech_Utils_Detach(); /////////////////////////////////////////////////////////////////////////////// extern RTech* g_pRTech; @@ -189,13 +359,22 @@ class VPakFile : public IDetour spdlog::debug("| VAR: s_pLoadedPakCount : {:#18x} |\n", reinterpret_cast(s_pLoadedPakCount)); spdlog::debug("+----------------------------------------------------------------+\n"); } - virtual void GetFun(void) const { } + virtual void GetFun(void) const + { +#if not defined DEDICATED && defined (GAMEDLL_S3) + p_RTech_CreateDXTexture = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xE8\x00\x00\x00\x00\x4C\x8B\xC7\x48\x8B\xD5\x48\x8B\xCB\x48\x83\xC4\x60"), "x????xxxxxxxxxxxxx").FollowNearCallSelf(); + RTech_CreateDXTexture = p_RTech_CreateDXTexture.RCast(); /*E8 ? ? ? ? 4C 8B C7 48 8B D5 48 8B CB 48 83 C4 60*/ +#endif + } virtual void GetVar(void) const { CMemory localRef = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x8B\xC1"), "xxxx?xxxx?xxxxxxx"); g_pLoadedPakInfo = localRef.FindPattern("48 8D 05", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); s_pLoadedPakCount = localRef.FindPattern("66 89", CMemory::Direction::DOWN, 450).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); +#if not defined DEDICATED && defined (GAMEDLL_S3) + s_pBitsPerPixelWord = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x0F\xB7\x43\x16\x48\x8D\x0D\x00\x00\x00\x00"), "xxxxxxx????").OffsetSelf(0x4).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); +#endif } virtual void GetCon(void) const { } virtual void Attach(void) const { } diff --git a/r5dev/windows/id3dx.h b/r5dev/windows/id3dx.h index a8aab659..19d0fa11 100644 --- a/r5dev/windows/id3dx.h +++ b/r5dev/windows/id3dx.h @@ -112,11 +112,18 @@ enum class DXGISwapChainVTbl : short GetLastPresentCount = 17, }; +inline CMemory p_gGameDevice; +inline ID3D11Device** g_ppGameDevice = nullptr; + class HIDXGI : public IDetour { virtual void GetAdr(void) const; virtual void GetFun(void) const { } - virtual void GetVar(void) const { } + virtual void GetVar(void) const + { + p_gGameDevice = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xD3\xEA\x48\x8B\x0D\x00\x00\x00\x00"), "xxxxx????").OffsetSelf(0x2).ResolveRelativeAddressSelf(0x3, 0x7); + g_ppGameDevice = p_gGameDevice.RCast(); /*D3 EA 48 8B 0D ? ? ? ?*/ + } virtual void GetCon(void) const { } virtual void Attach(void) const { } virtual void Detach(void) const { }