2016-06-08 23:23:25 +02:00
|
|
|
#define CINTERFACE
|
|
|
|
|
|
|
|
#include <d3d.h>
|
|
|
|
|
2016-08-29 22:04:58 +02:00
|
|
|
#include "Common/CompatPtr.h"
|
|
|
|
#include "Common/CompatRef.h"
|
|
|
|
#include "Common/Log.h"
|
2016-08-27 22:39:28 +02:00
|
|
|
#include "DDraw/ActivateAppHandler.h"
|
|
|
|
#include "DDraw/DirectDraw.h"
|
2017-03-05 12:50:45 +01:00
|
|
|
#include "DDraw/DirectDrawClipper.h"
|
2017-05-27 22:14:48 +02:00
|
|
|
#include "DDraw/DirectDrawGammaControl.h"
|
2016-08-27 22:39:28 +02:00
|
|
|
#include "DDraw/DirectDrawPalette.h"
|
2017-03-05 12:50:45 +01:00
|
|
|
#include "DDraw/DirectDrawSurface.h"
|
2016-08-27 22:39:28 +02:00
|
|
|
#include "DDraw/Hooks.h"
|
|
|
|
#include "DDraw/RealPrimarySurface.h"
|
|
|
|
#include "DDraw/Repository.h"
|
2016-09-03 16:57:10 +02:00
|
|
|
#include "Dll/Procs.h"
|
2016-12-26 16:17:20 +01:00
|
|
|
#include "Win32/Registry.h"
|
2016-06-08 23:23:25 +02:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
2016-09-18 19:01:41 +02:00
|
|
|
template <typename Interface>
|
|
|
|
void hookVtable(const CompatPtr<Interface>& intf);
|
2016-06-08 23:23:25 +02:00
|
|
|
|
|
|
|
void hookDirectDraw(CompatRef<IDirectDraw7> dd)
|
|
|
|
{
|
2016-08-27 22:39:28 +02:00
|
|
|
DDraw::DirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl;
|
2016-06-08 23:23:25 +02:00
|
|
|
CompatPtr<IDirectDraw7> dd7(&dd);
|
2016-09-18 19:01:41 +02:00
|
|
|
hookVtable<IDirectDraw>(dd7);
|
|
|
|
hookVtable<IDirectDraw2>(dd7);
|
|
|
|
hookVtable<IDirectDraw4>(dd7);
|
|
|
|
hookVtable<IDirectDraw7>(dd7);
|
2016-06-08 23:23:25 +02:00
|
|
|
dd7.detach();
|
|
|
|
}
|
|
|
|
|
2017-03-05 12:50:45 +01:00
|
|
|
void hookDirectDrawClipper(CompatRef<IDirectDraw7> dd)
|
|
|
|
{
|
|
|
|
CompatPtr<IDirectDrawClipper> clipper;
|
|
|
|
HRESULT result = dd->CreateClipper(&dd, 0, &clipper.getRef(), nullptr);
|
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
DDraw::DirectDrawClipper::hookVtable(clipper.get()->lpVtbl);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Compat::Log() << "Failed to create a DirectDraw clipper for hooking: " << result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-08 23:23:25 +02:00
|
|
|
void hookDirectDrawPalette(CompatRef<IDirectDraw7> dd)
|
|
|
|
{
|
|
|
|
PALETTEENTRY paletteEntries[2] = {};
|
|
|
|
CompatPtr<IDirectDrawPalette> palette;
|
|
|
|
HRESULT result = dd->CreatePalette(&dd,
|
|
|
|
DDPCAPS_1BIT, paletteEntries, &palette.getRef(), nullptr);
|
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
2016-08-27 22:39:28 +02:00
|
|
|
DDraw::DirectDrawPalette::hookVtable(palette.get()->lpVtbl);
|
2016-06-08 23:23:25 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Compat::Log() << "Failed to create a DirectDraw palette for hooking: " << result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hookDirectDrawSurface(CompatRef<IDirectDraw7> dd)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
CompatPtr<IDirectDrawSurface7> surface;
|
|
|
|
HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
|
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
2016-08-27 22:39:28 +02:00
|
|
|
DDraw::DirectDrawSurface<IDirectDrawSurface7>::s_origVtable = *surface.get()->lpVtbl;
|
2016-09-18 19:01:41 +02:00
|
|
|
hookVtable<IDirectDrawSurface>(surface);
|
|
|
|
hookVtable<IDirectDrawSurface2>(surface);
|
|
|
|
hookVtable<IDirectDrawSurface3>(surface);
|
|
|
|
hookVtable<IDirectDrawSurface4>(surface);
|
|
|
|
hookVtable<IDirectDrawSurface7>(surface);
|
2017-05-27 22:14:48 +02:00
|
|
|
hookVtable<IDirectDrawGammaControl>(surface);
|
2016-06-08 23:23:25 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Compat::Log() << "Failed to create a DirectDraw surface for hooking: " << result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-18 19:01:41 +02:00
|
|
|
template <typename Interface>
|
|
|
|
void hookVtable(const CompatPtr<Interface>& intf)
|
2016-06-08 23:23:25 +02:00
|
|
|
{
|
2017-05-27 22:14:48 +02:00
|
|
|
if (intf)
|
|
|
|
{
|
|
|
|
CompatVtable<Vtable<Interface>>::hookVtable(intf.get()->lpVtbl);
|
|
|
|
}
|
2016-06-08 23:23:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-27 22:39:28 +02:00
|
|
|
namespace DDraw
|
2016-06-08 23:23:25 +02:00
|
|
|
{
|
|
|
|
void installHooks()
|
|
|
|
{
|
2016-12-26 16:17:20 +01:00
|
|
|
Win32::Registry::unsetValue(
|
|
|
|
HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\DirectDraw", "EmulationOnly");
|
|
|
|
Win32::Registry::unsetValue(
|
|
|
|
HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Microsoft\\DirectDraw", "EmulationOnly");
|
|
|
|
|
2016-06-08 23:23:25 +02:00
|
|
|
CompatPtr<IDirectDraw> dd;
|
2016-09-03 16:57:10 +02:00
|
|
|
CALL_ORIG_PROC(DirectDrawCreate, nullptr, &dd.getRef(), nullptr);
|
2016-06-08 23:23:25 +02:00
|
|
|
if (!dd)
|
|
|
|
{
|
|
|
|
Compat::Log() << "Failed to create a DirectDraw object for hooking";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-06-10 18:21:52 +02:00
|
|
|
HRESULT result = dd->SetCooperativeLevel(dd, nullptr, DDSCL_NORMAL);
|
|
|
|
if (FAILED(result))
|
|
|
|
{
|
|
|
|
Compat::Log() << "Failed to set the cooperative level for hooking: " << result;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-27 22:39:28 +02:00
|
|
|
auto dd7(Repository::getDirectDraw());
|
2016-06-08 23:23:25 +02:00
|
|
|
if (!dd7)
|
|
|
|
{
|
|
|
|
Compat::Log() << "Failed to create a DirectDraw7 object for hooking";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
hookDirectDraw(*dd7);
|
2017-03-05 12:50:45 +01:00
|
|
|
hookDirectDrawClipper(*dd7);
|
2016-06-08 23:23:25 +02:00
|
|
|
hookDirectDrawPalette(*dd7);
|
2017-03-05 12:50:45 +01:00
|
|
|
hookDirectDrawSurface(*dd7);
|
2016-06-08 23:23:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void uninstallHooks()
|
|
|
|
{
|
|
|
|
RealPrimarySurface::removeUpdateThread();
|
|
|
|
}
|
|
|
|
}
|