From 53cbce83a2b43c961e81ad320c5689a3e0a2d333 Mon Sep 17 00:00:00 2001 From: rebtd7 <59185507+rebtd7@users.noreply.github.com> Date: Tue, 16 Mar 2021 11:16:55 -0300 Subject: [PATCH] Fix misaligned full screen effects (proper fix for 1440p issue) --- d3d9ex/AutoFix.cpp | 54 ++++++++++++++++++++++--------------- d3d9ex/Context.h | 20 +++++++++++++- d3d9ex/IDirect3DDevice9.cpp | 4 +-- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/d3d9ex/AutoFix.cpp b/d3d9ex/AutoFix.cpp index d2ae0ef..f0f00c7 100644 --- a/d3d9ex/AutoFix.cpp +++ b/d3d9ex/AutoFix.cpp @@ -87,28 +87,6 @@ HRESULT MainContext::SetScissorRect(IDirect3DDevice9* pIDirect3DDevice9, CONST R return pIDirect3DDevice9->SetScissorRect(rect); } -HRESULT MainContext::SetViewport(IDirect3DDevice9* pIDirect3DDevice9, CONST D3DVIEWPORT9* pViewport) -{ - // DXVK fixes this better - if(IsDXVK()) - return pIDirect3DDevice9->SetViewport(pViewport); - - if (pViewport) - { - D3DVIEWPORT9* vp = const_cast(pViewport); - if (pViewport->Width > 1920 && pViewport->Height > 1080) - { - vp->Width--; - vp->X++; - - vp->Height--; - vp->Y++; - return pIDirect3DDevice9->SetViewport(vp); - } - } - return pIDirect3DDevice9->SetViewport(pViewport); -} - // hate this workaround but we cant directly mix d3d9 include with and without defined CINTERFACE namespace cinterface { void VertexBufferFix(IDirect3DVertexBuffer9* pVertexBuffer); @@ -136,6 +114,25 @@ HRESULT MainContext::CreateVertexBuffer(IDirect3DDevice9* pIDirect3DDevice9, UIN return pIDirect3DDevice9->CreateVertexBuffer(Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle); } +HRESULT MainContext::DrawPrimitiveUP(IDirect3DDevice9* pIDirect3DDevice9, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride) +{ + if (PrimitiveType == D3DPT_TRIANGLEFAN && PrimitiveCount == 2 && VertexStreamZeroStride == 20 && MatchesExpectedVertexStream((const float*)pVertexStreamZeroData)) { + return pIDirect3DDevice9->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, fixedDrawPrimitiveUpVertexData, VertexStreamZeroStride); + } + else { + return pIDirect3DDevice9->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + } +} + +bool MainContext::MatchesExpectedVertexStream(const float* pVertexStreamZeroData) { + for (int i = 0; i < 4 * 5; i++) { + if (fabs(expectedDrawPrimitiveUpVertexData[i] - pVertexStreamZeroData[i]) > 0.000001f) { + return false; + } + } + return true; +} + bool MainContext::OneTimeFixInit(std::unique_ptr& className, HWND hWnd) { if (wcscmp(className.get(), L"SQEX.CDev.Engine.Framework.MainWindow") == 0) { @@ -212,6 +209,7 @@ void MainContext::FF13_OneTimeFixes() { FF13_FixScissorRect(); FF13_EnableControllerVibration(); FF13_SetFrameRateVariables(); + AdjustVertexData(*ff13_internal_res_w, *ff13_internal_res_h); PrintLog("Finished FF13 One Time Fixes"); } @@ -321,6 +319,7 @@ void MainContext::FF13_2_OneTimeFixes() FF13_2_AddHookIngameFrameRateLimitSetter(); FF13_2_RemoveContinuousControllerScan(); FF13_2_EnableControllerVibration(); + AdjustVertexData(*ff13_2_internal_res_w, *ff13_2_internal_res_h); PrintLog("Finished FF13-2 One Time Fixes"); } else { @@ -342,6 +341,17 @@ void MainContext::FF13_2_EnableControllerVibration() xinputManager = new XInputManager(ff13_2_base_controller_input_address_ptr, config.GetFFXIIIVibrationStrengthFactor()); } +void MainContext::AdjustVertexData(const uint32_t width, const uint32_t height) +{ + const float widthHalfPixelSize = 1.0f / width; + const float heightHalfPixelSize = 1.0f / height; + for (int i = 0; i < 4; i++) { + const unsigned int rowBaseIndex = i * 5; + context.fixedDrawPrimitiveUpVertexData[rowBaseIndex] -= widthHalfPixelSize; + context.fixedDrawPrimitiveUpVertexData[1 + rowBaseIndex] += heightHalfPixelSize; + } +} + void MainContext::FF13_2_InitializeGameAddresses() { // FF13-2 uses address space layout randomization (ASLR) so we can't rely on fixed addresses without considering the base address diff --git a/d3d9ex/Context.h b/d3d9ex/Context.h index 5f84a54..40978d5 100644 --- a/d3d9ex/Context.h +++ b/d3d9ex/Context.h @@ -49,7 +49,7 @@ public: void ApplyBehaviorFlagsFix(DWORD* flags); HRESULT SetScissorRect(IDirect3DDevice9* pIDirect3DDevice9, CONST RECT* rect); HRESULT CreateVertexBuffer(IDirect3DDevice9* pIDirect3DDevice9, UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle); - HRESULT SetViewport(IDirect3DDevice9* pIDirect3DDevice9, CONST D3DVIEWPORT9* pViewport); + HRESULT DrawPrimitiveUP(IDirect3DDevice9* pIDirect3DDevice9, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride); bool BehaviorFlagsToString(DWORD BehaviorFlags, std::string* BehaviorFlagsString); bool CheckWindow(HWND hWnd); @@ -107,6 +107,20 @@ private: uint32_t* ff13_2_internal_res_w; uint32_t* ff13_2_internal_res_h; + float expectedDrawPrimitiveUpVertexData[5 * 4] + { -1.00f - 1.0f / 1280.0f, 1.00f + 1.0f / 720.0f, 0.0f, 0.0f, 0.0f, + 1.00f - 1.0f / 1280.0f, 1.00f + 1.0f / 720.0f, 0.0f, 1.0f, 0.0f, + 1.00f - 1.0f / 1280.0f, -1.00f + 1.0f / 720.0f, 0.0f, 1.0f, 1.0f, + -1.00f - 1.0f / 1280.0f, -1.00f + 1.0f / 720.0f, 0.0f, 0.0f, 1.0f + }; + + float fixedDrawPrimitiveUpVertexData[5 * 4] + { -1.00f, 1.00f, 0.0f, 0.0f, 0.0f, + 1.00f, 1.00f, 0.0f, 1.0f, 0.0f, + 1.00f, -1.00f, 0.0f, 1.0f, 1.0f, + -1.00f, -1.00f, 0.0f, 0.0f, 1.0f + }; + const float FF13_2_30_FPS = 30.0F; const float FF13_2_MAX_FRAME_CAP = 1000.0F; @@ -139,6 +153,10 @@ private: void FF13_2_OneTimeFixes(); void FF13_2_EnableControllerVibration(); + void AdjustVertexData(const uint32_t width, const uint32_t height); + + bool MatchesExpectedVertexStream(const float* pVertexStreamZeroData); + bool OneTimeFixInit(std::unique_ptr& className, HWND hWnd); std::atomic_bool otf_init = false; diff --git a/d3d9ex/IDirect3DDevice9.cpp b/d3d9ex/IDirect3DDevice9.cpp index 5d4bae7..9c65c02 100644 --- a/d3d9ex/IDirect3DDevice9.cpp +++ b/d3d9ex/IDirect3DDevice9.cpp @@ -261,7 +261,7 @@ HRESULT APIENTRY hkIDirect3DDevice9::MultiplyTransform(D3DTRANSFORMSTATETYPE Sta HRESULT APIENTRY hkIDirect3DDevice9::SetViewport(CONST D3DVIEWPORT9* pViewport) { IDirect3DDevice9_PrintLog(__FUNCTION__); - return context.SetViewport(m_pWrapped, pViewport); + return m_pWrapped->SetViewport(pViewport); } HRESULT APIENTRY hkIDirect3DDevice9::GetViewport(D3DVIEWPORT9* pViewport) { @@ -441,7 +441,7 @@ HRESULT APIENTRY hkIDirect3DDevice9::DrawIndexedPrimitive(D3DPRIMITIVETYPE Primi HRESULT APIENTRY hkIDirect3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) { IDirect3DDevice9_PrintLog(__FUNCTION__); - return m_pWrapped->DrawPrimitiveUP(PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); + return context.DrawPrimitiveUP(m_pWrapped, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride); } HRESULT APIENTRY hkIDirect3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {