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

Replaced IDirectDraw raw pointers with smart pointers

This commit is contained in:
narzoul 2016-05-16 22:01:52 +02:00
parent 068cdb8028
commit e8f4a970e0
15 changed files with 130 additions and 126 deletions

View File

@ -4,6 +4,7 @@
#include "CompatGdi.h" #include "CompatGdi.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
#include "CompatPtr.h" #include "CompatPtr.h"
#include "CompatRef.h"
#include "DDrawLog.h" #include "DDrawLog.h"
extern HWND g_mainWindow; extern HWND g_mainWindow;
@ -11,14 +12,14 @@ extern HWND g_mainWindow;
namespace namespace
{ {
bool g_isActive = true; bool g_isActive = true;
IUnknown* g_fullScreenDirectDraw = nullptr; CompatWeakPtr<IUnknown> g_fullScreenDirectDraw = nullptr;
HWND g_fullScreenCooperativeWindow = nullptr; HWND g_fullScreenCooperativeWindow = nullptr;
DWORD g_fullScreenCooperativeFlags = 0; DWORD g_fullScreenCooperativeFlags = 0;
HHOOK g_callWndProcHook = nullptr; HHOOK g_callWndProcHook = nullptr;
void handleActivateApp(bool isActivated); void handleActivateApp(bool isActivated);
void activateApp(IDirectDraw7& dd) void activateApp(CompatRef<IDirectDraw7> dd)
{ {
if (!(g_fullScreenCooperativeFlags & DDSCL_NOWINDOWCHANGES)) if (!(g_fullScreenCooperativeFlags & DDSCL_NOWINDOWCHANGES))
{ {
@ -30,13 +31,11 @@ namespace
} }
} }
CompatDirectDraw<IDirectDraw7>::s_origVtable.SetCooperativeLevel( dd->SetCooperativeLevel(&dd, g_fullScreenCooperativeWindow, g_fullScreenCooperativeFlags);
&dd, g_fullScreenCooperativeWindow, g_fullScreenCooperativeFlags);
if (CompatPrimarySurface::isDisplayModeChanged) if (CompatPrimarySurface::isDisplayModeChanged)
{ {
const CompatPrimarySurface::DisplayMode& dm = CompatPrimarySurface::displayMode; const CompatPrimarySurface::DisplayMode& dm = CompatPrimarySurface::displayMode;
CompatDirectDraw<IDirectDraw7>::s_origVtable.SetDisplayMode( dd->SetDisplayMode(&dd, dm.width, dm.height, 32, dm.refreshRate, 0);
&dd, dm.width, dm.height, 32, dm.refreshRate, 0);
} }
auto primary(CompatPrimarySurface::getPrimary()); auto primary(CompatPrimarySurface::getPrimary());
@ -47,14 +46,13 @@ namespace
} }
} }
void deactivateApp(IDirectDraw7& dd) void deactivateApp(CompatRef<IDirectDraw7> dd)
{ {
if (CompatPrimarySurface::isDisplayModeChanged) if (CompatPrimarySurface::isDisplayModeChanged)
{ {
CompatDirectDraw<IDirectDraw7>::s_origVtable.RestoreDisplayMode(&dd); dd->RestoreDisplayMode(&dd);
} }
CompatDirectDraw<IDirectDraw7>::s_origVtable.SetCooperativeLevel( dd->SetCooperativeLevel(&dd, g_fullScreenCooperativeWindow, DDSCL_NORMAL);
&dd, g_fullScreenCooperativeWindow, DDSCL_NORMAL);
if (!(g_fullScreenCooperativeFlags & DDSCL_NOWINDOWCHANGES)) if (!(g_fullScreenCooperativeFlags & DDSCL_NOWINDOWCHANGES))
{ {
@ -95,10 +93,7 @@ namespace
if (g_fullScreenDirectDraw) if (g_fullScreenDirectDraw)
{ {
IDirectDraw7* dd = nullptr; CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(g_fullScreenDirectDraw.get()));
g_fullScreenDirectDraw->lpVtbl->QueryInterface(
g_fullScreenDirectDraw, IID_IDirectDraw7, reinterpret_cast<void**>(&dd));
if (isActivated) if (isActivated)
{ {
activateApp(*dd); activateApp(*dd);
@ -107,8 +102,6 @@ namespace
{ {
deactivateApp(*dd); deactivateApp(*dd);
} }
CompatDirectDraw<IDirectDraw7>::s_origVtable.Release(dd);
} }
if (isActivated) if (isActivated)
@ -133,7 +126,7 @@ namespace CompatActivateAppHandler
return g_isActive; return g_isActive;
} }
void setFullScreenCooperativeLevel(IUnknown* dd, HWND hwnd, DWORD flags) void setFullScreenCooperativeLevel(CompatWeakPtr<IUnknown> dd, HWND hwnd, DWORD flags)
{ {
g_fullScreenDirectDraw = dd; g_fullScreenDirectDraw = dd;
g_fullScreenCooperativeWindow = hwnd; g_fullScreenCooperativeWindow = hwnd;

View File

@ -1,15 +1,17 @@
#pragma once #pragma once
#define CINTERFACE
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
#include <Unknwnbase.h>
struct IUnknown; #include "CompatWeakPtr.h"
namespace CompatActivateAppHandler namespace CompatActivateAppHandler
{ {
void installHooks(); void installHooks();
bool isActive(); bool isActive();
void setFullScreenCooperativeLevel(IUnknown* dd, HWND hwnd, DWORD flags); void setFullScreenCooperativeLevel(CompatWeakPtr<IUnknown> dd, HWND hwnd, DWORD flags);
void uninstallHooks(); void uninstallHooks();
} }

View File

@ -3,6 +3,7 @@
#include "CompatDirectDrawSurface.h" #include "CompatDirectDrawSurface.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
#include "CompatPtr.h" #include "CompatPtr.h"
#include "CompatRef.h"
#include "IReleaseNotifier.h" #include "IReleaseNotifier.h"
namespace namespace
@ -24,7 +25,7 @@ namespace
IReleaseNotifier g_fullScreenTagSurfaceReleaseNotifier(&onReleaseFullScreenTagSurface); IReleaseNotifier g_fullScreenTagSurfaceReleaseNotifier(&onReleaseFullScreenTagSurface);
CompatPtr<IDirectDrawSurface> createFullScreenTagSurface(IDirectDraw& dd) CompatPtr<IDirectDrawSurface> createFullScreenTagSurface(CompatRef<IDirectDraw> dd)
{ {
DDSURFACEDESC desc = {}; DDSURFACEDESC desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
@ -34,7 +35,7 @@ namespace
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
CompatPtr<IDirectDrawSurface> tagSurface; CompatPtr<IDirectDrawSurface> tagSurface;
CompatDirectDraw<IDirectDraw>::s_origVtable.CreateSurface(&dd, &desc, &tagSurface.getRef(), nullptr); dd->CreateSurface(&dd, &desc, &tagSurface.getRef(), nullptr);
if (tagSurface) if (tagSurface)
{ {
CompatPtr<IDirectDrawSurface7> tagSurface7(tagSurface); CompatPtr<IDirectDrawSurface7> tagSurface7(tagSurface);
@ -71,11 +72,10 @@ namespace
g_fullScreenTagSurface = nullptr; g_fullScreenTagSurface = nullptr;
} }
template <typename TDirectDraw> HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP,
HRESULT setDisplayMode(TDirectDraw* This, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP,
DWORD dwRefreshRate, DWORD dwFlags) DWORD dwRefreshRate, DWORD dwFlags)
{ {
typename Types<TDirectDraw>::TSurfaceDesc desc = {}; DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
desc.dwWidth = dwWidth; desc.dwWidth = dwWidth;
@ -95,8 +95,8 @@ namespace
DDPIXELFORMAT pf = {}; DDPIXELFORMAT pf = {};
if (dwBPP > 8) if (dwBPP > 8)
{ {
if (FAILED(CompatDirectDraw<TDirectDraw>::s_origVtable.EnumDisplayModes( if (FAILED(dd->EnumDisplayModes(&dd, 0, &desc, &pf, &enumDisplayModesCallback)) ||
This, 0, &desc, &pf, &enumDisplayModesCallback)) || 0 == pf.dwSize) 0 == pf.dwSize)
{ {
Compat::Log() << "Failed to find the requested display mode: " << Compat::Log() << "Failed to find the requested display mode: " <<
dwWidth << "x" << dwHeight << "x" << dwBPP; dwWidth << "x" << dwHeight << "x" << dwBPP;
@ -108,8 +108,7 @@ namespace
pf = desc.ddpfPixelFormat; pf = desc.ddpfPixelFormat;
} }
HRESULT result = CompatDirectDraw<TDirectDraw>::s_origVtable.SetDisplayMode( HRESULT result = dd->SetDisplayMode(&dd, dwWidth, dwHeight, 32, dwRefreshRate, dwFlags);
This, dwWidth, dwHeight, 32, dwRefreshRate, dwFlags);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
CompatPrimarySurface::displayMode.width = dwWidth; CompatPrimarySurface::displayMode.width = dwWidth;
@ -126,17 +125,12 @@ namespace
return result; return result;
} }
HRESULT setDisplayMode(IDirectDraw* This, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP) HRESULT setDisplayMode(CompatRef<IDirectDraw7> dd, DWORD dwWidth, DWORD dwHeight, DWORD dwBPP)
{ {
IDirectDraw7* dd = nullptr; return setDisplayMode(dd, dwWidth, dwHeight, dwBPP, 0, 0);
CompatDirectDraw<IDirectDraw>::s_origVtable.QueryInterface(
This, IID_IDirectDraw7, reinterpret_cast<void**>(&dd));
HRESULT result = setDisplayMode(dd, dwWidth, dwHeight, dwBPP, 0, 0);
CompatDirectDraw<IDirectDraw7>::s_origVtable.Release(dd);
return result;
} }
void setFullScreenDirectDraw(IDirectDraw& dd) void setFullScreenDirectDraw(CompatRef<IDirectDraw> dd)
{ {
g_fullScreenTagSurface.release(); g_fullScreenTagSurface.release();
g_fullScreenTagSurface = createFullScreenTagSurface(dd).detach(); g_fullScreenTagSurface = createFullScreenTagSurface(dd).detach();
@ -156,7 +150,7 @@ namespace
static DirectDrawInterface fullScreenDirectDraw = {}; static DirectDrawInterface fullScreenDirectDraw = {};
ZeroMemory(&fullScreenDirectDraw, sizeof(fullScreenDirectDraw)); ZeroMemory(&fullScreenDirectDraw, sizeof(fullScreenDirectDraw));
DirectDrawInterface& ddIntf = reinterpret_cast<DirectDrawInterface&>(dd); DirectDrawInterface& ddIntf = reinterpret_cast<DirectDrawInterface&>(dd.get());
fullScreenDirectDraw.vtable = ddIntf.vtable; fullScreenDirectDraw.vtable = ddIntf.vtable;
fullScreenDirectDraw.ddObject = ddIntf.ddObject; fullScreenDirectDraw.ddObject = ddIntf.ddObject;
g_fullScreenDirectDraw = &fullScreenDirectDraw; g_fullScreenDirectDraw = &fullScreenDirectDraw;
@ -187,7 +181,7 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::CreateSurface(
if (isPrimary) if (isPrimary)
{ {
result = CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface( result = CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface<TDirectDraw>(
*This, *lpDDSurfaceDesc, *lplpDDSurface); *This, *lpDDSurfaceDesc, *lplpDDSurface);
} }
else else
@ -224,7 +218,8 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::RestoreDisplayMode(TDir
HRESULT result = s_origVtable.RestoreDisplayMode(This); HRESULT result = s_origVtable.RestoreDisplayMode(This);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
CompatPrimarySurface::displayMode = CompatPrimarySurface::getDisplayMode(*This); CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
CompatPrimarySurface::displayMode = CompatPrimarySurface::getDisplayMode(*dd);
CompatPrimarySurface::isDisplayModeChanged = false; CompatPrimarySurface::isDisplayModeChanged = false;
} }
return result; return result;
@ -244,12 +239,10 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::SetCooperativeLevel(
{ {
if (dwFlags & DDSCL_FULLSCREEN) if (dwFlags & DDSCL_FULLSCREEN)
{ {
IDirectDraw* dd = nullptr; CompatPtr<IDirectDraw> dd(Compat::queryInterface<IDirectDraw>(This));
s_origVtable.QueryInterface(This, IID_IDirectDraw, reinterpret_cast<void**>(&dd));
setFullScreenDirectDraw(*dd); setFullScreenDirectDraw(*dd);
CompatActivateAppHandler::setFullScreenCooperativeLevel( CompatActivateAppHandler::setFullScreenCooperativeLevel(
reinterpret_cast<IUnknown*>(g_fullScreenDirectDraw), hWnd, dwFlags); reinterpret_cast<IUnknown*>(g_fullScreenDirectDraw), hWnd, dwFlags);
CompatDirectDraw<IDirectDraw>::s_origVtable.Release(dd);
} }
else if (isFullScreenDirectDraw(This) && g_fullScreenTagSurface) else if (isFullScreenDirectDraw(This) && g_fullScreenTagSurface)
{ {
@ -268,9 +261,15 @@ HRESULT STDMETHODCALLTYPE CompatDirectDraw<TDirectDraw>::SetDisplayMode(
DWORD dwBPP, DWORD dwBPP,
Params... params) Params... params)
{ {
return setDisplayMode(This, dwWidth, dwHeight, dwBPP, params...); CompatPtr<IDirectDraw7> dd(Compat::queryInterface<IDirectDraw7>(This));
return setDisplayMode(*dd, dwWidth, dwHeight, dwBPP, params...);
} }
template <> const IID& CompatDirectDraw<IDirectDraw>::s_iid = IID_IDirectDraw;
template <> const IID& CompatDirectDraw<IDirectDraw2>::s_iid = IID_IDirectDraw2;
template <> const IID& CompatDirectDraw<IDirectDraw4>::s_iid = IID_IDirectDraw4;
template <> const IID& CompatDirectDraw<IDirectDraw7>::s_iid = IID_IDirectDraw7;
template CompatDirectDraw<IDirectDraw>; template CompatDirectDraw<IDirectDraw>;
template CompatDirectDraw<IDirectDraw2>; template CompatDirectDraw<IDirectDraw2>;
template CompatDirectDraw<IDirectDraw4>; template CompatDirectDraw<IDirectDraw4>;

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <type_traits>
#include "CompatVtable.h" #include "CompatVtable.h"
#include "DDrawTypes.h" #include "DDrawTypes.h"
#include "DirectDrawVtblVisitor.h" #include "DirectDrawVtblVisitor.h"
@ -29,4 +31,42 @@ public:
DWORD dwHeight, DWORD dwHeight,
DWORD dwBPP, DWORD dwBPP,
Params... params); Params... params);
static const IID& s_iid;
}; };
namespace Compat
{
template <typename Intf>
struct IsDirectDrawIntf : std::false_type {};
template<> struct IsDirectDrawIntf<IDirectDraw> : std::true_type {};
template<> struct IsDirectDrawIntf<IDirectDraw2> : std::true_type {};
template<> struct IsDirectDrawIntf<IDirectDraw4> : std::true_type {};
template<> struct IsDirectDrawIntf<IDirectDraw7> : std::true_type {};
template <typename NewIntf, typename OrigIntf>
std::enable_if_t<IsDirectDrawIntf<NewIntf>::value && IsDirectDrawIntf<OrigIntf>::value>
queryInterface(OrigIntf& origIntf, NewIntf*& newIntf)
{
CompatDirectDraw<OrigIntf>::s_origVtable.QueryInterface(
&origIntf, CompatDirectDraw<NewIntf>::s_iid, reinterpret_cast<void**>(&newIntf));
}
template <typename NewIntf>
std::enable_if_t<IsDirectDrawIntf<NewIntf>::value>
queryInterface(IUnknown& origIntf, NewIntf*& newIntf)
{
CompatDirectDraw<IDirectDraw>::s_origVtable.QueryInterface(
reinterpret_cast<IDirectDraw*>(&origIntf),
CompatDirectDraw<NewIntf>::s_iid, reinterpret_cast<void**>(&newIntf));
}
template <typename OrigIntf>
std::enable_if_t<IsDirectDrawIntf<OrigIntf>::value>
queryInterface(OrigIntf& origIntf, IUnknown*& newIntf)
{
CompatDirectDraw<OrigIntf>::s_origVtable.QueryInterface(
&origIntf, IID_IUnknown, reinterpret_cast<void**>(&newIntf));
}
}

View File

@ -174,13 +174,14 @@ void CompatDirectDrawSurface<TSurface>::setCompatVtable(Vtable<TSurface>& vtable
template <typename TSurface> template <typename TSurface>
template <typename TDirectDraw> template <typename TDirectDraw>
HRESULT CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface( HRESULT CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface(
TDirectDraw& dd, CompatRef<TDirectDraw> dd,
TSurfaceDesc compatDesc, TSurfaceDesc compatDesc,
TSurface*& compatSurface) TSurface*& compatSurface)
{ {
if (0 == CompatPrimarySurface::displayMode.pixelFormat.dwSize) if (0 == CompatPrimarySurface::displayMode.pixelFormat.dwSize)
{ {
CompatPrimarySurface::displayMode = CompatPrimarySurface::getDisplayMode(dd); CompatPtr<IDirectDraw7> dd7(Compat::queryInterface<IDirectDraw7>(&dd));
CompatPrimarySurface::displayMode = CompatPrimarySurface::getDisplayMode(*dd7);
} }
HRESULT result = RealPrimarySurface::create(dd); HRESULT result = RealPrimarySurface::create(dd);
@ -200,8 +201,7 @@ HRESULT CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface(
compatDesc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; compatDesc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
compatDesc.ddpfPixelFormat = CompatPrimarySurface::pixelFormat; compatDesc.ddpfPixelFormat = CompatPrimarySurface::pixelFormat;
result = CompatDirectDraw<TDirectDraw>::s_origVtable.CreateSurface( result = dd->CreateSurface(&dd, &compatDesc, &compatSurface, nullptr);
&dd, &compatDesc, &compatSurface, nullptr);
if (FAILED(result)) if (FAILED(result))
{ {
Compat::Log() << "Failed to create the compat primary surface!"; Compat::Log() << "Failed to create the compat primary surface!";
@ -551,18 +551,18 @@ template CompatDirectDrawSurface<IDirectDrawSurface4>;
template CompatDirectDrawSurface<IDirectDrawSurface7>; template CompatDirectDrawSurface<IDirectDrawSurface7>;
template HRESULT CompatDirectDrawSurface<IDirectDrawSurface>::createCompatPrimarySurface( template HRESULT CompatDirectDrawSurface<IDirectDrawSurface>::createCompatPrimarySurface(
IDirectDraw& dd, CompatRef<IDirectDraw> dd,
TSurfaceDesc compatDesc, TSurfaceDesc compatDesc,
IDirectDrawSurface*& compatSurface); IDirectDrawSurface*& compatSurface);
template HRESULT CompatDirectDrawSurface<IDirectDrawSurface>::createCompatPrimarySurface( template HRESULT CompatDirectDrawSurface<IDirectDrawSurface>::createCompatPrimarySurface(
IDirectDraw2& dd, CompatRef<IDirectDraw2> dd,
TSurfaceDesc compatDesc, TSurfaceDesc compatDesc,
IDirectDrawSurface*& compatSurface); IDirectDrawSurface*& compatSurface);
template HRESULT CompatDirectDrawSurface<IDirectDrawSurface4>::createCompatPrimarySurface( template HRESULT CompatDirectDrawSurface<IDirectDrawSurface4>::createCompatPrimarySurface(
IDirectDraw4& dd, CompatRef<IDirectDraw4> dd,
TSurfaceDesc compatDesc, TSurfaceDesc compatDesc,
IDirectDrawSurface4*& compatSurface); IDirectDrawSurface4*& compatSurface);
template HRESULT CompatDirectDrawSurface<IDirectDrawSurface7>::createCompatPrimarySurface( template HRESULT CompatDirectDrawSurface<IDirectDrawSurface7>::createCompatPrimarySurface(
IDirectDraw7& dd, CompatRef<IDirectDraw7> dd,
TSurfaceDesc compatDesc, TSurfaceDesc compatDesc,
IDirectDrawSurface7*& compatSurface); IDirectDrawSurface7*& compatSurface);

View File

@ -19,7 +19,7 @@ public:
template <typename TDirectDraw> template <typename TDirectDraw>
static HRESULT createCompatPrimarySurface( static HRESULT createCompatPrimarySurface(
TDirectDraw& dd, CompatRef<TDirectDraw> dd,
TSurfaceDesc compatDesc, TSurfaceDesc compatDesc,
TSurface*& compatSurface); TSurface*& compatSurface);

View File

@ -1,7 +1,6 @@
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#include "CompatDirectDraw.h"
#include "CompatDirectDrawPalette.h" #include "CompatDirectDrawPalette.h"
#include "CompatGdiDcCache.h" #include "CompatGdiDcCache.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
@ -21,7 +20,6 @@ namespace
DWORD g_maxUsedCacheSize = 0; DWORD g_maxUsedCacheSize = 0;
DWORD g_ddLockThreadId = 0; DWORD g_ddLockThreadId = 0;
IDirectDraw7* g_directDraw = nullptr;
IDirectDrawPalette* g_palette = nullptr; IDirectDrawPalette* g_palette = nullptr;
PALETTEENTRY g_paletteEntries[256] = {}; PALETTEENTRY g_paletteEntries[256] = {};
void* g_surfaceMemory = nullptr; void* g_surfaceMemory = nullptr;
@ -68,9 +66,9 @@ namespace
desc.lPitch = g_pitch; desc.lPitch = g_pitch;
desc.lpSurface = g_surfaceMemory; desc.lpSurface = g_surfaceMemory;
auto dd(DDrawRepository::getDirectDraw());
CompatPtr<IDirectDrawSurface7> surface; CompatPtr<IDirectDrawSurface7> surface;
HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface( HRESULT result = dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
g_directDraw, &desc, &surface.getRef(), nullptr);
if (FAILED(result)) if (FAILED(result))
{ {
LOG_ONCE("Failed to create a GDI surface: " << result); LOG_ONCE("Failed to create a GDI surface: " << result);
@ -168,13 +166,9 @@ namespace CompatGdiDcCache
bool init() bool init()
{ {
g_directDraw = DDrawRepository::getDirectDraw(); auto dd(DDrawRepository::getDirectDraw());
if (g_directDraw) dd->CreatePalette(dd, DDPCAPS_8BIT | DDPCAPS_ALLOW256, g_paletteEntries, &g_palette, nullptr);
{ return nullptr != g_palette;
CompatDirectDraw<IDirectDraw7>::s_origVtable.CreatePalette(
g_directDraw, DDPCAPS_8BIT | DDPCAPS_ALLOW256, g_paletteEntries, &g_palette, nullptr);
}
return nullptr != g_directDraw;
} }
void releaseDc(const CachedDc& cachedDc) void releaseDc(const CachedDc& cachedDc)

View File

@ -1,7 +1,6 @@
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include "CompatDirectDraw.h"
#include "CompatDirectDrawPalette.h" #include "CompatDirectDrawPalette.h"
#include "CompatPaletteConverter.h" #include "CompatPaletteConverter.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
@ -50,12 +49,6 @@ namespace
CompatPtr<IDirectDrawSurface7> createSurface(const DDSURFACEDESC2& primaryDesc, void* bits) CompatPtr<IDirectDrawSurface7> createSurface(const DDSURFACEDESC2& primaryDesc, void* bits)
{ {
IDirectDraw7* dd = DDrawRepository::getDirectDraw();
if (!dd)
{
return nullptr;
}
DDSURFACEDESC2 desc = {}; DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS |
@ -67,8 +60,9 @@ namespace
desc.lPitch = (primaryDesc.dwWidth + 3) & ~3; desc.lPitch = (primaryDesc.dwWidth + 3) & ~3;
desc.lpSurface = bits; desc.lpSurface = bits;
auto dd(DDrawRepository::getDirectDraw());
CompatPtr<IDirectDrawSurface7> surface; CompatPtr<IDirectDrawSurface7> surface;
CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(dd, &desc, &surface.getRef(), nullptr); dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
return surface; return surface;
} }
} }

View File

@ -1,7 +1,6 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include "CompatDirectDraw.h"
#include "CompatDirectDrawSurface.h" #include "CompatDirectDrawSurface.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
#include "CompatPtr.h" #include "CompatPtr.h"
@ -33,13 +32,12 @@ namespace
namespace CompatPrimarySurface namespace CompatPrimarySurface
{ {
template <typename TDirectDraw> DisplayMode getDisplayMode(CompatRef<IDirectDraw7> dd)
DisplayMode getDisplayMode(TDirectDraw& dd)
{ {
DisplayMode dm = {}; DisplayMode dm = {};
typename CompatDirectDraw<TDirectDraw>::TSurfaceDesc desc = {}; DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
CompatDirectDraw<TDirectDraw>::s_origVtable.GetDisplayMode(&dd, &desc); dd->GetDisplayMode(&dd, &desc);
dm.width = desc.dwWidth; dm.width = desc.dwWidth;
dm.height = desc.dwHeight; dm.height = desc.dwHeight;
dm.pixelFormat = desc.ddpfPixelFormat; dm.pixelFormat = desc.ddpfPixelFormat;
@ -47,11 +45,6 @@ namespace CompatPrimarySurface
return dm; return dm;
} }
template DisplayMode getDisplayMode(IDirectDraw& dd);
template DisplayMode getDisplayMode(IDirectDraw2& dd);
template DisplayMode getDisplayMode(IDirectDraw4& dd);
template DisplayMode getDisplayMode(IDirectDraw7& dd);
CompatPtr<IDirectDrawSurface7> getPrimary() CompatPtr<IDirectDrawSurface7> getPrimary()
{ {
if (!g_primarySurface) if (!g_primarySurface)

View File

@ -19,8 +19,7 @@ namespace CompatPrimarySurface
DWORD refreshRate; DWORD refreshRate;
}; };
template <typename TDirectDraw> DisplayMode getDisplayMode(CompatRef<IDirectDraw7> dd);
DisplayMode getDisplayMode(TDirectDraw& dd);
CompatPtr<IDirectDrawSurface7> getPrimary(); CompatPtr<IDirectDrawSurface7> getPrimary();
bool isPrimary(void* surface); bool isPrimary(void* surface);

View File

@ -1,7 +1,6 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include "CompatDirectDraw.h"
#include "CompatPtr.h" #include "CompatPtr.h"
#include "DDrawLog.h" #include "DDrawLog.h"
#include "DDrawProcs.h" #include "DDrawProcs.h"
@ -14,7 +13,7 @@ namespace
static std::vector<Surface> g_sysMemSurfaces; static std::vector<Surface> g_sysMemSurfaces;
static std::vector<Surface> g_vidMemSurfaces; static std::vector<Surface> g_vidMemSurfaces;
IDirectDraw7* createDirectDraw(); CompatPtr<IDirectDraw7> createDirectDraw();
Surface createSurface(DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps); Surface createSurface(DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps);
std::vector<Surface>::iterator findSurface(DWORD width, DWORD height, const DDPIXELFORMAT& pf, std::vector<Surface>::iterator findSurface(DWORD width, DWORD height, const DDPIXELFORMAT& pf,
std::vector<Surface>& cachedSurfaces); std::vector<Surface>& cachedSurfaces);
@ -24,22 +23,21 @@ namespace
void normalizePixelFormat(DDPIXELFORMAT& pf); void normalizePixelFormat(DDPIXELFORMAT& pf);
void returnSurface(const Surface& surface); void returnSurface(const Surface& surface);
IDirectDraw7* createDirectDraw() CompatPtr<IDirectDraw7> createDirectDraw()
{ {
IDirectDraw7* dd = nullptr; CompatPtr<IDirectDraw7> dd;
HRESULT result = CALL_ORIG_DDRAW(DirectDrawCreateEx, nullptr, HRESULT result = CALL_ORIG_DDRAW(DirectDrawCreateEx, nullptr,
reinterpret_cast<void**>(&dd), IID_IDirectDraw7, nullptr); reinterpret_cast<void**>(&dd.getRef()), IID_IDirectDraw7, nullptr);
if (FAILED(result)) if (FAILED(result))
{ {
Compat::Log() << "Failed to create a DirectDraw object in the repository: " << result; Compat::Log() << "Failed to create a DirectDraw object in the repository: " << result;
return nullptr; return nullptr;
} }
result = dd->lpVtbl->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL); result = dd->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL);
if (FAILED(result)) if (FAILED(result))
{ {
Compat::Log() << "Failed to set the cooperative level in the repository: " << result; Compat::Log() << "Failed to set the cooperative level in the repository: " << result;
dd->lpVtbl->Release(dd);
return nullptr; return nullptr;
} }
@ -49,11 +47,6 @@ namespace
Surface createSurface(DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps) Surface createSurface(DWORD width, DWORD height, const DDPIXELFORMAT& pf, DWORD caps)
{ {
Surface surface = {}; Surface surface = {};
IDirectDraw7* dd = DDrawRepository::getDirectDraw();
if (!dd)
{
return surface;
}
surface.desc.dwSize = sizeof(surface.desc); surface.desc.dwSize = sizeof(surface.desc);
surface.desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS; surface.desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
@ -62,8 +55,8 @@ namespace
surface.desc.ddpfPixelFormat = pf; surface.desc.ddpfPixelFormat = pf;
surface.desc.ddsCaps.dwCaps = caps; surface.desc.ddsCaps.dwCaps = caps;
CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface( auto dd(DDrawRepository::getDirectDraw());
dd, &surface.desc, &surface.surface.getRef(), nullptr); dd->CreateSurface(dd, &surface.desc, &surface.surface.getRef(), nullptr);
return surface; return surface;
} }
@ -177,9 +170,9 @@ namespace DDrawRepository
returnSurface(*this); returnSurface(*this);
} }
IDirectDraw7* getDirectDraw() CompatWeakPtr<IDirectDraw7> getDirectDraw()
{ {
static IDirectDraw7* dd = createDirectDraw(); static auto dd = new CompatPtr<IDirectDraw7>(createDirectDraw());
return dd; return *dd;
} }
} }

View File

@ -21,5 +21,5 @@ namespace DDrawRepository
~ScopedSurface(); ~ScopedSurface();
}; };
IDirectDraw7* getDirectDraw(); CompatWeakPtr<IDirectDraw7> getDirectDraw();
} }

View File

@ -42,16 +42,18 @@ namespace
CompatInterface::hookVtable(*intf); CompatInterface::hookVtable(*intf);
} }
void hookDirectDraw(IDirectDraw7& dd) void hookDirectDraw(CompatRef<IDirectDraw7> dd)
{ {
IUnknown& ddUnk = reinterpret_cast<IUnknown&>(dd); CompatDirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl;
hookVtable<CompatDirectDraw<IDirectDraw>>(IID_IDirectDraw, ddUnk); CompatPtr<IDirectDraw7> dd7(&dd);
hookVtable<CompatDirectDraw<IDirectDraw2>>(IID_IDirectDraw2, ddUnk); hookVtable<CompatDirectDraw<IDirectDraw>>(dd7);
hookVtable<CompatDirectDraw<IDirectDraw4>>(IID_IDirectDraw4, ddUnk); hookVtable<CompatDirectDraw<IDirectDraw2>>(dd7);
hookVtable<CompatDirectDraw<IDirectDraw7>>(IID_IDirectDraw7, ddUnk); hookVtable<CompatDirectDraw<IDirectDraw4>>(dd7);
hookVtable<CompatDirectDraw<IDirectDraw7>>(dd7);
dd7.detach();
} }
void hookDirectDrawSurface(IDirectDraw7& dd) void hookDirectDrawSurface(CompatRef<IDirectDraw7> dd)
{ {
DDSURFACEDESC2 desc = {}; DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
@ -61,8 +63,7 @@ namespace
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
CompatPtr<IDirectDrawSurface7> surface; CompatPtr<IDirectDrawSurface7> surface;
HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface( HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
&dd, &desc, &surface.getRef(), nullptr);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable = *surface.get()->lpVtbl; CompatDirectDrawSurface<IDirectDrawSurface7>::s_origVtable = *surface.get()->lpVtbl;
@ -78,12 +79,11 @@ namespace
} }
} }
void hookDirectDrawPalette(IDirectDraw7& dd) void hookDirectDrawPalette(CompatRef<IDirectDraw7> dd)
{ {
PALETTEENTRY paletteEntries[2] = {}; PALETTEENTRY paletteEntries[2] = {};
IDirectDrawPalette* palette = nullptr; IDirectDrawPalette* palette = nullptr;
HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreatePalette( HRESULT result = dd->CreatePalette(&dd, DDPCAPS_1BIT, paletteEntries, &palette, nullptr);
&dd, DDPCAPS_1BIT, paletteEntries, &palette, nullptr);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
CompatDirectDrawPalette::hookVtable(*palette); CompatDirectDrawPalette::hookVtable(*palette);
@ -101,7 +101,7 @@ namespace
if (!isAlreadyInstalled) if (!isAlreadyInstalled)
{ {
Compat::Log() << "Installing DirectDraw hooks"; Compat::Log() << "Installing DirectDraw hooks";
IDirectDraw7* dd = DDrawRepository::getDirectDraw(); auto dd(DDrawRepository::getDirectDraw());
if (dd) if (dd)
{ {
hookDirectDraw(*dd); hookDirectDraw(*dd);

View File

@ -1,13 +1,11 @@
#include <atomic> #include <atomic>
#include "CompatDirectDraw.h"
#include "CompatDirectDrawPalette.h" #include "CompatDirectDrawPalette.h"
#include "CompatDirectDrawSurface.h" #include "CompatDirectDrawSurface.h"
#include "CompatGdi.h" #include "CompatGdi.h"
#include "CompatPaletteConverter.h" #include "CompatPaletteConverter.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
#include "CompatPtr.h" #include "CompatPtr.h"
#include "CompatRef.h"
#include "Config.h" #include "Config.h"
#include "DDrawScopedThreadLock.h" #include "DDrawScopedThreadLock.h"
#include "DDrawProcs.h" #include "DDrawProcs.h"
@ -217,7 +215,7 @@ namespace
} }
template <typename DirectDraw> template <typename DirectDraw>
HRESULT RealPrimarySurface::create(DirectDraw& dd) HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
{ {
typename Types<DirectDraw>::TSurfaceDesc desc = {}; typename Types<DirectDraw>::TSurfaceDesc desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
@ -226,8 +224,7 @@ HRESULT RealPrimarySurface::create(DirectDraw& dd)
desc.dwBackBufferCount = 1; desc.dwBackBufferCount = 1;
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface; CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface;
HRESULT result = CompatDirectDraw<DirectDraw>::s_origVtable.CreateSurface( HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
&dd, &desc, &surface.getRef(), nullptr);
bool isFlippable = true; bool isFlippable = true;
if (DDERR_NOEXCLUSIVEMODE == result) if (DDERR_NOEXCLUSIVEMODE == result)
@ -236,8 +233,7 @@ HRESULT RealPrimarySurface::create(DirectDraw& dd)
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
desc.dwBackBufferCount = 0; desc.dwBackBufferCount = 0;
isFlippable = false; isFlippable = false;
result = CompatDirectDraw<DirectDraw>::s_origVtable.CreateSurface( result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
&dd, &desc, &surface.getRef(), nullptr);
} }
if (FAILED(result)) if (FAILED(result))
@ -249,10 +245,10 @@ HRESULT RealPrimarySurface::create(DirectDraw& dd)
return init(surface); return init(surface);
} }
template HRESULT RealPrimarySurface::create(IDirectDraw&); template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw>);
template HRESULT RealPrimarySurface::create(IDirectDraw2&); template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw2>);
template HRESULT RealPrimarySurface::create(IDirectDraw4&); template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw4>);
template HRESULT RealPrimarySurface::create(IDirectDraw7&); template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw7>);
void RealPrimarySurface::disableUpdates() void RealPrimarySurface::disableUpdates()
{ {

View File

@ -5,12 +5,13 @@
#include <ddraw.h> #include <ddraw.h>
#include "CompatWeakPtr.h" #include "CompatWeakPtr.h"
#include "CompatRef.h"
class RealPrimarySurface class RealPrimarySurface
{ {
public: public:
template <typename DirectDraw> template <typename DirectDraw>
static HRESULT create(DirectDraw& dd); static HRESULT create(CompatRef<DirectDraw> dd);
static void disableUpdates(); static void disableUpdates();
static void enableUpdates(); static void enableUpdates();