From 6396b7420d5382ef9bc54da756315e5cf5814e34 Mon Sep 17 00:00:00 2001 From: narzoul Date: Wed, 7 Apr 2021 20:04:52 +0200 Subject: [PATCH] Fixed palette issues in Deer Hunter 2 --- DDrawCompat/DDraw/DirectDraw.cpp | 21 +++++++++++- DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp | 7 +--- DDrawCompat/DDraw/Surfaces/PrimarySurface.h | 1 + DDrawCompat/DDraw/Surfaces/Surface.cpp | 15 ++++++-- DDrawCompat/DDraw/Surfaces/Surface.h | 3 +- DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp | 34 +++++++++++++++---- DDrawCompat/DDraw/Surfaces/SurfaceImpl.h | 2 ++ 7 files changed, 66 insertions(+), 17 deletions(-) diff --git a/DDrawCompat/DDraw/DirectDraw.cpp b/DDrawCompat/DDraw/DirectDraw.cpp index 9b09a4e..4394a83 100644 --- a/DDrawCompat/DDraw/DirectDraw.cpp +++ b/DDrawCompat/DDraw/DirectDraw.cpp @@ -1,7 +1,10 @@ +#include + #include #include #include #include +#include #include #include #include @@ -29,7 +32,7 @@ namespace else { return DDraw::Surface::create( - *This, *lpDDSurfaceDesc, *lplpDDSurface, std::make_unique()); + *This, *lpDDSurfaceDesc, *lplpDDSurface, std::make_unique(lpDDSurfaceDesc->ddsCaps.dwCaps)); } } @@ -65,6 +68,17 @@ namespace return getOrigVtable(This).Initialize(This, lpGUID); } + template + HRESULT STDMETHODCALLTYPE RestoreAllSurfaces(TDirectDraw* This) + { + auto primary(DDraw::PrimarySurface::getPrimary()); + if (primary) + { + primary.get()->lpVtbl->Restore(primary); + } + return getOrigVtable(This).RestoreAllSurfaces(This); + } + template HRESULT STDMETHODCALLTYPE WaitForVerticalBlank(TDirectDraw* This, DWORD dwFlags, HANDLE hEvent) { @@ -95,6 +109,11 @@ namespace vtable.GetGDISurface = &GetGDISurface; vtable.Initialize = &Initialize; vtable.WaitForVerticalBlank = &WaitForVerticalBlank; + + if constexpr (std::is_same_v || std::is_same_v) + { + vtable.RestoreAllSurfaces = &RestoreAllSurfaces; + } } } diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp index f1547d0..c0bd07d 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -61,13 +61,8 @@ namespace DDraw DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM); desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; desc.ddpfPixelFormat = dm.ddpfPixelFormat; - if (desc.ddpfPixelFormat.dwRGBBitCount <= 8 && (desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) - { - desc.ddsCaps.dwCaps &= ~DDSCAPS_3DDEVICE; - desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - } - auto privateData(std::make_unique()); + auto privateData(std::make_unique(origCaps)); auto data = privateData.get(); result = Surface::create(dd, desc, surface, std::move(privateData)); if (FAILED(result)) diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h index b2b158f..09dd937 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h @@ -11,6 +11,7 @@ namespace DDraw class PrimarySurface : public Surface { public: + PrimarySurface(DWORD origCaps) : Surface(origCaps) {} virtual ~PrimarySurface(); template diff --git a/DDrawCompat/DDraw/Surfaces/Surface.cpp b/DDrawCompat/DDraw/Surfaces/Surface.cpp index 59ba362..ced596a 100644 --- a/DDrawCompat/DDraw/Surfaces/Surface.cpp +++ b/DDrawCompat/DDraw/Surfaces/Surface.cpp @@ -6,6 +6,7 @@ #include #include #include +#include // {C62D8849-DFAC-4454-A1E8-DA67446426BA} DEFINE_GUID(IID_CompatSurfacePrivateData, @@ -33,8 +34,9 @@ namespace DDraw return refCount; } - Surface::Surface() - : m_refCount(0) + Surface::Surface(DWORD origCaps) + : m_origCaps(origCaps) + , m_refCount(0) , m_sizeOverride{} { } @@ -58,6 +60,13 @@ namespace DDraw HRESULT Surface::create( CompatRef dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr privateData) { + if ((desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && + ((desc.dwFlags & DDSD_PIXELFORMAT) && (desc.ddpfPixelFormat.dwRGBBitCount <= 8)) || + (!(desc.dwFlags & DDSD_PIXELFORMAT) && Win32::DisplayMode::getBpp() <= 8)) + { + desc.ddsCaps.dwCaps &= ~DDSCAPS_3DDEVICE; + } + HRESULT result = dd->CreateSurface(&dd, &desc, &surface, nullptr); if (FAILED(result)) { @@ -70,7 +79,7 @@ namespace DDraw auto attachedSurfaces(DirectDrawSurface::getAllAttachedSurfaces(*surface7)); for (DWORD i = 0; i < attachedSurfaces.size(); ++i) { - attach(*attachedSurfaces[i], std::make_unique()); + attach(*attachedSurfaces[i], std::make_unique(privateData->m_origCaps)); } } diff --git a/DDrawCompat/DDraw/Surfaces/Surface.h b/DDrawCompat/DDraw/Surfaces/Surface.h index 505026e..d27985c 100644 --- a/DDrawCompat/DDraw/Surfaces/Surface.h +++ b/DDrawCompat/DDraw/Surfaces/Surface.h @@ -20,7 +20,7 @@ namespace DDraw virtual ULONG STDMETHODCALLTYPE AddRef(); virtual ULONG STDMETHODCALLTYPE Release(); - Surface(); + Surface(DWORD origCaps); virtual ~Surface(); template @@ -54,6 +54,7 @@ namespace DDraw template friend class SurfaceImpl; + DWORD m_origCaps; DWORD m_refCount; SIZE m_sizeOverride; }; diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp index 220dcff..7ef778e 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp @@ -79,7 +79,12 @@ namespace DDraw template HRESULT SurfaceImpl::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps) { - return getOrigVtable(This).GetCaps(This, lpDDSCaps); + HRESULT result = getOrigVtable(This).GetCaps(This, lpDDSCaps); + if (SUCCEEDED(result)) + { + restoreOrigCaps(lpDDSCaps->dwCaps); + } + return result; } template @@ -113,11 +118,15 @@ namespace DDraw HRESULT SurfaceImpl::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc) { HRESULT result = getOrigVtable(This).GetSurfaceDesc(This, lpDDSurfaceDesc); - if (SUCCEEDED(result) && 0 != m_data->m_sizeOverride.cx) + if (SUCCEEDED(result)) { - lpDDSurfaceDesc->dwWidth = m_data->m_sizeOverride.cx; - lpDDSurfaceDesc->dwHeight = m_data->m_sizeOverride.cy; - m_data->m_sizeOverride = {}; + if (0 != m_data->m_sizeOverride.cx) + { + lpDDSurfaceDesc->dwWidth = m_data->m_sizeOverride.cx; + lpDDSurfaceDesc->dwHeight = m_data->m_sizeOverride.cy; + m_data->m_sizeOverride = {}; + } + restoreOrigCaps(lpDDSurfaceDesc->ddsCaps.dwCaps); } return result; } @@ -139,7 +148,11 @@ namespace DDraw } HRESULT result = getOrigVtable(This).Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent); - if (DDERR_SURFACELOST == result) + if (SUCCEEDED(result)) + { + restoreOrigCaps(lpDDSurfaceDesc->ddsCaps.dwCaps); + } + else if (DDERR_SURFACELOST == result) { TSurfaceDesc desc = {}; desc.dwSize = sizeof(desc); @@ -202,6 +215,15 @@ namespace DDraw return getOrigVtable(This).Unlock(This, lpRect); } + template + void SurfaceImpl::restoreOrigCaps(DWORD& caps) + { + if (m_data->m_origCaps & DDSCAPS_3DDEVICE) + { + caps |= DDSCAPS_3DDEVICE; + } + } + template bool SurfaceImpl::waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag) { diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h index 9d64c96..27125e4 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h @@ -45,6 +45,8 @@ namespace DDraw bool waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag); private: + void restoreOrigCaps(DWORD& caps); + Surface* m_data; }; }