From 71e90210addf25fb05c2e1040a315241fd7fb943 Mon Sep 17 00:00:00 2001 From: narzoul Date: Mon, 28 Mar 2016 19:48:45 +0200 Subject: [PATCH] Introduced a DirectDraw repository for reusable objects --- DDrawCompat/CompatDirectDrawSurface.cpp | 27 +++++++----------- DDrawCompat/CompatGdiDcCache.cpp | 23 ++------------- DDrawCompat/DDrawCompat.vcxproj | 2 ++ DDrawCompat/DDrawCompat.vcxproj.filters | 6 ++++ DDrawCompat/DDrawRepository.cpp | 38 +++++++++++++++++++++++++ DDrawCompat/DDrawRepository.h | 10 +++++++ DDrawCompat/DllMain.cpp | 29 +++++++------------ 7 files changed, 79 insertions(+), 56 deletions(-) create mode 100644 DDrawCompat/DDrawRepository.cpp create mode 100644 DDrawCompat/DDrawRepository.h diff --git a/DDrawCompat/CompatDirectDrawSurface.cpp b/DDrawCompat/CompatDirectDrawSurface.cpp index e5673fc..9502e09 100644 --- a/DDrawCompat/CompatDirectDrawSurface.cpp +++ b/DDrawCompat/CompatDirectDrawSurface.cpp @@ -7,6 +7,7 @@ #include "CompatGdi.h" #include "CompatPrimarySurface.h" #include "DDrawProcs.h" +#include "DDrawRepository.h" #include "IReleaseNotifier.h" #include "RealPrimarySurface.h" @@ -24,21 +25,8 @@ namespace SimilarSurface getSimilarSurface(const DDSURFACEDESC2& desc); bool mirrorBlt(IDirectDrawSurface7& dst, IDirectDrawSurface7& src, RECT srcRect, DWORD mirrorFx); - IDirectDraw7* g_mirrorDirectDraw = nullptr; bool g_lockingPrimary = false; - IDirectDraw7* createMirrorDirectDraw() - { - IDirectDraw7* dd = nullptr; - CALL_ORIG_DDRAW(DirectDrawCreateEx, nullptr, reinterpret_cast(&dd), IID_IDirectDraw7, nullptr); - if (!dd || - FAILED(CompatDirectDraw::s_origVtable.SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL))) - { - Compat::Log() << "Failed to create a helper DirectDraw object for mirroring"; - } - return dd; - } - void fixSurfacePtr(IDirectDrawSurface7& surface, const DDSURFACEDESC2& desc) { if ((desc.dwFlags & DDSD_CAPS) && (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) @@ -213,8 +201,15 @@ namespace similarDesc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; } + IDirectDraw7* dd = DDrawRepository::getDirectDraw(); + if (!dd) + { + similarSurface.front = nullptr; + return similarSurface; + } + HRESULT result = CompatDirectDraw::s_origVtable.CreateSurface( - g_mirrorDirectDraw, &similarDesc, &similarSurface.front, nullptr); + dd, &similarDesc, &similarSurface.front, nullptr); if (FAILED(result)) { LOG_ONCE("Failed to create a similar front surface"); @@ -223,7 +218,7 @@ namespace } result = CompatDirectDraw::s_origVtable.CreateSurface( - g_mirrorDirectDraw, &similarDesc, &similarSurface.back, nullptr); + dd, &similarDesc, &similarSurface.back, nullptr); if (FAILED(result)) { LOG_ONCE("Failed to create a similar back surface"); @@ -347,8 +342,6 @@ HRESULT CompatDirectDrawSurface::createCompatPrimarySurface( return result; } - g_mirrorDirectDraw = createMirrorDirectDraw(); - s_compatPrimarySurface = compatSurface; initCompatPrimarySurface(); return DD_OK; diff --git a/DDrawCompat/CompatGdiDcCache.cpp b/DDrawCompat/CompatGdiDcCache.cpp index 7f64934..8c5d17e 100644 --- a/DDrawCompat/CompatGdiDcCache.cpp +++ b/DDrawCompat/CompatGdiDcCache.cpp @@ -7,6 +7,7 @@ #include "Config.h" #include "DDrawLog.h" #include "DDrawProcs.h" +#include "DDrawRepository.h" namespace { @@ -24,26 +25,6 @@ namespace IDirectDrawSurface7* createGdiSurface(); - IDirectDraw7* createDirectDraw() - { - IDirectDraw7* dd = nullptr; - CALL_ORIG_DDRAW(DirectDrawCreateEx, nullptr, reinterpret_cast(&dd), IID_IDirectDraw7, nullptr); - if (!dd) - { - Compat::Log() << "Failed to create a DirectDraw interface for GDI"; - return nullptr; - } - - if (FAILED(CompatDirectDraw::s_origVtable.SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL))) - { - Compat::Log() << "Failed to set the cooperative level on the DirectDraw interface for GDI"; - dd->lpVtbl->Release(dd); - return nullptr; - } - - return dd; - } - CachedDc createCachedDc() { CachedDc cachedDc = {}; @@ -186,7 +167,7 @@ namespace CompatGdiDcCache bool init() { - g_directDraw = createDirectDraw(); + g_directDraw = DDrawRepository::getDirectDraw(); return nullptr != g_directDraw; } diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index 142578d..a64cdc2 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -160,6 +160,7 @@ + @@ -196,6 +197,7 @@ + diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index d85158d..52422f7 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -99,6 +99,9 @@ Header Files + + Header Files + @@ -170,6 +173,9 @@ Source Files + + Source Files + diff --git a/DDrawCompat/DDrawRepository.cpp b/DDrawCompat/DDrawRepository.cpp new file mode 100644 index 0000000..fe58ce6 --- /dev/null +++ b/DDrawCompat/DDrawRepository.cpp @@ -0,0 +1,38 @@ +#include "CompatDirectDraw.h" +#include "DDrawLog.h" +#include "DDrawProcs.h" +#include "DDrawRepository.h" + +namespace +{ + IDirectDraw7* createDirectDraw() + { + IDirectDraw7* dd = nullptr; + HRESULT result = CALL_ORIG_DDRAW(DirectDrawCreateEx, nullptr, + reinterpret_cast(&dd), IID_IDirectDraw7, nullptr); + if (FAILED(result)) + { + Compat::Log() << "Failed to create a DirectDraw object in the repository: " << result; + return nullptr; + } + + result = dd->lpVtbl->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL); + if (FAILED(result)) + { + Compat::Log() << "Failed to set the cooperative level in the repository: " << result; + dd->lpVtbl->Release(dd); + return nullptr; + } + + return dd; + } +} + +namespace DDrawRepository +{ + IDirectDraw7* getDirectDraw() + { + static IDirectDraw7* dd = createDirectDraw(); + return dd; + } +} diff --git a/DDrawCompat/DDrawRepository.h b/DDrawCompat/DDrawRepository.h new file mode 100644 index 0000000..6994c17 --- /dev/null +++ b/DDrawCompat/DDrawRepository.h @@ -0,0 +1,10 @@ +#pragma once + +#define CINTERFACE + +#include + +namespace DDrawRepository +{ + IDirectDraw7* getDirectDraw(); +} diff --git a/DDrawCompat/DllMain.cpp b/DDrawCompat/DllMain.cpp index 423c2e8..e0fb0cc 100644 --- a/DDrawCompat/DllMain.cpp +++ b/DDrawCompat/DllMain.cpp @@ -12,6 +12,7 @@ #include "CompatRegistry.h" #include "CompatVtable.h" #include "DDrawProcs.h" +#include "DDrawRepository.h" struct IDirectInput; @@ -31,7 +32,7 @@ namespace } } - void hookDirectDraw(IDirectDraw& dd) + void hookDirectDraw(IDirectDraw7& dd) { IUnknown& ddUnk = reinterpret_cast(dd); hookVtable>(IID_IDirectDraw, ddUnk); @@ -40,17 +41,17 @@ namespace hookVtable>(IID_IDirectDraw7, ddUnk); } - void hookDirectDrawSurface(IDirectDraw& dd) + void hookDirectDrawSurface(IDirectDraw7& dd) { - DDSURFACEDESC desc = {}; + DDSURFACEDESC2 desc = {}; desc.dwSize = sizeof(desc); desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; desc.dwWidth = 1; desc.dwHeight = 1; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; - IDirectDrawSurface* surface = nullptr; - HRESULT result = CompatDirectDraw::s_origVtable.CreateSurface(&dd, &desc, &surface, nullptr); + IDirectDrawSurface7* surface = nullptr; + HRESULT result = CompatDirectDraw::s_origVtable.CreateSurface(&dd, &desc, &surface, nullptr); if (SUCCEEDED(result)) { IUnknown& surfaceUnk = reinterpret_cast(*surface); @@ -67,11 +68,11 @@ namespace } } - void hookDirectDrawPalette(IDirectDraw& dd) + void hookDirectDrawPalette(IDirectDraw7& dd) { PALETTEENTRY paletteEntries[2] = {}; IDirectDrawPalette* palette = nullptr; - HRESULT result = CompatDirectDraw::s_origVtable.CreatePalette( + HRESULT result = CompatDirectDraw::s_origVtable.CreatePalette( &dd, DDPCAPS_1BIT, paletteEntries, &palette, nullptr); if (SUCCEEDED(result)) { @@ -90,12 +91,9 @@ namespace if (!isAlreadyInstalled) { Compat::Log() << "Installing DirectDraw hooks"; - IDirectDraw* dd = nullptr; - HRESULT result = CALL_ORIG_DDRAW(DirectDrawCreate, nullptr, &dd, nullptr); - if (SUCCEEDED(result)) + IDirectDraw7* dd = DDrawRepository::getDirectDraw(); + if (dd) { - dd->lpVtbl->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL); - hookDirectDraw(*dd); hookDirectDrawSurface(*dd); hookDirectDrawPalette(*dd); @@ -106,13 +104,8 @@ namespace Compat::Log() << "Installing registry hooks"; CompatRegistry::installHooks(); - dd->lpVtbl->Release(dd); + Compat::Log() << "Finished installing hooks"; } - else - { - Compat::Log() << "Failed to create a DirectDraw object for hooking" << result; - } - Compat::Log() << "Finished installing hooks"; isAlreadyInstalled = true; } }