From 0dbd2106493c973e9a3240363cdc406595a08629 Mon Sep 17 00:00:00 2001 From: narzoul Date: Sun, 11 Sep 2016 17:34:39 +0200 Subject: [PATCH] Moved CompatPrimarySurface implementation to separate layer --- DDrawCompat/DDraw/ActivateAppHandler.cpp | 4 +- DDrawCompat/DDraw/CompatPrimarySurface.cpp | 85 ------- DDrawCompat/DDraw/CompatPrimarySurface.h | 22 -- DDrawCompat/DDraw/DirectDraw.cpp | 5 +- DDrawCompat/DDraw/DirectDrawPalette.cpp | 10 +- DDrawCompat/DDraw/PaletteConverter.cpp | 6 +- DDrawCompat/DDraw/RealPrimarySurface.cpp | 12 +- DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp | 104 ++++++++ DDrawCompat/DDraw/Surfaces/PrimarySurface.h | 25 ++ .../DDraw/Surfaces/PrimarySurfaceImpl.cpp | 230 ++++++++++++++++++ .../DDraw/Surfaces/PrimarySurfaceImpl.h | 35 +++ DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp | 229 +---------------- DDrawCompat/DDraw/Surfaces/SurfaceImpl.h | 5 - DDrawCompat/DDrawCompat.vcxproj | 6 +- DDrawCompat/DDrawCompat.vcxproj.filters | 18 +- DDrawCompat/Gdi/DcCache.cpp | 10 +- DDrawCompat/Gdi/Gdi.cpp | 8 +- DDrawCompat/Gdi/PaintHandlers.cpp | 1 - DDrawCompat/Gdi/TitleBar.cpp | 4 +- 19 files changed, 450 insertions(+), 369 deletions(-) delete mode 100644 DDrawCompat/DDraw/CompatPrimarySurface.cpp delete mode 100644 DDrawCompat/DDraw/CompatPrimarySurface.h create mode 100644 DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp create mode 100644 DDrawCompat/DDraw/Surfaces/PrimarySurface.h create mode 100644 DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp create mode 100644 DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h diff --git a/DDrawCompat/DDraw/ActivateAppHandler.cpp b/DDrawCompat/DDraw/ActivateAppHandler.cpp index 4b059de..74d04ce 100644 --- a/DDrawCompat/DDraw/ActivateAppHandler.cpp +++ b/DDrawCompat/DDraw/ActivateAppHandler.cpp @@ -2,9 +2,9 @@ #include "Common/CompatRef.h" #include "Common/Log.h" #include "DDraw/ActivateAppHandler.h" -#include "DDraw/CompatPrimarySurface.h" #include "DDraw/DirectDraw.h" #include "DDraw/DisplayMode.h" +#include "DDraw/Surfaces/PrimarySurface.h" #include "DDraw/Surfaces/SurfaceImpl.h" #include "Gdi/Gdi.h" #include "Win32/FontSmoothing.h" @@ -38,7 +38,7 @@ namespace auto dm = DDraw::DisplayMode::getDisplayMode(dd); dd->SetDisplayMode(&dd, dm.dwWidth, dm.dwHeight, 32, dm.dwRefreshRate, 0); - auto primary(DDraw::CompatPrimarySurface::getPrimary()); + auto primary(DDraw::PrimarySurface::getPrimary()); if (primary && SUCCEEDED(primary->Restore(primary))) { DDraw::SurfaceImpl::fixSurfacePtrs(*primary); diff --git a/DDrawCompat/DDraw/CompatPrimarySurface.cpp b/DDrawCompat/DDraw/CompatPrimarySurface.cpp deleted file mode 100644 index 11b0c89..0000000 --- a/DDrawCompat/DDraw/CompatPrimarySurface.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include - -#include "Common/CompatPtr.h" -#include "DDraw/CompatPrimarySurface.h" -#include "DDraw/DirectDrawSurface.h" -#include "DDraw/IReleaseNotifier.h" -#include "DDraw/RealPrimarySurface.h" - -namespace -{ - void onRelease(); - - DDSURFACEDESC2 g_primarySurfaceDesc = {}; - CompatWeakPtr g_primarySurface = nullptr; - std::vector g_primarySurfacePtrs; - DDraw::IReleaseNotifier g_releaseNotifier(onRelease); - - void onRelease() - { - Compat::LogEnter("CompatPrimarySurface::onRelease"); - - g_primarySurfacePtrs.clear(); - g_primarySurface = nullptr; - DDraw::CompatPrimarySurface::g_palette = nullptr; - ZeroMemory(&DDraw::CompatPrimarySurface::g_paletteEntries, - sizeof(DDraw::CompatPrimarySurface::g_paletteEntries)); - ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc)); - - DDraw::RealPrimarySurface::release(); - - Compat::LogLeave("CompatPrimarySurface::onRelease"); - } -} - -namespace DDraw -{ - namespace CompatPrimarySurface - { - const DDSURFACEDESC2& getDesc() - { - return g_primarySurfaceDesc; - } - - CompatPtr getPrimary() - { - if (!g_primarySurface) - { - return nullptr; - } - return CompatPtr( - Compat::queryInterface(g_primarySurface.get())); - } - - bool isPrimary(void* surface) - { - return g_primarySurfacePtrs.end() != - std::find(g_primarySurfacePtrs.begin(), g_primarySurfacePtrs.end(), surface); - } - - void setPrimary(CompatRef surface) - { - CompatPtr surfacePtr(Compat::queryInterface(&surface)); - g_primarySurface = surfacePtr; - - ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc)); - g_primarySurfaceDesc.dwSize = sizeof(g_primarySurfaceDesc); - surface->GetSurfaceDesc(&surface, &g_primarySurfaceDesc); - - g_primarySurfacePtrs.clear(); - g_primarySurfacePtrs.push_back(&surface); - g_primarySurfacePtrs.push_back(CompatPtr(surfacePtr)); - g_primarySurfacePtrs.push_back(CompatPtr(surfacePtr)); - g_primarySurfacePtrs.push_back(CompatPtr(surfacePtr)); - g_primarySurfacePtrs.push_back(surfacePtr); - - IReleaseNotifier* releaseNotifierPtr = &g_releaseNotifier; - surface->SetPrivateData(&surface, IID_IReleaseNotifier, - releaseNotifierPtr, sizeof(releaseNotifierPtr), DDSPD_IUNKNOWNPOINTER); - } - - CompatWeakPtr g_palette; - PALETTEENTRY g_paletteEntries[256] = {}; - } -} diff --git a/DDrawCompat/DDraw/CompatPrimarySurface.h b/DDrawCompat/DDraw/CompatPrimarySurface.h deleted file mode 100644 index 41cf526..0000000 --- a/DDrawCompat/DDraw/CompatPrimarySurface.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#define CINTERFACE - -#include - -#include "Common/CompatPtr.h" -#include "Common/CompatRef.h" - -namespace DDraw -{ - namespace CompatPrimarySurface - { - const DDSURFACEDESC2& getDesc(); - CompatPtr getPrimary(); - bool isPrimary(void* surface); - void setPrimary(CompatRef surface); - - extern CompatWeakPtr g_palette; - extern PALETTEENTRY g_paletteEntries[256]; - } -} diff --git a/DDrawCompat/DDraw/DirectDraw.cpp b/DDrawCompat/DDraw/DirectDraw.cpp index 6a46e16..5bac2b9 100644 --- a/DDrawCompat/DDraw/DirectDraw.cpp +++ b/DDrawCompat/DDraw/DirectDraw.cpp @@ -5,8 +5,8 @@ #include "DDraw/DirectDrawSurface.h" #include "DDraw/DisplayMode.h" #include "DDraw/IReleaseNotifier.h" +#include "DDraw/Surfaces/PrimarySurface.h" #include "DDraw/Surfaces/Surface.h" -#include "DDraw/Surfaces/SurfaceImpl.h" namespace { @@ -119,8 +119,7 @@ namespace DDraw if (isPrimary) { - result = SurfaceImpl::createCompatPrimarySurface( - *This, *lpDDSurfaceDesc, *lplpDDSurface); + result = PrimarySurface::create(*This, *lpDDSurfaceDesc, *lplpDDSurface); } else { diff --git a/DDrawCompat/DDraw/DirectDrawPalette.cpp b/DDrawCompat/DDraw/DirectDrawPalette.cpp index d35933c..c950501 100644 --- a/DDrawCompat/DDraw/DirectDrawPalette.cpp +++ b/DDrawCompat/DDraw/DirectDrawPalette.cpp @@ -3,9 +3,9 @@ #include "Common/Time.h" #include "Config/Config.h" -#include "DDraw/CompatPrimarySurface.h" #include "DDraw/DirectDrawPalette.h" #include "DDraw/RealPrimarySurface.h" +#include "DDraw/Surfaces/PrimarySurface.h" namespace DDraw { @@ -21,11 +21,11 @@ namespace DDraw DWORD dwCount, LPPALETTEENTRY lpEntries) { - if (This == CompatPrimarySurface::g_palette) + if (This == PrimarySurface::s_palette) { waitForNextUpdate(); if (lpEntries && dwStartingEntry + dwCount <= 256 && - 0 == std::memcmp(&CompatPrimarySurface::g_paletteEntries[dwStartingEntry], + 0 == std::memcmp(&PrimarySurface::s_paletteEntries[dwStartingEntry], lpEntries, dwCount * sizeof(PALETTEENTRY))) { return DD_OK; @@ -33,9 +33,9 @@ namespace DDraw } HRESULT result = s_origVtable.SetEntries(This, dwFlags, dwStartingEntry, dwCount, lpEntries); - if (This == CompatPrimarySurface::g_palette && SUCCEEDED(result)) + if (This == PrimarySurface::s_palette && SUCCEEDED(result)) { - std::memcpy(&CompatPrimarySurface::g_paletteEntries[dwStartingEntry], lpEntries, + std::memcpy(&PrimarySurface::s_paletteEntries[dwStartingEntry], lpEntries, dwCount * sizeof(PALETTEENTRY)); RealPrimarySurface::updatePalette(dwStartingEntry, dwCount); } diff --git a/DDrawCompat/DDraw/PaletteConverter.cpp b/DDrawCompat/DDraw/PaletteConverter.cpp index eb45f03..0ecc5e4 100644 --- a/DDrawCompat/DDraw/PaletteConverter.cpp +++ b/DDrawCompat/DDraw/PaletteConverter.cpp @@ -4,11 +4,11 @@ #include "Common/CompatPtr.h" #include "Common/Hook.h" #include "Common/ScopedCriticalSection.h" -#include "DDraw/CompatPrimarySurface.h" #include "DDraw/DisplayMode.h" #include "DDraw/PaletteConverter.h" #include "DDraw/RealPrimarySurface.h" #include "DDraw/Repository.h" +#include "DDraw/Surfaces/PrimarySurface.h" #include "DDraw/Types.h" namespace @@ -151,10 +151,10 @@ namespace DDraw void updatePalette(DWORD startingEntry, DWORD count) { - if (g_dc && CompatPrimarySurface::g_palette) + if (g_dc && PrimarySurface::s_palette) { RGBQUAD entries[256] = {}; - std::memcpy(entries, &CompatPrimarySurface::g_paletteEntries[startingEntry], + std::memcpy(entries, &PrimarySurface::s_paletteEntries[startingEntry], count * sizeof(PALETTEENTRY)); convertPaletteEntriesToRgbQuad(entries, count); SetDIBColorTable(g_dc, startingEntry, count, entries); diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index 510eda0..3314521 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -4,12 +4,12 @@ #include "Common/Hook.h" #include "Common/Time.h" #include "Config/Config.h" -#include "DDraw/CompatPrimarySurface.h" #include "DDraw/DirectDrawSurface.h" #include "DDraw/IReleaseNotifier.h" #include "DDraw/PaletteConverter.h" #include "DDraw/RealPrimarySurface.h" #include "DDraw/ScopedThreadLock.h" +#include "DDraw/Surfaces/PrimarySurface.h" #include "DDraw/Types.h" #include "Gdi/Gdi.h" @@ -46,8 +46,8 @@ namespace bool result = false; - auto primary(DDraw::CompatPrimarySurface::getPrimary()); - if (DDraw::CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount <= 8) + auto primary(DDraw::PrimarySurface::getPrimary()); + if (DDraw::PrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount <= 8) { auto paletteConverter(DDraw::PaletteConverter::getSurface()); paletteConverter->Blt(paletteConverter, &g_updateRect, @@ -291,7 +291,7 @@ namespace DDraw } else { - auto primaryDesc = CompatPrimarySurface::getDesc(); + auto primaryDesc = PrimarySurface::getDesc(); SetRect(&g_updateRect, 0, 0, primaryDesc.dwWidth, primaryDesc.dwHeight); } } @@ -351,7 +351,7 @@ namespace DDraw { if (g_surfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8) { - g_frontBuffer->SetPalette(g_frontBuffer, CompatPrimarySurface::g_palette); + g_frontBuffer->SetPalette(g_frontBuffer, PrimarySurface::s_palette); } updatePalette(0, 256); @@ -377,7 +377,7 @@ namespace DDraw { PaletteConverter::updatePalette(startingEntry, count); Gdi::updatePalette(startingEntry, count); - if (CompatPrimarySurface::g_palette) + if (PrimarySurface::s_palette) { invalidate(nullptr); update(); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp new file mode 100644 index 0000000..5cf1dd4 --- /dev/null +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -0,0 +1,104 @@ +#include "Common/CompatPtr.h" +#include "DDraw/DisplayMode.h" +#include "DDraw/RealPrimarySurface.h" +#include "DDraw/Surfaces/PrimarySurface.h" +#include "DDraw/Surfaces/PrimarySurfaceImpl.h" + +namespace +{ + DDSURFACEDESC2 g_primarySurfaceDesc = {}; + CompatWeakPtr g_primarySurface = nullptr; +} + +namespace DDraw +{ + PrimarySurface::~PrimarySurface() + { + Compat::LogEnter("PrimarySurface::~PrimarySurface"); + + g_primarySurface = nullptr; + s_palette = nullptr; + ZeroMemory(&s_paletteEntries, sizeof(s_paletteEntries)); + ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc)); + + DDraw::RealPrimarySurface::release(); + + Compat::LogLeave("PrimarySurface::~PrimarySurface"); + } + + template + HRESULT PrimarySurface::create(CompatRef dd, TSurfaceDesc desc, TSurface*& surface) + { + HRESULT result = RealPrimarySurface::create(dd); + if (FAILED(result)) + { + return result; + } + + CompatPtr dd7(Compat::queryInterface(&dd)); + const auto& dm = DisplayMode::getDisplayMode(*dd7); + desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + desc.dwWidth = dm.dwWidth; + desc.dwHeight = dm.dwHeight; + desc.ddsCaps.dwCaps &= ~DDSCAPS_PRIMARYSURFACE; + desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; + desc.ddpfPixelFormat = dm.ddpfPixelFormat; + + result = Surface::create(dd, desc, surface); + if (FAILED(result)) + { + Compat::Log() << "Failed to create the compat primary surface!"; + RealPrimarySurface::release(); + return result; + } + + CompatPtr surface7(Compat::queryInterface(surface)); + std::unique_ptr privateData(new PrimarySurface()); + attach(*surface7, privateData); + + CompatPtr surface1(Compat::queryInterface(surface)); + g_primarySurface = surface1; + + ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc)); + g_primarySurfaceDesc.dwSize = sizeof(g_primarySurfaceDesc); + CompatVtableBase::s_origVtable.GetSurfaceDesc(surface7, &g_primarySurfaceDesc); + + return DD_OK; + } + + template HRESULT PrimarySurface::create( + CompatRef dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface); + template HRESULT PrimarySurface::create( + CompatRef dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface); + template HRESULT PrimarySurface::create( + CompatRef dd, DDSURFACEDESC2 desc, IDirectDrawSurface4*& surface); + template HRESULT PrimarySurface::create( + CompatRef dd, DDSURFACEDESC2 desc, IDirectDrawSurface7*& surface); + + void PrimarySurface::createImpl() + { + m_impl.reset(new PrimarySurfaceImpl()); + m_impl2.reset(new PrimarySurfaceImpl()); + m_impl3.reset(new PrimarySurfaceImpl()); + m_impl4.reset(new PrimarySurfaceImpl()); + m_impl7.reset(new PrimarySurfaceImpl()); + } + + const DDSURFACEDESC2& PrimarySurface::getDesc() + { + return g_primarySurfaceDesc; + } + + CompatPtr PrimarySurface::getPrimary() + { + if (!g_primarySurface) + { + return nullptr; + } + return CompatPtr( + Compat::queryInterface(g_primarySurface.get())); + } + + CompatWeakPtr PrimarySurface::s_palette; + PALETTEENTRY PrimarySurface::s_paletteEntries[256] = {}; +} diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.h b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h new file mode 100644 index 0000000..339b39e --- /dev/null +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Common/CompatPtr.h" +#include "DDraw/Surfaces/Surface.h" + +namespace DDraw +{ + class PrimarySurface : public Surface + { + public: + virtual ~PrimarySurface(); + + template + static HRESULT create(CompatRef dd, TSurfaceDesc desc, TSurface*& surface); + + static const DDSURFACEDESC2& getDesc(); + static CompatPtr getPrimary(); + + static CompatWeakPtr s_palette; + static PALETTEENTRY s_paletteEntries[256]; + + private: + virtual void createImpl() override; + }; +} diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp new file mode 100644 index 0000000..909d4af --- /dev/null +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp @@ -0,0 +1,230 @@ +#include "DDraw/DirectDrawPalette.h" +#include "DDraw/RealPrimarySurface.h" +#include "DDraw/Surfaces/PrimarySurface.h" +#include "DDraw/Surfaces/PrimarySurfaceImpl.h" +#include "Gdi/Gdi.h" + +namespace +{ + void restorePrimaryCaps(DWORD& caps) + { + caps &= ~DDSCAPS_OFFSCREENPLAIN; + caps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE; + } +} + +namespace DDraw +{ + template + HRESULT PrimarySurfaceImpl::Blt( + TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, + DWORD dwFlags, LPDDBLTFX lpDDBltFx) + { + if (RealPrimarySurface::isLost()) + { + return DDERR_SURFACELOST; + } + + HRESULT result = SurfaceImpl::Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx); + if (SUCCEEDED(result)) + { + RealPrimarySurface::invalidate(lpDestRect); + RealPrimarySurface::update(); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::BltFast( + TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) + { + if (RealPrimarySurface::isLost()) + { + return DDERR_SURFACELOST; + } + + HRESULT result = SurfaceImpl::BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans); + if (SUCCEEDED(result)) + { + const LONG x = dwX; + const LONG y = dwY; + RECT destRect = { x, y, x, y }; + if (lpSrcRect) + { + destRect.right += lpSrcRect->right - lpSrcRect->left; + destRect.bottom += lpSrcRect->bottom - lpSrcRect->top; + } + else + { + TSurfaceDesc desc = {}; + desc.dwSize = sizeof(desc); + CompatVtableBase::s_origVtable.GetSurfaceDesc(lpDDSrcSurface, &desc); + destRect.right += desc.dwWidth; + destRect.bottom += desc.dwHeight; + } + RealPrimarySurface::invalidate(&destRect); + RealPrimarySurface::update(); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags) + { + if (RealPrimarySurface::isLost()) + { + return DDERR_SURFACELOST; + } + + HRESULT result = SurfaceImpl::Flip(This, lpDDSurfaceTargetOverride, dwFlags); + if (SUCCEEDED(result)) + { + result = RealPrimarySurface::flip(dwFlags); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps) + { + HRESULT result = SurfaceImpl::GetCaps(This, lpDDSCaps); + if (SUCCEEDED(result)) + { + restorePrimaryCaps(lpDDSCaps->dwCaps); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc) + { + HRESULT result = SurfaceImpl::GetSurfaceDesc(This, lpDDSurfaceDesc); + if (SUCCEEDED(result)) + { + restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::IsLost(TSurface* This) + { + HRESULT result = SurfaceImpl::IsLost(This); + if (SUCCEEDED(result)) + { + result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK; + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::Lock( + TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc, + DWORD dwFlags, HANDLE hEvent) + { + if (RealPrimarySurface::isLost()) + { + return DDERR_SURFACELOST; + } + + HRESULT result = SurfaceImpl::Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent); + if (SUCCEEDED(result)) + { + RealPrimarySurface::invalidate(lpDestRect); + restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::QueryInterface(TSurface* This, REFIID riid, LPVOID* obp) + { + if (riid == IID_IDirectDrawGammaControl) + { + auto realPrimary(RealPrimarySurface::getSurface()); + return realPrimary->QueryInterface(realPrimary, riid, obp); + } + return SurfaceImpl::QueryInterface(This, riid, obp); + } + + template + HRESULT PrimarySurfaceImpl::ReleaseDC(TSurface* This, HDC hDC) + { + HRESULT result = SurfaceImpl::ReleaseDC(This, hDC); + if (SUCCEEDED(result)) + { + RealPrimarySurface::invalidate(nullptr); + RealPrimarySurface::update(); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::Restore(TSurface* This) + { + HRESULT result = IsLost(This); + if (FAILED(result)) + { + result = RealPrimarySurface::restore(); + if (SUCCEEDED(result)) + { + result = SurfaceImpl::Restore(This); + if (SUCCEEDED(result)) + { + fixSurfacePtrs(*This); + Gdi::invalidate(nullptr); + } + } + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper) + { + HRESULT result = SurfaceImpl::SetClipper(This, lpDDClipper); + if (SUCCEEDED(result)) + { + RealPrimarySurface::setClipper(lpDDClipper); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) + { + if (lpDDPalette) + { + DirectDrawPalette::waitForNextUpdate(); + } + if (lpDDPalette == PrimarySurface::s_palette) + { + return DD_OK; + } + + HRESULT result = SurfaceImpl::SetPalette(This, lpDDPalette); + if (SUCCEEDED(result)) + { + PrimarySurface::s_palette = lpDDPalette; + RealPrimarySurface::setPalette(); + } + return result; + } + + template + HRESULT PrimarySurfaceImpl::Unlock(TSurface* This, TUnlockParam lpRect) + { + HRESULT result = SurfaceImpl::Unlock(This, lpRect); + if (SUCCEEDED(result)) + { + RealPrimarySurface::update(); + } + return result; + } + + template PrimarySurfaceImpl; + template PrimarySurfaceImpl; + template PrimarySurfaceImpl; + template PrimarySurfaceImpl; + template PrimarySurfaceImpl; +} diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h new file mode 100644 index 0000000..75db33a --- /dev/null +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.h @@ -0,0 +1,35 @@ +#pragma once + +#define CINTERFACE + +#include + +#include "Common/CompatRef.h" +#include "Common/CompatVtable.h" +#include "DDraw/Surfaces/SurfaceImpl.h" +#include "DDraw/Types.h" + +namespace DDraw +{ + template + class PrimarySurfaceImpl : public SurfaceImpl + { + public: + 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, + TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) override; + virtual HRESULT Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags) override; + virtual HRESULT GetCaps(TSurface* This, TDdsCaps* lpDDSCaps) override; + virtual HRESULT GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc) override; + virtual HRESULT IsLost(TSurface* This) override; + virtual HRESULT Lock(TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc, + DWORD dwFlags, HANDLE hEvent) override; + virtual HRESULT QueryInterface(TSurface* This, REFIID riid, LPVOID* obp) override; + virtual HRESULT ReleaseDC(TSurface* This, HDC hDC) override; + virtual HRESULT Restore(TSurface* This) override; + virtual HRESULT SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper) override; + virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) override; + virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect) override; + }; +} diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp index 2acaad2..e2a4403 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp @@ -1,22 +1,15 @@ #include #include "Common/CompatPtr.h" -#include "DDraw/CompatPrimarySurface.h" -#include "DDraw/DirectDrawPalette.h" -#include "DDraw/DisplayMode.h" -#include "DDraw/RealPrimarySurface.h" #include "DDraw/Repository.h" #include "DDraw/Surfaces/Surface.h" #include "DDraw/Surfaces/SurfaceImpl.h" -#include "Gdi/Gdi.h" namespace { bool mirrorBlt(CompatRef dst, CompatRef src, RECT srcRect, DWORD mirrorFx); - bool g_lockingPrimary = false; - void fixSurfacePtr(CompatRef surface, const DDSURFACEDESC2& desc) { if ((desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) || 0 == desc.dwWidth || 0 == desc.dwHeight) @@ -153,42 +146,6 @@ namespace namespace DDraw { - template - template - HRESULT SurfaceImpl::createCompatPrimarySurface( - CompatRef dd, - TSurfaceDesc compatDesc, - TSurface*& compatSurface) - { - HRESULT result = RealPrimarySurface::create(dd); - if (FAILED(result)) - { - return result; - } - - CompatPtr dd7(Compat::queryInterface(&dd)); - const auto& dm = DisplayMode::getDisplayMode(*dd7); - compatDesc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - compatDesc.dwWidth = dm.dwWidth; - compatDesc.dwHeight = dm.dwHeight; - compatDesc.ddsCaps.dwCaps &= ~DDSCAPS_PRIMARYSURFACE; - compatDesc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; - compatDesc.ddpfPixelFormat = dm.ddpfPixelFormat; - - result = Surface::create(dd, compatDesc, compatSurface); - if (FAILED(result)) - { - Compat::Log() << "Failed to create the compat primary surface!"; - RealPrimarySurface::release(); - return result; - } - - CompatPtr primary(Compat::queryInterface(compatSurface)); - CompatPrimarySurface::setPrimary(*primary); - - return DD_OK; - } - template SurfaceImpl::~SurfaceImpl() { @@ -206,13 +163,6 @@ namespace DDraw TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) { - const bool isPrimaryDest = CompatPrimarySurface::isPrimary(This); - if ((isPrimaryDest || CompatPrimarySurface::isPrimary(lpDDSrcSurface)) && - RealPrimarySurface::isLost()) - { - return DDERR_SURFACELOST; - } - HRESULT result = DD_OK; CompatPtr mirroredSrcSurface; @@ -261,12 +211,6 @@ namespace DDraw result = s_origVtable.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx); } - if (isPrimaryDest && SUCCEEDED(result)) - { - RealPrimarySurface::invalidate(lpDestRect); - RealPrimarySurface::update(); - } - return result; } @@ -274,80 +218,31 @@ namespace DDraw HRESULT SurfaceImpl::BltFast( TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) { - const bool isPrimaryDest = CompatPrimarySurface::isPrimary(This); - if ((isPrimaryDest || CompatPrimarySurface::isPrimary(lpDDSrcSurface)) && - RealPrimarySurface::isLost()) - { - return DDERR_SURFACELOST; - } - - HRESULT result = s_origVtable.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans); - if (isPrimaryDest && SUCCEEDED(result)) - { - const LONG x = dwX; - const LONG y = dwY; - RECT destRect = { x, y, x, y }; - if (lpSrcRect) - { - destRect.right += lpSrcRect->right - lpSrcRect->left; - destRect.bottom += lpSrcRect->bottom - lpSrcRect->top; - } - else - { - TSurfaceDesc desc = {}; - desc.dwSize = sizeof(desc); - s_origVtable.GetSurfaceDesc(lpDDSrcSurface, &desc); - destRect.right += desc.dwWidth; - destRect.bottom += desc.dwHeight; - } - RealPrimarySurface::invalidate(&destRect); - RealPrimarySurface::update(); - } - return result; + return s_origVtable.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans); } template HRESULT SurfaceImpl::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags) { - HRESULT result = s_origVtable.Flip(This, lpDDSurfaceTargetOverride, dwFlags); - if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This)) - { - result = RealPrimarySurface::flip(dwFlags); - } - return result; + return s_origVtable.Flip(This, lpDDSurfaceTargetOverride, dwFlags); } template HRESULT SurfaceImpl::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps) { - HRESULT result = s_origVtable.GetCaps(This, lpDDSCaps); - if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This)) - { - restorePrimaryCaps(*lpDDSCaps); - } - return result; + return s_origVtable.GetCaps(This, lpDDSCaps); } template HRESULT SurfaceImpl::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc) { - HRESULT result = s_origVtable.GetSurfaceDesc(This, lpDDSurfaceDesc); - if (SUCCEEDED(result) && !g_lockingPrimary && CompatPrimarySurface::isPrimary(This)) - { - restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps); - } - return result; + return s_origVtable.GetSurfaceDesc(This, lpDDSurfaceDesc); } template HRESULT SurfaceImpl::IsLost(TSurface* This) { - HRESULT result = s_origVtable.IsLost(This); - if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This)) - { - result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK; - } - return result; + return s_origVtable.IsLost(This); } template @@ -355,22 +250,8 @@ namespace DDraw TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) { - if (CompatPrimarySurface::isPrimary(This)) - { - if (RealPrimarySurface::isLost()) - { - return DDERR_SURFACELOST; - } - g_lockingPrimary = true; - } - HRESULT result = s_origVtable.Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent); - if (SUCCEEDED(result) && g_lockingPrimary && lpDDSurfaceDesc) - { - RealPrimarySurface::invalidate(lpDestRect); - restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps); - } - else if (DDERR_SURFACELOST == result) + if (DDERR_SURFACELOST == result) { TSurfaceDesc desc = {}; desc.dwSize = sizeof(desc); @@ -382,114 +263,43 @@ namespace DDraw } } - g_lockingPrimary = false; return result; } template HRESULT SurfaceImpl::QueryInterface(TSurface* This, REFIID riid, LPVOID* obp) { - if (riid == IID_IDirectDrawGammaControl && CompatPrimarySurface::isPrimary(This)) - { - auto realPrimary(RealPrimarySurface::getSurface()); - return realPrimary->QueryInterface(realPrimary, riid, obp); - } return s_origVtable.QueryInterface(This, riid, obp); } template HRESULT SurfaceImpl::ReleaseDC(TSurface* This, HDC hDC) { - const bool isPrimary = CompatPrimarySurface::isPrimary(This); - if (isPrimary && RealPrimarySurface::isLost()) - { - return DDERR_SURFACELOST; - } - - HRESULT result = s_origVtable.ReleaseDC(This, hDC); - if (isPrimary && SUCCEEDED(result)) - { - RealPrimarySurface::invalidate(nullptr); - RealPrimarySurface::update(); - } - return result; + return s_origVtable.ReleaseDC(This, hDC); } template HRESULT SurfaceImpl::Restore(TSurface* This) { - const bool wasLost = DDERR_SURFACELOST == s_origVtable.IsLost(This); - HRESULT result = s_origVtable.Restore(This); - if (SUCCEEDED(result)) - { - if (wasLost) - { - fixSurfacePtrs(*This); - } - if (CompatPrimarySurface::isPrimary(This)) - { - result = RealPrimarySurface::restore(); - if (wasLost) - { - Gdi::invalidate(nullptr); - } - } - } - return result; + return s_origVtable.Restore(This); } template HRESULT SurfaceImpl::SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper) { - HRESULT result = s_origVtable.SetClipper(This, lpDDClipper); - if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This)) - { - RealPrimarySurface::setClipper(lpDDClipper); - } - return result; + return s_origVtable.SetClipper(This, lpDDClipper); } template HRESULT SurfaceImpl::SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) { - const bool isPrimary = CompatPrimarySurface::isPrimary(This); - if (isPrimary) - { - if (lpDDPalette) - { - DirectDrawPalette::waitForNextUpdate(); - } - if (lpDDPalette == CompatPrimarySurface::g_palette) - { - return DD_OK; - } - } - - HRESULT result = s_origVtable.SetPalette(This, lpDDPalette); - if (isPrimary && SUCCEEDED(result)) - { - CompatPrimarySurface::g_palette = lpDDPalette; - RealPrimarySurface::setPalette(); - } - return result; + return s_origVtable.SetPalette(This, lpDDPalette); } template HRESULT SurfaceImpl::Unlock(TSurface* This, TUnlockParam lpRect) { - HRESULT result = s_origVtable.Unlock(This, lpRect); - if (SUCCEEDED(result) && CompatPrimarySurface::isPrimary(This)) - { - RealPrimarySurface::update(); - } - return result; - } - - template - void SurfaceImpl::restorePrimaryCaps(TDdsCaps& caps) - { - caps.dwCaps &= ~(DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY); - caps.dwCaps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM; + return s_origVtable.Unlock(This, lpRect); } template @@ -500,21 +310,4 @@ namespace DDraw template SurfaceImpl; template SurfaceImpl; template SurfaceImpl; - - template HRESULT SurfaceImpl::createCompatPrimarySurface( - CompatRef dd, - TSurfaceDesc compatDesc, - IDirectDrawSurface*& compatSurface); - template HRESULT SurfaceImpl::createCompatPrimarySurface( - CompatRef dd, - TSurfaceDesc compatDesc, - IDirectDrawSurface*& compatSurface); - template HRESULT SurfaceImpl::createCompatPrimarySurface( - CompatRef dd, - TSurfaceDesc compatDesc, - IDirectDrawSurface4*& compatSurface); - template HRESULT SurfaceImpl::createCompatPrimarySurface( - CompatRef dd, - TSurfaceDesc compatDesc, - IDirectDrawSurface7*& compatSurface); } diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h index 5d680b9..d792aff 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.h @@ -20,9 +20,6 @@ namespace DDraw virtual ~SurfaceImpl(); - template - static HRESULT createCompatPrimarySurface( - CompatRef dd, TSurfaceDesc compatDesc, TSurface*& compatSurface); static void fixSurfacePtrs(CompatRef surface); virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, @@ -43,8 +40,6 @@ namespace DDraw virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect); private: - static void restorePrimaryCaps(TDdsCaps& caps); - static const Vtable& s_origVtable; }; } diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index e416deb..dc65910 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -175,10 +175,11 @@ - + + @@ -224,11 +225,12 @@ - + + diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index d10eaa5..8ff12cb 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -105,9 +105,6 @@ Header Files\Gdi - - Header Files\DDraw - Header Files\DDraw @@ -252,6 +249,12 @@ Header Files\DDraw\Surfaces + + Header Files\DDraw\Surfaces + + + Header Files\DDraw\Surfaces + @@ -284,9 +287,6 @@ Source Files\Gdi - - Source Files\DDraw - Source Files\DDraw @@ -377,6 +377,12 @@ Source Files\DDraw\Surfaces + + Source Files\DDraw\Surfaces + + + Source Files\DDraw\Surfaces + diff --git a/DDrawCompat/Gdi/DcCache.cpp b/DDrawCompat/Gdi/DcCache.cpp index 84b3b39..06c3635 100644 --- a/DDrawCompat/Gdi/DcCache.cpp +++ b/DDrawCompat/Gdi/DcCache.cpp @@ -4,8 +4,8 @@ #include "Common/CompatPtr.h" #include "Common/Log.h" #include "Config/Config.h" -#include "DDraw/CompatPrimarySurface.h" #include "DDraw/Repository.h" +#include "DDraw/Surfaces/PrimarySurface.h" #include "Dll/Procs.h" #include "Gdi/DcCache.h" @@ -55,7 +55,7 @@ namespace CompatPtr createGdiSurface() { - DDSURFACEDESC2 desc = DDraw::CompatPrimarySurface::getDesc(); + DDSURFACEDESC2 desc = DDraw::PrimarySurface::getDesc(); desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_PITCH | DDSD_LPSURFACE; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; desc.lPitch = g_pitch; @@ -202,15 +202,15 @@ namespace Gdi { PALETTEENTRY entries[256] = {}; std::memcpy(&entries[startingEntry], - &DDraw::CompatPrimarySurface::g_paletteEntries[startingEntry], + &DDraw::PrimarySurface::s_paletteEntries[startingEntry], count * sizeof(PALETTEENTRY)); for (DWORD i = startingEntry; i < startingEntry + count; ++i) { if (entries[i].peFlags & PC_RESERVED) { - entries[i] = DDraw::CompatPrimarySurface::g_paletteEntries[0]; - entries[i].peFlags = DDraw::CompatPrimarySurface::g_paletteEntries[i].peFlags; + entries[i] = DDraw::PrimarySurface::s_paletteEntries[0]; + entries[i].peFlags = DDraw::PrimarySurface::s_paletteEntries[i].peFlags; } } diff --git a/DDrawCompat/Gdi/Gdi.cpp b/DDrawCompat/Gdi/Gdi.cpp index 84dc870..877d42a 100644 --- a/DDrawCompat/Gdi/Gdi.cpp +++ b/DDrawCompat/Gdi/Gdi.cpp @@ -1,9 +1,9 @@ #include #include "Common/ScopedCriticalSection.h" -#include "DDraw/CompatPrimarySurface.h" #include "DDraw/PaletteConverter.h" #include "DDraw/RealPrimarySurface.h" +#include "DDraw/Surfaces/PrimarySurface.h" #include "Dll/Procs.h" #include "Gdi/Caret.h" #include "Gdi/DcCache.h" @@ -58,7 +58,7 @@ namespace { DDSURFACEDESC2 desc = {}; desc.dwSize = sizeof(desc); - auto primary(DDraw::CompatPrimarySurface::getPrimary()); + auto primary(DDraw::PrimarySurface::getPrimary()); if (FAILED(primary->Lock(primary, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr))) { return false; @@ -79,7 +79,7 @@ namespace void unlockPrimarySurface() { GdiFlush(); - auto primary(DDraw::CompatPrimarySurface::getPrimary()); + auto primary(DDraw::PrimarySurface::getPrimary()); primary->Unlock(primary, nullptr); if (DDLOCK_READONLY != g_ddLockFlags) { @@ -239,7 +239,7 @@ namespace Gdi void updatePalette(DWORD startingEntry, DWORD count) { - if (isEmulationEnabled() && DDraw::CompatPrimarySurface::g_palette) + if (isEmulationEnabled() && DDraw::PrimarySurface::s_palette) { Gdi::DcCache::updatePalette(startingEntry, count); } diff --git a/DDrawCompat/Gdi/PaintHandlers.cpp b/DDrawCompat/Gdi/PaintHandlers.cpp index 4c4d41e..377aa65 100644 --- a/DDrawCompat/Gdi/PaintHandlers.cpp +++ b/DDrawCompat/Gdi/PaintHandlers.cpp @@ -1,6 +1,5 @@ #include "Common/Hook.h" #include "Common/Log.h" -#include "DDraw/CompatPrimarySurface.h" #include "DDraw/RealPrimarySurface.h" #include "Gdi/Dc.h" #include "Gdi/Gdi.h" diff --git a/DDrawCompat/Gdi/TitleBar.cpp b/DDrawCompat/Gdi/TitleBar.cpp index fe0c9ab..dc97433 100644 --- a/DDrawCompat/Gdi/TitleBar.cpp +++ b/DDrawCompat/Gdi/TitleBar.cpp @@ -1,5 +1,5 @@ #include "Common/Hook.h" -#include "DDraw/CompatPrimarySurface.h" +#include "DDraw/Surfaces/PrimarySurface.h" #include "Gdi/Gdi.h" #include "Gdi/TitleBar.h" @@ -96,7 +96,7 @@ namespace Gdi { flags |= DC_ACTIVE; } - if (DDraw::CompatPrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount > 8) + if (DDraw::PrimarySurface::getDesc().ddpfPixelFormat.dwRGBBitCount > 8) { flags |= DC_GRADIENT; }