From c54c45a7736601c925c10d3f7bdd7ce3604a9ee9 Mon Sep 17 00:00:00 2001 From: narzoul Date: Sat, 20 Apr 2024 10:56:19 +0200 Subject: [PATCH] Fixed flashing screen in Glover See issue #295. --- DDrawCompat/D3dDdi/Resource.cpp | 11 ++++------- DDrawCompat/DDraw/DirectDrawSurface.cpp | 1 + DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp | 15 +++++++++++++++ DDrawCompat/DDraw/Surfaces/PrimarySurface.h | 1 + .../DDraw/Surfaces/PrimarySurfaceImpl.cpp | 16 ++++++++++++++++ DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h | 1 + DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp | 6 ++++++ DDrawCompat/DDraw/Surfaces/SurfaceImpl.h | 1 + 8 files changed, 45 insertions(+), 7 deletions(-) diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index 88c3411..53c7058 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -1274,8 +1274,7 @@ namespace D3dDdi m_device.flushPrimitives(); if (srcResource->m_lockResource) { - if (srcResource->m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate && - !srcResource->m_origData.Flags.RenderTarget) + if (srcResource->m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate) { srcResource->m_lockData[data.SrcSubResourceIndex].isVidMemUpToDate = false; srcResource->m_lockData[data.SrcSubResourceIndex].isMsaaResolvedUpToDate = false; @@ -1488,11 +1487,9 @@ namespace D3dDdi void Resource::setAsPrimary() { D3dDdi::ScopedCriticalSection lock; - if (!m_isPrimary) - { - m_isPrimary = true; - updateConfig(); - } + m_isPrimary = true; + m_origData.Flags.RenderTarget = DDraw::PrimarySurface::getOrigCaps() & DDSCAPS_3DDEVICE ? 1 : 0; + updateConfig(); } void Resource::setFormatOverride(D3DDDIFORMAT format) diff --git a/DDrawCompat/DDraw/DirectDrawSurface.cpp b/DDrawCompat/DDraw/DirectDrawSurface.cpp index 58301ad..e332e10 100644 --- a/DDrawCompat/DDraw/DirectDrawSurface.cpp +++ b/DDrawCompat/DDraw/DirectDrawSurface.cpp @@ -59,6 +59,7 @@ namespace constexpr void setCompatVtable(Vtable& vtable) { typedef GetSurfaceType::Type TSurface; + SET_COMPAT_METHOD(AddAttachedSurface); SET_COMPAT_METHOD(Blt); SET_COMPAT_METHOD(BltFast); SET_COMPAT_METHOD(Flip); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp index 5d9ffee..b5f71f0 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -84,6 +84,11 @@ namespace DDraw desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; desc.ddpfPixelFormat = DirectDraw::getRgbPixelFormat(g_monitorInfo.bpp); + if (!(desc.dwFlags & DDSD_BACKBUFFERCOUNT)) + { + desc.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE; + } + result = Surface::create(dd, desc, surface, std::move(privateData)); if (FAILED(result)) { @@ -277,6 +282,16 @@ namespace DDraw Surface::restore(); } + void PrimarySurface::setAsRenderTarget() + { + g_origCaps |= DDSCAPS_3DDEVICE; + auto resource = D3dDdi::Device::findResource(DDraw::DirectDrawSurface::getDriverResourceHandle(*g_primarySurface)); + if (resource) + { + resource->setAsPrimary(); + } + } + void PrimarySurface::updateFrontResource() { g_frontResource = DirectDrawSurface::getDriverResourceHandle(*g_primarySurface); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h index 80472ce..5809af1 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h @@ -28,6 +28,7 @@ namespace DDraw static HANDLE getGdiResource(); static DWORD getOrigCaps(); static void onLost(); + static void setAsRenderTarget(); static void updatePalette(); template diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp index 8a889b7..eb74025 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp @@ -84,6 +84,22 @@ namespace DDraw { } + template + HRESULT PrimarySurfaceImpl::AddAttachedSurface(TSurface* This, TSurface* lpDDSAttachedSurface) + { + HRESULT result = getOrigVtable(This).AddAttachedSurface(This, lpDDSAttachedSurface); + if (SUCCEEDED(result) && !(PrimarySurface::getOrigCaps() & DDSCAPS_3DDEVICE)) + { + TDdsCaps caps = {}; + getOrigVtable(This).GetCaps(lpDDSAttachedSurface, &caps); + if (caps.dwCaps & DDSCAPS_3DDEVICE) + { + PrimarySurface::setAsRenderTarget(); + } + } + return result; + } + template HRESULT PrimarySurfaceImpl::Blt( TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h index 9ea2b86..d8f7f3d 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h @@ -15,6 +15,7 @@ namespace DDraw public: PrimarySurfaceImpl(Surface* data); + virtual HRESULT AddAttachedSurface(TSurface* This, TSurface* lpDDSAttachedSurface) override; virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) override; virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY, diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp index 768c327..febcdfc 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp @@ -122,6 +122,12 @@ namespace DDraw { } + template + HRESULT SurfaceImpl::AddAttachedSurface(TSurface* This, TSurface* lpDDSAttachedSurface) + { + return getOrigVtable(This).AddAttachedSurface(This, lpDDSAttachedSurface); + } + template HRESULT SurfaceImpl::Blt( TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h index e921896..236e755 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h @@ -24,6 +24,7 @@ namespace DDraw SurfaceImpl(Surface* data); virtual ~SurfaceImpl(); + virtual HRESULT AddAttachedSurface(TSurface* This, TSurface* lpDDSAttachedSurface); virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx); virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY,