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

Introduced a DirectDraw repository for reusable objects

This commit is contained in:
narzoul 2016-03-28 19:48:45 +02:00
parent 0c030f8d57
commit 71e90210ad
7 changed files with 79 additions and 56 deletions

View File

@ -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<void**>(&dd), IID_IDirectDraw7, nullptr);
if (!dd ||
FAILED(CompatDirectDraw<IDirectDraw7>::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<IDirectDraw7>::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<IDirectDraw7>::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<TSurface>::createCompatPrimarySurface(
return result;
}
g_mirrorDirectDraw = createMirrorDirectDraw();
s_compatPrimarySurface = compatSurface;
initCompatPrimarySurface();
return DD_OK;

View File

@ -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<LPVOID*>(&dd), IID_IDirectDraw7, nullptr);
if (!dd)
{
Compat::Log() << "Failed to create a DirectDraw interface for GDI";
return nullptr;
}
if (FAILED(CompatDirectDraw<IDirectDraw7>::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;
}

View File

@ -160,6 +160,7 @@
<ClInclude Include="DDrawProcs.h" />
<ClInclude Include="CompatDirectDraw.h" />
<ClInclude Include="CompatPrimarySurface.h" />
<ClInclude Include="DDrawRepository.h" />
<ClInclude Include="DDrawScopedThreadLock.h" />
<ClInclude Include="DDrawTypes.h" />
<ClInclude Include="CompatDirectDrawSurface.h" />
@ -196,6 +197,7 @@
<ClCompile Include="IReleaseNotifier.cpp" />
<ClCompile Include="RealPrimarySurface.cpp" />
<ClCompile Include="CompatGdiDc.cpp" />
<ClCompile Include="DDrawRepository.cpp" />
<ClCompile Include="UnmodifiedDDrawProcs.cpp" />
</ItemGroup>
<ItemGroup>

View File

@ -99,6 +99,9 @@
<ClInclude Include="CompatRegistry.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DDrawRepository.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="DllMain.cpp">
@ -170,6 +173,9 @@
<ClCompile Include="CompatRegistry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DDrawRepository.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="DDrawCompat.def">

View File

@ -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<void**>(&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;
}
}

View File

@ -0,0 +1,10 @@
#pragma once
#define CINTERFACE
#include <ddraw.h>
namespace DDrawRepository
{
IDirectDraw7* getDirectDraw();
}

View File

@ -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<IUnknown&>(dd);
hookVtable<CompatDirectDraw<IDirectDraw>>(IID_IDirectDraw, ddUnk);
@ -40,17 +41,17 @@ namespace
hookVtable<CompatDirectDraw<IDirectDraw7>>(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<IDirectDraw>::s_origVtable.CreateSurface(&dd, &desc, &surface, nullptr);
IDirectDrawSurface7* surface = nullptr;
HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(&dd, &desc, &surface, nullptr);
if (SUCCEEDED(result))
{
IUnknown& surfaceUnk = reinterpret_cast<IUnknown&>(*surface);
@ -67,11 +68,11 @@ namespace
}
}
void hookDirectDrawPalette(IDirectDraw& dd)
void hookDirectDrawPalette(IDirectDraw7& dd)
{
PALETTEENTRY paletteEntries[2] = {};
IDirectDrawPalette* palette = nullptr;
HRESULT result = CompatDirectDraw<IDirectDraw>::s_origVtable.CreatePalette(
HRESULT result = CompatDirectDraw<IDirectDraw7>::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;
}
}