From 8ab8058cebbc77bda8af90a89818b91c140d0481 Mon Sep 17 00:00:00 2001 From: narzoul Date: Sun, 6 Aug 2017 21:42:24 +0200 Subject: [PATCH] Fix reported memory caps of primary surface Changed primary surface caps to report video memory in case the surface was only forced into system memory by DDrawCompat. Fixes startup issues in C&C 95 and Red Alert, reported in issue #3. --- DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp | 12 +++++++----- DDrawCompat/DDraw/Surfaces/PrimarySurface.h | 2 +- DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp | 12 ++++++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp index 8c62e2a..c37c62a 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -10,7 +10,7 @@ namespace DDSURFACEDESC2 g_primarySurfaceDesc = {}; CompatWeakPtr g_gdiSurface = nullptr; CompatWeakPtr g_primarySurface = nullptr; - bool g_isFlipEmulated = false; + DWORD g_origCaps = 0; } namespace DDraw @@ -26,7 +26,7 @@ namespace DDraw g_gdiSurface = nullptr; g_primarySurface = nullptr; - g_isFlipEmulated = false; + g_origCaps = 0; s_palette = nullptr; s_surfaceBuffers.clear(); ZeroMemory(&s_paletteEntries, sizeof(s_paletteEntries)); @@ -46,6 +46,8 @@ namespace DDraw return result; } + const DWORD origCaps = desc.ddsCaps.dwCaps; + const auto& dm = DDraw::getDisplayMode(*CompatPtr::from(&dd)); desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; desc.dwWidth = dm.dwWidth; @@ -69,7 +71,7 @@ namespace DDraw CompatPtr surface1(Compat::queryInterface(surface)); g_gdiSurface = surface1; g_primarySurface = surface1; - g_isFlipEmulated = 0 != (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY); + g_origCaps = origCaps; ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc)); g_primarySurfaceDesc.dwSize = sizeof(g_primarySurfaceDesc); @@ -130,9 +132,9 @@ namespace DDraw Compat::queryInterface(g_primarySurface.get())); } - bool PrimarySurface::isFlipEmulated() + DWORD PrimarySurface::getOrigCaps() { - return g_isFlipEmulated; + return g_origCaps; } void PrimarySurface::resizeBuffers(CompatRef surface) diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h index 37478f0..0f7e82b 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h @@ -20,7 +20,7 @@ namespace DDraw static const DDSURFACEDESC2& getDesc(); static CompatPtr getGdiSurface(); static CompatPtr getPrimary(); - static bool isFlipEmulated(); + static DWORD getOrigCaps(); void updateGdiSurfacePtr(IDirectDrawSurface* flipTargetOverride); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp index 59b1673..5dda0a8 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp @@ -10,6 +10,13 @@ namespace { caps &= ~DDSCAPS_OFFSCREENPLAIN; caps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE; + + if ((caps & DDSCAPS_SYSTEMMEMORY) && + !(DDraw::PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY)) + { + caps &= ~DDSCAPS_SYSTEMMEMORY; + caps |= DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; + } } } @@ -85,8 +92,9 @@ namespace DDraw return result; } + const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY); result = RealPrimarySurface::flip(dwFlags); - if (SUCCEEDED(result) && !PrimarySurface::isFlipEmulated()) + if (SUCCEEDED(result) && !isFlipEmulated) { static_cast(m_data)->updateGdiSurfacePtr( CompatPtr::from(lpDDSurfaceTargetOverride)); @@ -95,7 +103,7 @@ namespace DDraw undoFlip(This, lpDDSurfaceTargetOverride); - if (SUCCEEDED(result) && PrimarySurface::isFlipEmulated()) + if (SUCCEEDED(result) && isFlipEmulated) { if (lpDDSurfaceTargetOverride) {