1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Fixed palette issues in Deer Hunter 2

This commit is contained in:
narzoul 2021-04-07 20:04:52 +02:00
parent c2d882fd88
commit 6396b7420d
7 changed files with 66 additions and 17 deletions

View File

@ -1,7 +1,10 @@
#include <type_traits>
#include <Common/CompatPtr.h>
#include <Common/CompatVtable.h>
#include <D3dDdi/KernelModeThunks.h>
#include <DDraw/DirectDraw.h>
#include <DDraw/RealPrimarySurface.h>
#include <DDraw/ScopedThreadLock.h>
#include <DDraw/Surfaces/PrimarySurface.h>
#include <DDraw/Visitors/DirectDrawVtblVisitor.h>
@ -29,7 +32,7 @@ namespace
else
{
return DDraw::Surface::create<TDirectDraw>(
*This, *lpDDSurfaceDesc, *lplpDDSurface, std::make_unique<DDraw::Surface>());
*This, *lpDDSurfaceDesc, *lplpDDSurface, std::make_unique<DDraw::Surface>(lpDDSurfaceDesc->ddsCaps.dwCaps));
}
}
@ -65,6 +68,17 @@ namespace
return getOrigVtable(This).Initialize(This, lpGUID);
}
template <typename TDirectDraw>
HRESULT STDMETHODCALLTYPE RestoreAllSurfaces(TDirectDraw* This)
{
auto primary(DDraw::PrimarySurface::getPrimary());
if (primary)
{
primary.get()->lpVtbl->Restore(primary);
}
return getOrigVtable(This).RestoreAllSurfaces(This);
}
template <typename TDirectDraw>
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<Vtable, IDirectDraw4Vtbl> || std::is_same_v<Vtable, IDirectDraw7Vtbl>)
{
vtable.RestoreAllSurfaces = &RestoreAllSurfaces;
}
}
}

View File

@ -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<PrimarySurface>());
auto privateData(std::make_unique<PrimarySurface>(origCaps));
auto data = privateData.get();
result = Surface::create(dd, desc, surface, std::move(privateData));
if (FAILED(result))

View File

@ -11,6 +11,7 @@ namespace DDraw
class PrimarySurface : public Surface
{
public:
PrimarySurface(DWORD origCaps) : Surface(origCaps) {}
virtual ~PrimarySurface();
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>

View File

@ -6,6 +6,7 @@
#include <DDraw/DirectDrawSurface.h>
#include <DDraw/Surfaces/Surface.h>
#include <DDraw/Surfaces/SurfaceImpl.h>
#include <Win32/DisplayMode.h>
// {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<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr<Surface> 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<Surface>());
attach(*attachedSurfaces[i], std::make_unique<Surface>(privateData->m_origCaps));
}
}

View File

@ -20,7 +20,7 @@ namespace DDraw
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
Surface();
Surface(DWORD origCaps);
virtual ~Surface();
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
@ -54,6 +54,7 @@ namespace DDraw
template <typename TDirectDrawSurface>
friend class SurfaceImpl;
DWORD m_origCaps;
DWORD m_refCount;
SIZE m_sizeOverride;
};

View File

@ -79,7 +79,12 @@ namespace DDraw
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::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 <typename TSurface>
@ -113,11 +118,15 @@ namespace DDraw
HRESULT SurfaceImpl<TSurface>::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 <typename TSurface>
void SurfaceImpl<TSurface>::restoreOrigCaps(DWORD& caps)
{
if (m_data->m_origCaps & DDSCAPS_3DDEVICE)
{
caps |= DDSCAPS_3DDEVICE;
}
}
template <typename TSurface>
bool SurfaceImpl<TSurface>::waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag)
{

View File

@ -45,6 +45,8 @@ namespace DDraw
bool waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag);
private:
void restoreOrigCaps(DWORD& caps);
Surface* m_data;
};
}