From 7a6e1b246e088235c7ed25b05032f1a67627a930 Mon Sep 17 00:00:00 2001 From: hedin77 Date: Mon, 3 Oct 2022 14:32:06 +0700 Subject: [PATCH 1/6] add possibility of dynamic scale font for [FontRendering] Enable=1 --- D3D11Engine/D3D11Engine.vcxproj | 16 ++++++++-------- D3D11Engine/D3D11GraphicsEngine.cpp | 10 +--------- Launcher/Launcher.vcxproj | 2 +- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/D3D11Engine/D3D11Engine.vcxproj b/D3D11Engine/D3D11Engine.vcxproj index 5249bd6e..0f3a1717 100644 --- a/D3D11Engine/D3D11Engine.vcxproj +++ b/D3D11Engine/D3D11Engine.vcxproj @@ -48,14 +48,14 @@ DynamicLibrary false - v142 + v143 true MultiByte DynamicLibrary false - v142 + v143 true MultiByte @@ -69,42 +69,42 @@ DynamicLibrary false - v142 + v143 true MultiByte DynamicLibrary false - v142 + v143 true MultiByte DynamicLibrary false - v142 + v143 true MultiByte DynamicLibrary false - v142 + v143 true MultiByte DynamicLibrary false - v142 + v143 true MultiByte DynamicLibrary false - v142 + v143 true MultiByte diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index 6c0e3cdb..85750870 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -6394,14 +6394,6 @@ void D3D11GraphicsEngine::DrawString( const std::string& str, float x, float y, if ( str.empty() ) return; if ( !font ) return; if ( !font->tex ) return; - float UIScale = 1.0f; - static int savedBarSize = -1; - if ( oCGame::GetGame() ) { - if ( savedBarSize == -1 ) { - savedBarSize = oCGame::GetGame()->swimBar->psizex; - } - UIScale = static_cast(savedBarSize) / 180.f; - } constexpr float FONT_CACHE_PRIO = -1; zCTexture* tx = font->tex; @@ -6466,7 +6458,7 @@ void D3D11GraphicsEngine::DrawString( const std::string& str, float x, float y, maxLen--; } - UI::zFont::AppendGlyphs( vertices, str, maxLen, x, y, font, fontColor, UIScale, zCCamera::GetCamera() ); + UI::zFont::AppendGlyphs( vertices, str, maxLen, x, y, font, fontColor, oCGame::GetGame() && oCGame::GetGame()->swimBar ? static_cast(oCGame::GetGame()->swimBar->psizex) / 180.f : 1.0f, zCCamera::GetCamera() ); //if (str[0] == '(') { // int o = 1; diff --git a/Launcher/Launcher.vcxproj b/Launcher/Launcher.vcxproj index 497253ed..51506766 100644 --- a/Launcher/Launcher.vcxproj +++ b/Launcher/Launcher.vcxproj @@ -17,7 +17,7 @@ DynamicLibrary false - v142 + v143 true Unicode From 101bb31f71b96ecc77c2e6fcdb62706ad573d972 Mon Sep 17 00:00:00 2001 From: hedin77 Date: Mon, 3 Oct 2022 16:46:47 +0700 Subject: [PATCH 2/6] change version --- D3D11Engine/pch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/D3D11Engine/pch.h b/D3D11Engine/pch.h index b0cf5545..1e556e71 100644 --- a/D3D11Engine/pch.h +++ b/D3D11Engine/pch.h @@ -31,7 +31,7 @@ using namespace DirectX; #define ENABLE_TESSELATION 0 -#define VERSION_NUMBER "17.8-dev8" +#define VERSION_NUMBER "17.8-dev9" __declspec(selectany) const char* VERSION_NUMBER_STR = VERSION_NUMBER; extern bool FeatureLevel10Compatibility; From 247ed779a0cece7ed4c8261039685d437b62bc8f Mon Sep 17 00:00:00 2001 From: hedin77 Date: Tue, 4 Oct 2022 09:39:10 +0700 Subject: [PATCH 3/6] Returned base font scale from swim bar and added unionCurrentCustomFontMultiplier --- BuildAll.bat | 2 +- BuilsAVX.bat | 11 +++++++++++ CreateRedist_All.bat | 2 +- D3D11Engine/D3D11GraphicsEngine.cpp | 22 +++++++++++++++++++++- D3D11Engine/D3D11GraphicsEngine.h | 4 ++++ D3D11Engine/DLLMain.cpp | 9 +++++++++ D3D11Engine/ddraw.def | 3 ++- Launcher/ddraw.def | 3 ++- Launcher/dllmain.cpp | 7 +++++++ 9 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 BuilsAVX.bat diff --git a/BuildAll.bat b/BuildAll.bat index d69e73de..dbeae899 100644 --- a/BuildAll.bat +++ b/BuildAll.bat @@ -1,7 +1,7 @@ @ECHO OFF CD %~dp0 -SET "MSBUILD=C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\amd64\MSBuild.exe" +SET "MSBUILD=G:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\amd64\MSBuild.exe" REM RMDIR /s /q D3D11Engine\Release_AVX\ REM RMDIR /s /q D3D11Engine\Release\ diff --git a/BuilsAVX.bat b/BuilsAVX.bat new file mode 100644 index 00000000..fda9496f --- /dev/null +++ b/BuilsAVX.bat @@ -0,0 +1,11 @@ +@ECHO OFF +CD %~dp0 + +SET "MSBUILD=G:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\amd64\MSBuild.exe" + +REM RMDIR /s /q D3D11Engine\Release_AVX\ +REM RMDIR /s /q D3D11Engine\Release\ +REM RMDIR /s /q D3D11Engine\Release_G1_AVX\ +REM RMDIR /s /q D3D11Engine\Release_G1\ + +"%MSBUILD%" Direct3D7Wrapper.sln /p:Configuration=Release_AVX \ No newline at end of file diff --git a/CreateRedist_All.bat b/CreateRedist_All.bat index 6109bf8b..7bc3adfc 100644 --- a/CreateRedist_All.bat +++ b/CreateRedist_All.bat @@ -3,7 +3,7 @@ setlocal enableextensions enabledelayedexpansion PUSHD %~dp0 -SET "VERSION=17.7-dev20" +SET "VERSION=17.8-dev9" CALL :SUB_BUILD "Gothic2-GD3D11-%VERSION%_avx2" "Release_AVX" CD /D %~dp0 diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index 85750870..9d0ec0b1 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -59,6 +59,7 @@ const int NUM_MIN_FRAME_SHADOW_UPDATES = 4; // Minimum lights to update per frame const int MAX_IMPORTANT_LIGHT_UPDATES = 1; + D3D11GraphicsEngine::D3D11GraphicsEngine() { DebugPointlight = nullptr; OutputWindow = nullptr; @@ -86,6 +87,7 @@ D3D11GraphicsEngine::D3D11GraphicsEngine() { Engine::GAPI->GetRendererState().RendererSettings.LoadedResolution; CachedRefreshRate.Numerator = 0; CachedRefreshRate.Denominator = 0; + unionCurrentCustomFontMultiplier = 1.0; } D3D11GraphicsEngine::~D3D11GraphicsEngine() { @@ -6390,17 +6392,35 @@ namespace UI::zFont { } } + +float D3D11GraphicsEngine::UpdateCustomFontMultiplierFontRendering( float multiplier ) { + float res = unionCurrentCustomFontMultiplier; + unionCurrentCustomFontMultiplier = multiplier; + return res; +} + void D3D11GraphicsEngine::DrawString( const std::string& str, float x, float y, const zFont* font, zColor& fontColor ) { if ( str.empty() ) return; if ( !font ) return; if ( !font->tex ) return; + float UIScale = 1.0f; + static int savedBarSize = -1; + if ( oCGame::GetGame() ) { + if ( savedBarSize == -1 ) { + savedBarSize = oCGame::GetGame()->swimBar->psizex; + } + UIScale = static_cast(savedBarSize) / 180.f; + } + constexpr float FONT_CACHE_PRIO = -1; zCTexture* tx = font->tex; if ( tx->CacheIn( FONT_CACHE_PRIO ) != zRES_CACHED_IN ) { return; } + + UIScale *= unionCurrentCustomFontMultiplier; // // Backup old renderstates, BlendState can be ignored here. @@ -6458,7 +6478,7 @@ void D3D11GraphicsEngine::DrawString( const std::string& str, float x, float y, maxLen--; } - UI::zFont::AppendGlyphs( vertices, str, maxLen, x, y, font, fontColor, oCGame::GetGame() && oCGame::GetGame()->swimBar ? static_cast(oCGame::GetGame()->swimBar->psizex) / 180.f : 1.0f, zCCamera::GetCamera() ); + UI::zFont::AppendGlyphs( vertices, str, maxLen, x, y, font, fontColor, UIScale, zCCamera::GetCamera() ); //if (str[0] == '(') { // int o = 1; diff --git a/D3D11Engine/D3D11GraphicsEngine.h b/D3D11Engine/D3D11GraphicsEngine.h index d5053306..67ff727e 100644 --- a/D3D11Engine/D3D11GraphicsEngine.h +++ b/D3D11Engine/D3D11GraphicsEngine.h @@ -337,6 +337,9 @@ class D3D11GraphicsEngine : public D3D11GraphicsEngineBase { RenderToTextureBuffer* GetDummyCubeRT() { return DummyShadowCubemapTexture.get(); } void EnsureTempVertexBufferSize( std::unique_ptr& buffer, UINT size ); + + float UpdateCustomFontMultiplierFontRendering( float multiplier ); + protected: std::unique_ptr m_FrameLimiter; int m_LastFrameLimit; @@ -438,4 +441,5 @@ class D3D11GraphicsEngine : public D3D11GraphicsEngineBase { bool m_HDR; int m_previousFpsLimit; bool m_isWindowActive; + float unionCurrentCustomFontMultiplier; }; diff --git a/D3D11Engine/DLLMain.cpp b/D3D11Engine/DLLMain.cpp index 66d54203..ec0da8c5 100644 --- a/D3D11Engine/DLLMain.cpp +++ b/D3D11Engine/DLLMain.cpp @@ -10,6 +10,7 @@ #include #include "VersionCheck.h" #include "InstructionSet.h" +#include "D3D11GraphicsEngine.h" #include @@ -66,6 +67,7 @@ struct ddraw_dll { FARPROC GetSurfaceFromDC; FARPROC RegisterSpecialCase; FARPROC ReleaseDDThreadLock; + FARPROC UpdateCustomFontMultiplier; } ddraw; HRESULT DoHookedDirectDrawCreateEx( GUID FAR* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown FAR* pUnkOuter ) { @@ -111,6 +113,13 @@ extern "C" void WINAPI HookedReleaseDDThreadLock() { LogInfo() << "ReleaseDDThreadLock called!"; } + +extern "C" float WINAPI UpdateCustomFontMultiplierFontRendering( float multiplier ) { + D3D11GraphicsEngine* engine = reinterpret_cast(Engine::GraphicsEngine); + return engine ? engine->UpdateCustomFontMultiplierFontRendering( multiplier ) : 1.0; +} + + __declspec(naked) void FakeAcquireDDThreadLock() { _asm { jmp[ddraw.AcquireDDThreadLock] } } __declspec(naked) void FakeCheckFullscreen() { _asm { jmp[ddraw.CheckFullscreen] } } __declspec(naked) void FakeCompleteCreateSysmemSurface() { _asm { jmp[ddraw.CompleteCreateSysmemSurface] } } diff --git a/D3D11Engine/ddraw.def b/D3D11Engine/ddraw.def index e3cc457e..f50f9259 100644 --- a/D3D11Engine/ddraw.def +++ b/D3D11Engine/ddraw.def @@ -21,4 +21,5 @@ EXPORTS GetOLEThunkData = FakeGetOLEThunkData @19 GetSurfaceFromDC = FakeGetSurfaceFromDC @20 RegisterSpecialCase = FakeRegisterSpecialCase @21 - ReleaseDDThreadLock = HookedReleaseDDThreadLock @22 \ No newline at end of file + ReleaseDDThreadLock = HookedReleaseDDThreadLock @22 + UpdateCustomFontMultiplier = UpdateCustomFontMultiplierFontRendering @23 \ No newline at end of file diff --git a/Launcher/ddraw.def b/Launcher/ddraw.def index 3fc16816..5dad6b26 100644 --- a/Launcher/ddraw.def +++ b/Launcher/ddraw.def @@ -33,4 +33,5 @@ EXPORTS GDX_SetShadowAOStrength = FakeGDX_SetShadowAOStrength @31 GDX_SetWorldAOStrength = FakeGDX_SetWorldAOStrength @32 GDX_OpenMessageBox = FakeGDX_OpenMessageBox @33 - GDX_Module = FakeGDX_Module @34 \ No newline at end of file + GDX_Module = FakeGDX_Module @34 + UpdateCustomFontMultiplier = FakeUpdateCustomFontMultiplier @35 \ No newline at end of file diff --git a/Launcher/dllmain.cpp b/Launcher/dllmain.cpp index bc7d8417..4552865a 100644 --- a/Launcher/dllmain.cpp +++ b/Launcher/dllmain.cpp @@ -43,6 +43,8 @@ struct ddraw_dll { FARPROC GDX_SetShadowAOStrength; FARPROC GDX_SetWorldAOStrength; FARPROC GDX_OpenMessageBox; + + FARPROC UpdateCustomFontMultiplier; } ddraw; __declspec(naked) void FakeAcquireDDThreadLock() { _asm { jmp[ddraw.AcquireDDThreadLock] } } @@ -80,6 +82,9 @@ __declspec(naked) void FakeGDX_SetShadowAOStrength() { _asm { jmp[ddraw.GDX_SetS __declspec(naked) void FakeGDX_SetWorldAOStrength() { _asm { jmp[ddraw.GDX_SetWorldAOStrength] } } __declspec(naked) void FakeGDX_OpenMessageBox() { _asm { jmp[ddraw.GDX_OpenMessageBox] } } +__declspec(naked) void FakeUpdateCustomFontMultiplier() { _asm { jmp[ddraw.UpdateCustomFontMultiplier] } } + + extern "C" HMODULE WINAPI FakeGDX_Module() { return ddraw.dll; } @@ -285,6 +290,8 @@ BOOL APIENTRY DllMain( HINSTANCE hInst, DWORD reason, LPVOID ) { ddraw.GDX_SetShadowAOStrength = GetProcAddress( ddraw.dll, "GDX_SetShadowAOStrength" ); ddraw.GDX_SetWorldAOStrength = GetProcAddress( ddraw.dll, "GDX_SetWorldAOStrength" ); ddraw.GDX_OpenMessageBox = GetProcAddress( ddraw.dll, "GDX_OpenMessageBox" ); + ddraw.UpdateCustomFontMultiplier = GetProcAddress( ddraw.dll, "UpdateCustomFontMultiplier" ); + } else if ( reason == DLL_PROCESS_DETACH ) { FreeLibrary( ddraw.dll ); } From fb7d631ff022c1be09dea0a8ab8d27aed2f31302 Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Wed, 5 Oct 2022 00:25:00 +0200 Subject: [PATCH 4/6] Fix loading 16bit textures and add support for other 16bit formats Zengine have a bug where it don't accept pitch different than ((width >> MipLevel) * bytesPerPixel) when loading mipmaps from tiled texture --- D3D11Engine/D3D11Engine.vcxproj | 1 + D3D11Engine/D3D11Engine.vcxproj.filters | 3 + D3D11Engine/D3D7/Conversions.h | 113 ++++++++++++++++++++ D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp | 17 ++- D3D11Engine/D3D7/MyDirectDraw.h | 16 +++ D3D11Engine/D3D7/MyDirectDrawSurface7.cpp | 22 ++-- 6 files changed, 155 insertions(+), 17 deletions(-) create mode 100644 D3D11Engine/D3D7/Conversions.h diff --git a/D3D11Engine/D3D11Engine.vcxproj b/D3D11Engine/D3D11Engine.vcxproj index 6b0a14e3..7d643532 100644 --- a/D3D11Engine/D3D11Engine.vcxproj +++ b/D3D11Engine/D3D11Engine.vcxproj @@ -620,6 +620,7 @@ copy "$(OutDir)$(TargetName).pdb" "$(G1_SYSTEM_PATH)\ddraw.pdb" + diff --git a/D3D11Engine/D3D11Engine.vcxproj.filters b/D3D11Engine/D3D11Engine.vcxproj.filters index 7b09f9c2..869d7102 100644 --- a/D3D11Engine/D3D11Engine.vcxproj.filters +++ b/D3D11Engine/D3D11Engine.vcxproj.filters @@ -725,6 +725,9 @@ ZenGin\Classes + + D3D7 + diff --git a/D3D11Engine/D3D7/Conversions.h b/D3D11Engine/D3D7/Conversions.h new file mode 100644 index 00000000..fa5bacad --- /dev/null +++ b/D3D11Engine/D3D7/Conversions.h @@ -0,0 +1,113 @@ +#pragma once +#include +#include + +static void Convert555to8888(unsigned char* dst, unsigned char* src, UINT realDataSize) +{ + for(UINT i = 0; i < realDataSize / 4; ++i) + { + unsigned char temp0 = src[2 * i + 0]; + unsigned char temp1 = src[2 * i + 1]; + UINT pixel_data = temp1 << 8 | temp0; + + unsigned char blueComponent = (pixel_data & 31) << 3; + unsigned char greenComponent = ((pixel_data >> 5) & 31) << 3; + unsigned char redComponent = ((pixel_data >> 10) & 31) << 3; + + dst[4 * i + 2] = redComponent; + dst[4 * i + 1] = greenComponent; + dst[4 * i + 0] = blueComponent; + dst[4 * i + 3] = 255; + } +} + +static void Convert565to8888(unsigned char* dst, unsigned char* src, UINT realDataSize) +{ + for(UINT i = 0; i < realDataSize / 4; ++i) + { + unsigned char temp0 = src[2 * i + 0]; + unsigned char temp1 = src[2 * i + 1]; + UINT pixel_data = temp1 << 8 | temp0; + + unsigned char redComponent = (pixel_data & 31) << 3; + unsigned char greenComponent = ((pixel_data >> 5) & 63) << 2; + unsigned char blueComponent = ((pixel_data >> 11) & 31) << 3; + + dst[4 * i + 2] = redComponent; + dst[4 * i + 1] = greenComponent; + dst[4 * i + 0] = blueComponent; + dst[4 * i + 3] = 255; + } +} + +static void Convert1555to8888(unsigned char* dst, unsigned char* src, UINT realDataSize) +{ + for(UINT i = 0; i < realDataSize / 4; ++i) + { + unsigned char temp0 = src[2 * i + 0]; + unsigned char temp1 = src[2 * i + 1]; + UINT pixel_data = temp1 << 8 | temp0; + + unsigned char redComponent = (pixel_data & 31) << 3; + unsigned char greenComponent = ((pixel_data >> 5) & 31) << 3; + unsigned char blueComponent = ((pixel_data >> 10) & 31) << 3; + unsigned char alphaComponent = (pixel_data >> 15) * 0xFF; + + dst[4 * i + 2] = redComponent; + dst[4 * i + 1] = greenComponent; + dst[4 * i + 0] = blueComponent; + dst[4 * i + 3] = alphaComponent; + } +} + +static void Convert4444to8888(unsigned char* dst, unsigned char* src, UINT realDataSize) +{ + for(UINT i = 0; i < realDataSize / 4; ++i) + { + unsigned char temp0 = src[2 * i + 0]; + unsigned char temp1 = src[2 * i + 1]; + UINT pixel_data = temp1 << 8 | temp0; + + unsigned char redComponent = (pixel_data & 15) << 4; + unsigned char greenComponent = ((pixel_data >> 4) & 15) << 4; + unsigned char blueComponent = ((pixel_data >> 8) & 15) << 4; + unsigned char alphaComponent = ((pixel_data >> 12) & 15) << 4; + + dst[4 * i + 2] = redComponent; + dst[4 * i + 1] = greenComponent; + dst[4 * i + 0] = blueComponent; + dst[4 * i + 3] = alphaComponent; + } +} + +static void ConvertRGBAtoBGRA(unsigned char* dst, unsigned char* src, UINT realDataSize) +{ + __m128i mask = _mm_setr_epi8(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0); + INT textureDataSize = static_cast(realDataSize) - 32; + INT i = 0; + for(; i <= textureDataSize; i += 32) + { + __m128i data0 = _mm_loadu_si128(reinterpret_cast(&src[i])); + __m128i data1 = _mm_loadu_si128(reinterpret_cast(&src[i + 16])); + __m128i gaComponents0 = _mm_andnot_si128(mask, data0); + __m128i brComponents0 = _mm_and_si128(data0, mask); + __m128i gaComponents1 = _mm_andnot_si128(mask, data1); + __m128i brComponents1 = _mm_and_si128(data1, mask); + __m128i brSwapped0 = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents0, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); + __m128i brSwapped1 = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents1, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&dst[i]), _mm_or_si128(gaComponents0, brSwapped0)); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&dst[i + 16]), _mm_or_si128(gaComponents1, brSwapped1)); + } + textureDataSize += 32; + for(; i < textureDataSize; i += 4) + { + unsigned char R = src[i + 0]; + unsigned char G = src[i + 1]; + unsigned char B = src[i + 2]; + unsigned char A = src[i + 2]; + dst[i + 0] = B; + dst[i + 1] = G; + dst[i + 2] = R; + dst[i + 3] = A; + } +} diff --git a/D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp b/D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp index 04fc18a0..95be0f74 100644 --- a/D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp +++ b/D3D11Engine/D3D7/FakeDirectDrawSurface7.cpp @@ -3,6 +3,7 @@ #include "../D3D11Texture.h" #include "../Engine.h" #include "../GothicAPI.h" +#include "Conversions.h" FakeDirectDrawSurface7::FakeDirectDrawSurface7() { RefCount = 0; @@ -169,11 +170,23 @@ HRESULT FakeDirectDrawSurface7::Lock( LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSu DebugWrite( "FakeDirectDrawSurface7(%p)::Lock(%s, %s)" ); *lpDDSurfaceDesc = OriginalDesc; + // Check for 16-bit surface. We allocate the texture as 32-bit, so we need to divide the size by two for that + int redBits = Toolbox::GetNumberOfBits( OriginalDesc.ddpfPixelFormat.dwRBitMask ); + int greenBits = Toolbox::GetNumberOfBits( OriginalDesc.ddpfPixelFormat.dwGBitMask ); + int blueBits = Toolbox::GetNumberOfBits( OriginalDesc.ddpfPixelFormat.dwBBitMask ); + int alphaBits = Toolbox::GetNumberOfBits( OriginalDesc.ddpfPixelFormat.dwRGBAlphaBitMask ); + + int bpp = redBits + greenBits + blueBits + alphaBits; + int divisor = 1; + + if ( bpp == 16 ) + divisor = 2; + // Allocate some temporary data delete [] Data; - Data = new unsigned char[Resource->GetEngineTexture()->GetSizeInBytes( MipLevel )]; + Data = new unsigned char[Resource->GetEngineTexture()->GetSizeInBytes( MipLevel ) / divisor]; lpDDSurfaceDesc->lpSurface = Data; - lpDDSurfaceDesc->lPitch = Resource->GetEngineTexture()->GetRowPitchBytes( MipLevel ); + lpDDSurfaceDesc->lPitch = Resource->GetEngineTexture()->GetRowPitchBytes( MipLevel ) / divisor; int px = (OriginalDesc.dwWidth >> MipLevel); int py = (OriginalDesc.dwHeight >> MipLevel); diff --git a/D3D11Engine/D3D7/MyDirectDraw.h b/D3D11Engine/D3D7/MyDirectDraw.h index 2a3257c0..40fb176b 100644 --- a/D3D11Engine/D3D7/MyDirectDraw.h +++ b/D3D11Engine/D3D7/MyDirectDraw.h @@ -160,6 +160,22 @@ class MyDirectDraw : public IDirectDraw7 { lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask = 0x000000FF; } + // Check potential texture conversions + if ( lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBBitCount == 16 ) { + if ( lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask == 0x7C00 + && lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask == 0x3E0 + && lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask == 0x1F + && lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBAlphaBitMask == 0x8000 ) + lpDDSurfaceDesc2->ddpfPixelFormat.dwFourCC = 1; + else if ( lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask == 0xF00 + && lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask == 0xF0 + && lpDDSurfaceDesc2->ddpfPixelFormat.dwBBitMask == 0x0F + && lpDDSurfaceDesc2->ddpfPixelFormat.dwRGBAlphaBitMask == 0xF000 ) + lpDDSurfaceDesc2->ddpfPixelFormat.dwFourCC = 2; + else + lpDDSurfaceDesc2->ddpfPixelFormat.dwFourCC = 0; + } + // Calculate bpp int redBits = Toolbox::GetNumberOfBits( lpDDSurfaceDesc2->ddpfPixelFormat.dwRBitMask ); int greenBits = Toolbox::GetNumberOfBits( lpDDSurfaceDesc2->ddpfPixelFormat.dwGBitMask ); diff --git a/D3D11Engine/D3D7/MyDirectDrawSurface7.cpp b/D3D11Engine/D3D7/MyDirectDrawSurface7.cpp index 0f02f635..fe076c76 100644 --- a/D3D11Engine/D3D7/MyDirectDrawSurface7.cpp +++ b/D3D11Engine/D3D7/MyDirectDrawSurface7.cpp @@ -4,6 +4,7 @@ #include "../D3D11GraphicsEngineBase.h" #include "../D3D11Texture.h" #include "../zCTexture.h" +#include "Conversions.h" #define DebugWriteTex(x) DebugWrite(x) @@ -404,21 +405,12 @@ HRESULT MyDirectDrawSurface7::Unlock( LPRECT lpRect ) { if ( bpp == 16 ) { // Convert - unsigned char* dst = new unsigned char[EngineTexture->GetSizeInBytes( 0 )]; - for ( unsigned int i = 0; i < EngineTexture->GetSizeInBytes( 0 ) / 4; i++ ) { - unsigned char temp0 = LockedData[i * 2 + 0]; - unsigned char temp1 = LockedData[i * 2 + 1]; - unsigned pixel_data = temp1 << 8 | temp0; - - unsigned char blueComponent = (pixel_data & 0x1F); - unsigned char greenComponent = (pixel_data >> 6) & 0x1F; - unsigned char redComponent = (pixel_data >> 11) & 0x1F; - - // Extract red, green and blue components from the 16 bits - dst[4 * i + 0] = static_cast((redComponent / 32.0) * 255.0f); - dst[4 * i + 1] = static_cast((greenComponent / 32.0) * 255.0f); - dst[4 * i + 2] = static_cast((blueComponent / 32.0) * 255.0f); - dst[4 * i + 3] = 255; + UINT realDataSize = EngineTexture->GetSizeInBytes( 0 ); + unsigned char* dst = new unsigned char[realDataSize]; + switch ( OriginalSurfaceDesc.ddpfPixelFormat.dwFourCC ) { + case 1: Convert1555to8888( dst, LockedData, realDataSize ); break; + case 2: Convert4444to8888( dst, LockedData, realDataSize ); break; + default: Convert565to8888( dst, LockedData, realDataSize ); break; } if ( Engine::GAPI->GetMainThreadID() != GetCurrentThreadId() ) { From 4d162528578ee434f732934c3a4c8e03ff44eb4b Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Tue, 11 Oct 2022 02:02:57 +0200 Subject: [PATCH 5/6] Remove half-pixel offset from shaders Zengine DX7 renderer doesn't actually add the half-pixel offset to the rendering position so avoid removing it. --- D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl | 3 --- D3D11Engine/Shaders/VS_TransformedEx.hlsl | 3 --- D3D11Engine/Shaders/VS_XYZRHW_DIF_T1.hlsl | 3 --- 3 files changed, 9 deletions(-) diff --git a/D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl b/D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl index aba1ab88..8ee52cfd 100644 --- a/D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl +++ b/D3D11Engine/Shaders/VS_Lines_XYZRHW.hlsl @@ -34,9 +34,6 @@ float4 TransformXYZRHW(float4 xyzrhw) ndc.y = 1 - ((2 * (xyzrhw.y - V_ViewportPos.y)) / V_ViewportSize.y); ndc.z = xyzrhw.z; - // Remove the stupid half-pixel offset from pre D3D10 - ndc.xy -= 0.5f / V_ViewportSize; - // Convert to clip-space. rhw is actually 1/w ("reciprocal"). So to undo the devide by w, devide by the given 1/w. float actualW = 1.0f / xyzrhw.w; float3 clipSpace = ndc.xyz * actualW; diff --git a/D3D11Engine/Shaders/VS_TransformedEx.hlsl b/D3D11Engine/Shaders/VS_TransformedEx.hlsl index f6575d78..45a4f68e 100644 --- a/D3D11Engine/Shaders/VS_TransformedEx.hlsl +++ b/D3D11Engine/Shaders/VS_TransformedEx.hlsl @@ -43,9 +43,6 @@ float4 TransformXYZRHW(float4 xyzrhw) ndc.y = 1 - ((2 * (xyzrhw.y - V_ViewportPos.y)) / V_ViewportSize.y); ndc.z = xyzrhw.z; - // Remove the stupid half-pixel offset from pre D3D10 - ndc.xy -= 0.5f / V_ViewportSize; - // Convert to clip-space. rhw is actually 1/w ("reciprocal"). So to undo the devide by w, devide by the given 1/w. float actualW = 1.0f / xyzrhw.w; float3 clipSpace = ndc.xyz * actualW; diff --git a/D3D11Engine/Shaders/VS_XYZRHW_DIF_T1.hlsl b/D3D11Engine/Shaders/VS_XYZRHW_DIF_T1.hlsl index de21211b..d6116202 100644 --- a/D3D11Engine/Shaders/VS_XYZRHW_DIF_T1.hlsl +++ b/D3D11Engine/Shaders/VS_XYZRHW_DIF_T1.hlsl @@ -41,9 +41,6 @@ float4 TransformXYZRHW(float4 xyzrhw) ndc.y = 1 - ((2 * (xyzrhw.y - V_ViewportPos.y)) / V_ViewportSize.y); ndc.z = xyzrhw.z; - // Remove the stupid half-pixel offset from pre D3D10 - ndc.xy -= 0.5f / V_ViewportSize; - // Convert to clip-space. rhw is actually 1/w ("reciprocal"). So to undo the devide by w, devide by the given 1/w. float actualW = 1.0f / xyzrhw.w; float3 clipSpace = ndc.xyz * actualW; From 7d7116b1cfa0892517e1af686025d90c0501ed0c Mon Sep 17 00:00:00 2001 From: SaiyansKing <38609240+SaiyansKing@users.noreply.github.com> Date: Sat, 22 Oct 2022 21:23:17 +0200 Subject: [PATCH 6/6] Rewrite Animated_Inventory SystemPack option Rewrite Animated_Inventory SystemPack option to fix problems with fucked up items world matrixes that happens due to broken SystemPack code. --- D3D11Engine/D3D11GraphicsEngine.cpp | 15 ----------- D3D11Engine/GothicAPI.cpp | 3 +++ D3D11Engine/GothicMemoryLocations.h | 22 +++++++++++++++ D3D11Engine/HookedFunctions.cpp | 42 +++++++++++++++++++++++++++++ D3D11Engine/HookedFunctions.h | 5 ++++ 5 files changed, 72 insertions(+), 15 deletions(-) diff --git a/D3D11Engine/D3D11GraphicsEngine.cpp b/D3D11Engine/D3D11GraphicsEngine.cpp index 0a865478..ff9acbd2 100644 --- a/D3D11Engine/D3D11GraphicsEngine.cpp +++ b/D3D11Engine/D3D11GraphicsEngine.cpp @@ -5196,21 +5196,6 @@ D3D11ENGINE_RENDER_STAGE D3D11GraphicsEngine::GetRenderingStage() { /** Draws a VOB (used for inventory) */ void D3D11GraphicsEngine::DrawVobSingle( VobInfo* vob, zCCamera& camera ) { -#if defined(BUILD_GOTHIC_1_08k) && !defined(BUILD_1_12F) - // System Pack Animated_Inventory workaround - XMMATRIX worldMatrix = vob->Vob->GetWorldMatrixXM(); - const uint32_t mask = _mm_movemask_epi8( _mm_packs_epi32( - _mm_castps_si128( _mm_cmpord_ps( worldMatrix.r[0], worldMatrix.r[1] ) ), - _mm_castps_si128( _mm_cmpord_ps( worldMatrix.r[2], worldMatrix.r[3] ) ) - ) ); - if ( mask != 0xFFFF ) { // Check whether there are any NAN's in the mask - // Sometimes items position doesn't get initialized properly - // let's just call RotateForInventory to restart them - reinterpret_cast( 0x672560 )( vob->Vob, 0, 1 ); - return; - } -#endif - Engine::GAPI->SetViewTransformXM( XMLoadFloat4x4( &camera.GetTransformDX( zCCamera::ETransformType::TT_VIEW ) ) ); GetContext()->OMSetRenderTargets( 1, HDRBackBuffer->GetRenderTargetView().GetAddressOf(), DepthStencilBuffer->GetDepthStencilView().Get() ); diff --git a/D3D11Engine/GothicAPI.cpp b/D3D11Engine/GothicAPI.cpp index 5dcefa83..4f5edc4e 100644 --- a/D3D11Engine/GothicAPI.cpp +++ b/D3D11Engine/GothicAPI.cpp @@ -231,6 +231,9 @@ void GothicAPI::OnGameStart() { UpdateMTResourceManager(); +#if defined(BUILD_GOTHIC_1_08k) && !defined(BUILD_1_12F) + HookedFunctions::OriginalFunctions.InitAnimatedInventoryHooks(); +#endif void RegisterBinkPlayerHooks(); RegisterBinkPlayerHooks(); } diff --git a/D3D11Engine/GothicMemoryLocations.h b/D3D11Engine/GothicMemoryLocations.h index 95702018..1b04df54 100644 --- a/D3D11Engine/GothicMemoryLocations.h +++ b/D3D11Engine/GothicMemoryLocations.h @@ -27,6 +27,28 @@ static void PatchAddr( unsigned int adr, const T( &v )[n] ) { } } +static void PatchCall( unsigned int adr, unsigned int func ) { + DWORD dwOldProtect, dwNewProtect, dwNewCall; + dwNewCall = func - adr - 5; + if ( VirtualProtect( reinterpret_cast(adr), 5, PAGE_EXECUTE_READWRITE, &dwOldProtect ) ) { + *reinterpret_cast(adr) = 0xE8; + *reinterpret_cast(adr + 1) = dwNewCall; + VirtualProtect( reinterpret_cast(adr), 5, dwOldProtect, &dwNewProtect ); + FlushInstructionCache( GetCurrentProcess(), reinterpret_cast(adr), 5 ); + } +} + +static void PatchJMP( unsigned int adr, unsigned int jmp ) { + DWORD dwOldProtect, dwNewProtect, dwNewCall; + dwNewCall = jmp - adr - 5; + if ( VirtualProtect( reinterpret_cast(adr), 5, PAGE_EXECUTE_READWRITE, &dwOldProtect ) ) { + *reinterpret_cast(adr) = 0xE9; + *reinterpret_cast(adr + 1) = dwNewCall; + VirtualProtect( reinterpret_cast(adr), 5, dwOldProtect, &dwNewProtect ); + FlushInstructionCache( GetCurrentProcess(), reinterpret_cast(adr), 5 ); + } +} + #define INST_NOP 0x90 #define REPLACE_OP(addr, op) {unsigned char* a = (unsigned char*)addr; *a = op;} #define REPLACE_RANGE(start, end_incl, op) {for(int i=start; i<=end_incl;i++){REPLACE_OP(i, op);}} diff --git a/D3D11Engine/HookedFunctions.cpp b/D3D11Engine/HookedFunctions.cpp index 2c672b9c..56c9dfb3 100644 --- a/D3D11Engine/HookedFunctions.cpp +++ b/D3D11Engine/HookedFunctions.cpp @@ -417,3 +417,45 @@ FARPROC WINAPI HookedFunctionInfo::hooked_GetProcAddress( HMODULE mod, const cha } return GetProcAddress( mod, procName ); } + +#if defined(BUILD_GOTHIC_1_08k) && !defined(BUILD_1_12F) +void HookedFunctionInfo::InitAnimatedInventoryHooks() { + if ( *reinterpret_cast(0x67303D) != 0xD8 ) { + // Remove Animated_Inventory SystemPack memory jump and insert our function instead that doesn't fuckup items world matrix + PatchAddr( 0x67303D, "\xD8\x1D\xA4\x08\x7D\x00" ); + DWORD FixAnimation = reinterpret_cast(VirtualAlloc( nullptr, 32, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE )); + if ( FixAnimation ) { + PatchAddr( FixAnimation, "\x8B\xCF\xE8\x00\x00\x00\x00\xE9\x00\x00\x00\x00\x6A\x01\x8B\xCF\xE8\x00\x00\x00\x00\xE9\x00\x00\x00\x00" ); + PatchCall( FixAnimation + 2, reinterpret_cast(&HookedFunctionInfo::hooked_RotateInInventory) ); + PatchCall( FixAnimation + 16, 0x672560 ); + PatchJMP( FixAnimation + 7, 0x673053 ); + PatchJMP( FixAnimation + 21, 0x673053 ); + PatchJMP( 0x673049, FixAnimation ); + PatchJMP( 0x67304E, FixAnimation + 12 ); + PatchAddr( 0x673048, "\x0F\x8A" ); + } + } +} + +void __fastcall HookedFunctionInfo::hooked_RotateInInventory( DWORD oCItem ) { + // Call RotateForInventory to reset world matrix + reinterpret_cast( 0x672560 )( oCItem, 1 ); + + float rotAxis[3] = { 0.f, 0.f, 0.f }; + float* bbox3d = reinterpret_cast(oCItem + 0x7C); + + float val = -1.f; + int index = 0; + for ( int i = 0; i < 3; ++i ) { + float v = (bbox3d[i + 3] - bbox3d[i]); + if ( v > val ) { + val = v; + index = i; + } + } + rotAxis[index] = 1.f; + + // Call RotateLocal to rotate item world matrix + reinterpret_cast( 0x5EE100 )( oCItem, rotAxis, 20.f * (*reinterpret_cast(0x8CF1F0) / 1000.f) ); +} +#endif diff --git a/D3D11Engine/HookedFunctions.h b/D3D11Engine/HookedFunctions.h index c13683be..e433ee96 100644 --- a/D3D11Engine/HookedFunctions.h +++ b/D3D11Engine/HookedFunctions.h @@ -173,6 +173,11 @@ struct HookedFunctionInfo { static void __fastcall hooked_SetLightmap( void* polygonPtr ); static FARPROC WINAPI hooked_GetProcAddress( HMODULE mod, const char* procName ); + +#if defined(BUILD_GOTHIC_1_08k) && !defined(BUILD_1_12F) + void InitAnimatedInventoryHooks(); + static void __fastcall hooked_RotateInInventory( DWORD oCItem ); +#endif }; namespace HookedFunctions {