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 "CompatGdi.h"
#include "CompatPrimarySurface.h" #include "CompatPrimarySurface.h"
#include "DDrawProcs.h" #include "DDrawProcs.h"
#include "DDrawRepository.h"
#include "IReleaseNotifier.h" #include "IReleaseNotifier.h"
#include "RealPrimarySurface.h" #include "RealPrimarySurface.h"
@ -24,21 +25,8 @@ namespace
SimilarSurface getSimilarSurface(const DDSURFACEDESC2& desc); SimilarSurface getSimilarSurface(const DDSURFACEDESC2& desc);
bool mirrorBlt(IDirectDrawSurface7& dst, IDirectDrawSurface7& src, RECT srcRect, DWORD mirrorFx); bool mirrorBlt(IDirectDrawSurface7& dst, IDirectDrawSurface7& src, RECT srcRect, DWORD mirrorFx);
IDirectDraw7* g_mirrorDirectDraw = nullptr;
bool g_lockingPrimary = false; 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) void fixSurfacePtr(IDirectDrawSurface7& surface, const DDSURFACEDESC2& desc)
{ {
if ((desc.dwFlags & DDSD_CAPS) && (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) if ((desc.dwFlags & DDSD_CAPS) && (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY))
@ -213,8 +201,15 @@ namespace
similarDesc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; similarDesc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
} }
IDirectDraw7* dd = DDrawRepository::getDirectDraw();
if (!dd)
{
similarSurface.front = nullptr;
return similarSurface;
}
HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface( HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(
g_mirrorDirectDraw, &similarDesc, &similarSurface.front, nullptr); dd, &similarDesc, &similarSurface.front, nullptr);
if (FAILED(result)) if (FAILED(result))
{ {
LOG_ONCE("Failed to create a similar front surface"); LOG_ONCE("Failed to create a similar front surface");
@ -223,7 +218,7 @@ namespace
} }
result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface( result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(
g_mirrorDirectDraw, &similarDesc, &similarSurface.back, nullptr); dd, &similarDesc, &similarSurface.back, nullptr);
if (FAILED(result)) if (FAILED(result))
{ {
LOG_ONCE("Failed to create a similar back surface"); LOG_ONCE("Failed to create a similar back surface");
@ -347,8 +342,6 @@ HRESULT CompatDirectDrawSurface<TSurface>::createCompatPrimarySurface(
return result; return result;
} }
g_mirrorDirectDraw = createMirrorDirectDraw();
s_compatPrimarySurface = compatSurface; s_compatPrimarySurface = compatSurface;
initCompatPrimarySurface(); initCompatPrimarySurface();
return DD_OK; return DD_OK;

View File

@ -7,6 +7,7 @@
#include "Config.h" #include "Config.h"
#include "DDrawLog.h" #include "DDrawLog.h"
#include "DDrawProcs.h" #include "DDrawProcs.h"
#include "DDrawRepository.h"
namespace namespace
{ {
@ -24,26 +25,6 @@ namespace
IDirectDrawSurface7* createGdiSurface(); 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 createCachedDc()
{ {
CachedDc cachedDc = {}; CachedDc cachedDc = {};
@ -186,7 +167,7 @@ namespace CompatGdiDcCache
bool init() bool init()
{ {
g_directDraw = createDirectDraw(); g_directDraw = DDrawRepository::getDirectDraw();
return nullptr != g_directDraw; return nullptr != g_directDraw;
} }

View File

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

View File

@ -99,6 +99,9 @@
<ClInclude Include="CompatRegistry.h"> <ClInclude Include="CompatRegistry.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="DDrawRepository.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="DllMain.cpp"> <ClCompile Include="DllMain.cpp">
@ -170,6 +173,9 @@
<ClCompile Include="CompatRegistry.cpp"> <ClCompile Include="CompatRegistry.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="DDrawRepository.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="DDrawCompat.def"> <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 "CompatRegistry.h"
#include "CompatVtable.h" #include "CompatVtable.h"
#include "DDrawProcs.h" #include "DDrawProcs.h"
#include "DDrawRepository.h"
struct IDirectInput; struct IDirectInput;
@ -31,7 +32,7 @@ namespace
} }
} }
void hookDirectDraw(IDirectDraw& dd) void hookDirectDraw(IDirectDraw7& dd)
{ {
IUnknown& ddUnk = reinterpret_cast<IUnknown&>(dd); IUnknown& ddUnk = reinterpret_cast<IUnknown&>(dd);
hookVtable<CompatDirectDraw<IDirectDraw>>(IID_IDirectDraw, ddUnk); hookVtable<CompatDirectDraw<IDirectDraw>>(IID_IDirectDraw, ddUnk);
@ -40,17 +41,17 @@ namespace
hookVtable<CompatDirectDraw<IDirectDraw7>>(IID_IDirectDraw7, ddUnk); hookVtable<CompatDirectDraw<IDirectDraw7>>(IID_IDirectDraw7, ddUnk);
} }
void hookDirectDrawSurface(IDirectDraw& dd) void hookDirectDrawSurface(IDirectDraw7& dd)
{ {
DDSURFACEDESC desc = {}; DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
desc.dwWidth = 1; desc.dwWidth = 1;
desc.dwHeight = 1; desc.dwHeight = 1;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
IDirectDrawSurface* surface = nullptr; IDirectDrawSurface7* surface = nullptr;
HRESULT result = CompatDirectDraw<IDirectDraw>::s_origVtable.CreateSurface(&dd, &desc, &surface, nullptr); HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreateSurface(&dd, &desc, &surface, nullptr);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
IUnknown& surfaceUnk = reinterpret_cast<IUnknown&>(*surface); IUnknown& surfaceUnk = reinterpret_cast<IUnknown&>(*surface);
@ -67,11 +68,11 @@ namespace
} }
} }
void hookDirectDrawPalette(IDirectDraw& dd) void hookDirectDrawPalette(IDirectDraw7& dd)
{ {
PALETTEENTRY paletteEntries[2] = {}; PALETTEENTRY paletteEntries[2] = {};
IDirectDrawPalette* palette = nullptr; IDirectDrawPalette* palette = nullptr;
HRESULT result = CompatDirectDraw<IDirectDraw>::s_origVtable.CreatePalette( HRESULT result = CompatDirectDraw<IDirectDraw7>::s_origVtable.CreatePalette(
&dd, DDPCAPS_1BIT, paletteEntries, &palette, nullptr); &dd, DDPCAPS_1BIT, paletteEntries, &palette, nullptr);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
@ -90,12 +91,9 @@ namespace
if (!isAlreadyInstalled) if (!isAlreadyInstalled)
{ {
Compat::Log() << "Installing DirectDraw hooks"; Compat::Log() << "Installing DirectDraw hooks";
IDirectDraw* dd = nullptr; IDirectDraw7* dd = DDrawRepository::getDirectDraw();
HRESULT result = CALL_ORIG_DDRAW(DirectDrawCreate, nullptr, &dd, nullptr); if (dd)
if (SUCCEEDED(result))
{ {
dd->lpVtbl->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL);
hookDirectDraw(*dd); hookDirectDraw(*dd);
hookDirectDrawSurface(*dd); hookDirectDrawSurface(*dd);
hookDirectDrawPalette(*dd); hookDirectDrawPalette(*dd);
@ -106,13 +104,8 @@ namespace
Compat::Log() << "Installing registry hooks"; Compat::Log() << "Installing registry hooks";
CompatRegistry::installHooks(); 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; isAlreadyInstalled = true;
} }
} }