mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Create helper surfaces via DirectDraw runtime
This commit is contained in:
parent
51a451f424
commit
62983b19fe
23
DDrawCompat/Common/Comparison.h
Normal file
23
DDrawCompat/Common/Comparison.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_class_v<T> && std::is_trivial_v<T>, bool> operator==(const T& left, const T& right)
|
||||
{
|
||||
return toTuple(left) == toTuple(right);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::enable_if_t<std::is_class_v<T> && std::is_trivial_v<T>, bool> operator<(const T& left, const T& right)
|
||||
{
|
||||
return toTuple(left) < toTuple(right);
|
||||
}
|
||||
|
||||
inline auto toTuple(const LUID& luid)
|
||||
{
|
||||
return std::make_tuple(luid.LowPart, luid.HighPart);
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
#include <Common/Comparison.h>
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <D3dDdi/Adapter.h>
|
||||
#include <D3dDdi/AdapterFuncs.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/DeviceCallbacks.h>
|
||||
#include <D3dDdi/DeviceFuncs.h>
|
||||
#include <D3dDdi/KernelModeThunks.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -30,7 +32,10 @@ namespace D3dDdi
|
||||
, m_origVtable(CompatVtable<D3DDDI_ADAPTERFUNCS>::s_origVtable)
|
||||
, m_runtimeVersion(data.Version)
|
||||
, m_driverVersion(data.DriverVersion)
|
||||
, m_luid(KernelModeThunks::getLastOpenAdapterInfo().luid)
|
||||
, m_repository{}
|
||||
, m_d3dExtendedCaps{}
|
||||
, m_ddrawCaps{}
|
||||
{
|
||||
if (m_adapter)
|
||||
{
|
||||
@ -143,5 +148,16 @@ namespace D3dDdi
|
||||
return result;
|
||||
}
|
||||
|
||||
void Adapter::setRepository(LUID luid, const DDraw::DirectDraw::Repository& repository)
|
||||
{
|
||||
for (auto& adapter : s_adapters)
|
||||
{
|
||||
if (adapter.second.m_luid == luid)
|
||||
{
|
||||
adapter.second.m_repository = repository;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::map<HANDLE, Adapter> Adapter::s_adapters;
|
||||
}
|
||||
|
@ -6,6 +6,9 @@
|
||||
#include <d3dnthal.h>
|
||||
#include <d3dumddi.h>
|
||||
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <DDraw/DirectDraw.h>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
class Adapter
|
||||
@ -21,7 +24,10 @@ namespace D3dDdi
|
||||
|
||||
const D3DNTHAL_D3DEXTENDEDCAPS& getD3dExtendedCaps() const { return m_d3dExtendedCaps; }
|
||||
const DDRAW_CAPS& getDDrawCaps() const { return m_ddrawCaps; }
|
||||
LUID getLuid() const { return m_luid; }
|
||||
const D3DDDI_ADAPTERFUNCS& getOrigVtable() const { return m_origVtable; }
|
||||
CompatWeakPtr<IDirectDraw7> getRepository() const { return m_repository.repo; }
|
||||
bool isSrcColorKeySupported() const { return m_repository.isSrcColorKeySupported; }
|
||||
|
||||
HRESULT pfnCloseAdapter();
|
||||
HRESULT pfnCreateDevice(D3DDDIARG_CREATEDEVICE* pCreateData);
|
||||
@ -29,6 +35,7 @@ namespace D3dDdi
|
||||
|
||||
static void add(const D3DDDIARG_OPENADAPTER& data) { s_adapters.emplace(data.hAdapter, data); }
|
||||
static Adapter& get(HANDLE adapter) { return s_adapters.find(adapter)->second; }
|
||||
static void setRepository(LUID luid, const DDraw::DirectDraw::Repository& repository);
|
||||
|
||||
private:
|
||||
DWORD getSupportedZBufferBitDepths();
|
||||
@ -37,6 +44,8 @@ namespace D3dDdi
|
||||
D3DDDI_ADAPTERFUNCS m_origVtable;
|
||||
UINT m_runtimeVersion;
|
||||
UINT m_driverVersion;
|
||||
LUID m_luid;
|
||||
DDraw::DirectDraw::Repository m_repository;
|
||||
|
||||
D3DNTHAL_D3DEXTENDEDCAPS m_d3dExtendedCaps;
|
||||
DDRAW_CAPS m_ddrawCaps;
|
||||
|
@ -17,19 +17,6 @@ namespace
|
||||
{
|
||||
HANDLE g_gdiResourceHandle = nullptr;
|
||||
D3dDdi::Resource* g_gdiResource = nullptr;
|
||||
|
||||
void logSrcColorKeySupportFailure(const char* reason, UINT32 resultCode)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Checking source color key support: failed (" << reason;
|
||||
if (resultCode)
|
||||
{
|
||||
oss << ": " << Compat::hex(resultCode);
|
||||
}
|
||||
oss << ')';
|
||||
|
||||
LOG_ONCE(oss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
namespace D3dDdi
|
||||
@ -38,7 +25,6 @@ namespace D3dDdi
|
||||
: m_origVtable(CompatVtable<D3DDDI_DEVICEFUNCS>::s_origVtable)
|
||||
, m_adapter(adapter)
|
||||
, m_device(device)
|
||||
, m_isSrcColorKeySupported(checkSrcColorKeySupport())
|
||||
, m_renderTarget(nullptr)
|
||||
, m_renderTargetSubResourceIndex(0)
|
||||
, m_sharedPrimary(nullptr)
|
||||
@ -53,140 +39,26 @@ namespace D3dDdi
|
||||
s_devices.try_emplace(device, adapter, device);
|
||||
}
|
||||
|
||||
bool Device::checkSrcColorKeySupport()
|
||||
{
|
||||
if (!(m_adapter.getDDrawCaps().CKeyCaps & DDRAW_CKEYCAPS_SRCBLT))
|
||||
{
|
||||
logSrcColorKeySupportFailure("driver indicates no support", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
D3DDDI_SURFACEINFO si = {};
|
||||
si.Width = 2;
|
||||
si.Height = 1;
|
||||
|
||||
D3DDDIARG_CREATERESOURCE2 cr = {};
|
||||
cr.Format = D3DDDIFMT_R5G6B5;
|
||||
cr.Pool = D3DDDIPOOL_VIDEOMEMORY;
|
||||
cr.pSurfList = &si;
|
||||
cr.SurfCount = 1;
|
||||
cr.Rotation = D3DDDI_ROTATION_IDENTITY;
|
||||
|
||||
HRESULT result = createPrivateResource(cr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error creating source resource", result);
|
||||
return false;
|
||||
}
|
||||
auto resourceDeleter = [&](HANDLE resource) { m_origVtable.pfnDestroyResource(m_device, resource); };
|
||||
std::unique_ptr<void, std::function<void(HANDLE)>> srcRes(cr.hResource, resourceDeleter);
|
||||
|
||||
cr.hResource = nullptr;
|
||||
cr.Flags.RenderTarget = 1;
|
||||
result = createPrivateResource(cr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error creating destination resource", result);
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<void, std::function<void(HANDLE)>> dstRes(cr.hResource, resourceDeleter);
|
||||
|
||||
D3DDDIARG_LOCK lock = {};
|
||||
lock.hResource = srcRes.get();
|
||||
result = m_origVtable.pfnLock(m_device, &lock);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error locking source resource", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
const UINT16 colorKey = 0xFA9F;
|
||||
*static_cast<UINT32*>(lock.pSurfData) = colorKey;
|
||||
|
||||
D3DDDIARG_UNLOCK unlock = {};
|
||||
unlock.hResource = srcRes.get();
|
||||
m_origVtable.pfnUnlock(m_device, &unlock);
|
||||
|
||||
lock = {};
|
||||
lock.hResource = dstRes.get();
|
||||
result = m_origVtable.pfnLock(m_device, &lock);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error locking destination resource", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
*static_cast<UINT32*>(lock.pSurfData) = 0xFFFFFFFF;
|
||||
unlock.hResource = dstRes.get();
|
||||
m_origVtable.pfnUnlock(m_device, &unlock);
|
||||
|
||||
D3DDDIARG_BLT blt = {};
|
||||
blt.hSrcResource = srcRes.get();
|
||||
blt.SrcRect = { 0, 0, 2, 1 };
|
||||
blt.hDstResource = dstRes.get();
|
||||
blt.DstRect = { 0, 0, 2, 1 };
|
||||
blt.ColorKey = colorKey;
|
||||
blt.Flags.SrcColorKey = 1;
|
||||
result = m_origVtable.pfnBlt(m_device, &blt);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("blt error", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
lock = {};
|
||||
lock.hResource = dstRes.get();
|
||||
result = m_origVtable.pfnLock(m_device, &lock);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error locking destination resource after blt", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
const UINT32 dstPixels = *static_cast<UINT32*>(lock.pSurfData);
|
||||
|
||||
unlock.hResource = dstRes.get();
|
||||
m_origVtable.pfnUnlock(m_device, &unlock);
|
||||
|
||||
if (dstPixels != 0xFFFF)
|
||||
{
|
||||
logSrcColorKeySupportFailure("test result pattern is incorrect", dstPixels);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_ONCE("Checking source color key support: passed");
|
||||
return true;
|
||||
}
|
||||
|
||||
HRESULT Device::createPrivateResource(D3DDDIARG_CREATERESOURCE2& data)
|
||||
{
|
||||
if (m_origVtable.pfnCreateResource2)
|
||||
const bool isPalettizedOffScreen = D3DDDIFMT_P8 == data.Format && !data.Flags.Texture;
|
||||
if (isPalettizedOffScreen)
|
||||
{
|
||||
return m_origVtable.pfnCreateResource2(m_device, &data);
|
||||
data.Format = D3DDDIFMT_L8;
|
||||
data.Flags.Texture = 1;
|
||||
}
|
||||
return m_origVtable.pfnCreateResource(m_device, reinterpret_cast<D3DDDIARG_CREATERESOURCE*>(&data));
|
||||
}
|
||||
|
||||
template <typename Arg>
|
||||
HRESULT Device::createResourceImpl(Arg& data)
|
||||
{
|
||||
try
|
||||
HRESULT result = m_origVtable.pfnCreateResource2
|
||||
? m_origVtable.pfnCreateResource2(m_device, &data)
|
||||
: m_origVtable.pfnCreateResource(m_device, reinterpret_cast<D3DDDIARG_CREATERESOURCE*>(&data));
|
||||
|
||||
if (isPalettizedOffScreen)
|
||||
{
|
||||
Resource resource(*this, data);
|
||||
m_resources.emplace(resource, std::move(resource));
|
||||
if (data.Flags.VertexBuffer &&
|
||||
D3DDDIPOOL_SYSTEMMEM == data.Pool &&
|
||||
data.pSurfList[0].pSysMem)
|
||||
{
|
||||
m_drawPrimitive.addSysMemVertexBuffer(data.hResource,
|
||||
static_cast<BYTE*>(const_cast<void*>(data.pSurfList[0].pSysMem)));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
catch (const HResultException& e)
|
||||
{
|
||||
return e.getResult();
|
||||
data.Format = D3DDDIFMT_P8;
|
||||
data.Flags.Texture = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Resource* Device::findResource(HANDLE resource)
|
||||
@ -297,12 +169,32 @@ namespace D3dDdi
|
||||
|
||||
HRESULT Device::pfnCreateResource(D3DDDIARG_CREATERESOURCE* data)
|
||||
{
|
||||
return createResourceImpl(*data);
|
||||
D3DDDIARG_CREATERESOURCE2 data2 = {};
|
||||
memcpy(&data2, data, sizeof(*data));
|
||||
HRESULT result = pfnCreateResource2(&data2);
|
||||
data->hResource = data2.hResource;
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT Device::pfnCreateResource2(D3DDDIARG_CREATERESOURCE2* data)
|
||||
{
|
||||
return createResourceImpl(*data);
|
||||
try
|
||||
{
|
||||
Resource resource(*this, *data);
|
||||
m_resources.emplace(resource, std::move(resource));
|
||||
if (data->Flags.VertexBuffer &&
|
||||
D3DDDIPOOL_SYSTEMMEM == data->Pool &&
|
||||
data->pSurfList[0].pSysMem)
|
||||
{
|
||||
m_drawPrimitive.addSysMemVertexBuffer(data->hResource,
|
||||
static_cast<BYTE*>(const_cast<void*>(data->pSurfList[0].pSysMem)));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
catch (const HResultException& e)
|
||||
{
|
||||
return e.getResult();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT Device::pfnDestroyDevice()
|
||||
|
@ -59,8 +59,6 @@ namespace D3dDdi
|
||||
void prepareForRendering();
|
||||
void setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data);
|
||||
|
||||
bool isSrcColorKeySupported() const { return m_isSrcColorKeySupported; }
|
||||
|
||||
static void add(Adapter& adapter, HANDLE device);
|
||||
static Device& get(HANDLE device) { return s_devices.find(device)->second; }
|
||||
|
||||
@ -70,11 +68,6 @@ namespace D3dDdi
|
||||
static void setGdiResourceHandle(HANDLE resource);
|
||||
|
||||
private:
|
||||
bool checkSrcColorKeySupport();
|
||||
|
||||
template <typename Arg>
|
||||
HRESULT createResourceImpl(Arg& data);
|
||||
|
||||
D3DDDI_DEVICEFUNCS m_origVtable;
|
||||
Adapter& m_adapter;
|
||||
HANDLE m_device;
|
||||
@ -85,7 +78,6 @@ namespace D3dDdi
|
||||
DrawPrimitive m_drawPrimitive;
|
||||
DeviceState m_state;
|
||||
ShaderBlitter m_shaderBlitter;
|
||||
bool m_isSrcColorKeySupported;
|
||||
|
||||
static std::map<HANDLE, Device> s_devices;
|
||||
static bool s_isFlushEnabled;
|
||||
|
@ -18,17 +18,10 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
struct AdapterInfo
|
||||
{
|
||||
UINT adapter;
|
||||
UINT vidPnSourceId;
|
||||
RECT monitorRect;
|
||||
};
|
||||
|
||||
D3DDDIFORMAT g_dcFormatOverride = D3DDDIFMT_UNKNOWN;
|
||||
bool g_dcPaletteOverride = false;
|
||||
AdapterInfo g_gdiAdapterInfo = {};
|
||||
AdapterInfo g_lastOpenAdapterInfo = {};
|
||||
D3dDdi::KernelModeThunks::AdapterInfo g_gdiAdapterInfo = {};
|
||||
D3dDdi::KernelModeThunks::AdapterInfo g_lastOpenAdapterInfo = {};
|
||||
Compat::SrwLock g_lastOpenAdapterInfoSrwLock;
|
||||
std::string g_lastDDrawCreateDcDevice;
|
||||
|
||||
@ -109,7 +102,17 @@ namespace
|
||||
HDC WINAPI ddrawCreateDcA(LPCSTR pwszDriver, LPCSTR pwszDevice, LPCSTR pszPort, const DEVMODEA* pdm)
|
||||
{
|
||||
LOG_FUNC("ddrawCreateDCA", pwszDriver, pwszDevice, pszPort, pdm);
|
||||
g_lastDDrawCreateDcDevice = pwszDevice ? pwszDevice : std::string();
|
||||
if (pwszDevice)
|
||||
{
|
||||
g_lastDDrawCreateDcDevice = pwszDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
MONITORINFOEXA mi = {};
|
||||
mi.cbSize = sizeof(mi);
|
||||
CALL_ORIG_FUNC(GetMonitorInfoA)(MonitorFromPoint({}, MONITOR_DEFAULTTOPRIMARY), &mi);
|
||||
g_lastDDrawCreateDcDevice = mi.szDevice;
|
||||
}
|
||||
return LOG_RESULT(CreateDCA(pwszDriver, pwszDevice, pszPort, pdm));
|
||||
}
|
||||
|
||||
@ -126,11 +129,12 @@ namespace
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
AdapterInfo getAdapterInfo(const D3DKMT_OPENADAPTERFROMHDC& data)
|
||||
D3dDdi::KernelModeThunks::AdapterInfo getAdapterInfo(const D3DKMT_OPENADAPTERFROMHDC& data)
|
||||
{
|
||||
AdapterInfo adapterInfo = {};
|
||||
D3dDdi::KernelModeThunks::AdapterInfo adapterInfo = {};
|
||||
adapterInfo.adapter = data.hAdapter;
|
||||
adapterInfo.vidPnSourceId = data.VidPnSourceId;
|
||||
adapterInfo.luid = data.AdapterLuid;
|
||||
|
||||
EnumDisplayMonitors(nullptr, nullptr, findDDrawMonitorRect,
|
||||
reinterpret_cast<LPARAM>(&adapterInfo.monitorRect));
|
||||
@ -277,6 +281,20 @@ namespace D3dDdi
|
||||
{
|
||||
namespace KernelModeThunks
|
||||
{
|
||||
AdapterInfo getAdapterInfo(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
DDraw::ScopedThreadLock lock;
|
||||
DDDEVICEIDENTIFIER2 di = {};
|
||||
dd.get().lpVtbl->GetDeviceIdentifier(&dd, &di, 0);
|
||||
return getLastOpenAdapterInfo();
|
||||
}
|
||||
|
||||
AdapterInfo getLastOpenAdapterInfo()
|
||||
{
|
||||
Compat::ScopedSrwLockShared srwLock(g_lastOpenAdapterInfoSrwLock);
|
||||
return g_lastOpenAdapterInfo;
|
||||
}
|
||||
|
||||
RECT getMonitorRect()
|
||||
{
|
||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
||||
@ -298,7 +316,7 @@ namespace D3dDdi
|
||||
dd7.get()->lpVtbl->GetDeviceIdentifier(dd7, &di, 0);
|
||||
}
|
||||
|
||||
return g_lastOpenAdapterInfo.monitorRect;
|
||||
return getLastOpenAdapterInfo().monitorRect;
|
||||
}
|
||||
|
||||
long long getQpcLastVsync()
|
||||
|
@ -1,11 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <ddraw.h>
|
||||
|
||||
#include <Common/CompatRef.h>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
namespace KernelModeThunks
|
||||
{
|
||||
struct AdapterInfo
|
||||
{
|
||||
UINT adapter;
|
||||
UINT vidPnSourceId;
|
||||
LUID luid;
|
||||
RECT monitorRect;
|
||||
};
|
||||
|
||||
AdapterInfo getAdapterInfo(CompatRef<IDirectDraw7> dd);
|
||||
AdapterInfo getLastOpenAdapterInfo();
|
||||
RECT getMonitorRect();
|
||||
long long getQpcLastVsync();
|
||||
UINT getVsyncCounter();
|
||||
|
@ -103,27 +103,10 @@ namespace
|
||||
data.pSurfList = tiles.data();
|
||||
data.Flags.Texture = 0;
|
||||
}
|
||||
|
||||
D3DDDIARG_CREATERESOURCE2 upgradeResourceData(const D3DDDIARG_CREATERESOURCE& data)
|
||||
{
|
||||
D3DDDIARG_CREATERESOURCE2 data2 = {};
|
||||
reinterpret_cast<D3DDDIARG_CREATERESOURCE&>(data2) = data;
|
||||
return data2;
|
||||
}
|
||||
}
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
Resource::Data::Data()
|
||||
: D3DDDIARG_CREATERESOURCE2{}
|
||||
{
|
||||
}
|
||||
|
||||
Resource::Data::Data(const D3DDDIARG_CREATERESOURCE& data)
|
||||
: Data(upgradeResourceData(data))
|
||||
{
|
||||
}
|
||||
|
||||
Resource::Data::Data(const D3DDDIARG_CREATERESOURCE2& data)
|
||||
: D3DDDIARG_CREATERESOURCE2(data)
|
||||
{
|
||||
@ -135,8 +118,7 @@ namespace D3dDdi
|
||||
pSurfList = surfaceData.data();
|
||||
}
|
||||
|
||||
template <typename Arg>
|
||||
Resource::Resource(Device& device, Arg& data, HRESULT(APIENTRY* createResourceFunc)(HANDLE, Arg*))
|
||||
Resource::Resource(Device& device, D3DDDIARG_CREATERESOURCE2& data)
|
||||
: m_device(device)
|
||||
, m_handle(nullptr)
|
||||
, m_origData(data)
|
||||
@ -154,26 +136,13 @@ namespace D3dDdi
|
||||
fixResourceData(device, reinterpret_cast<D3DDDIARG_CREATERESOURCE&>(m_fixedData));
|
||||
m_formatInfo = getFormatInfo(m_fixedData.Format);
|
||||
|
||||
const bool isPalettized = D3DDDIFMT_P8 == m_fixedData.Format;
|
||||
if (isPalettized)
|
||||
{
|
||||
m_fixedData.Format = D3DDDIFMT_L8;
|
||||
m_fixedData.Flags.Texture = 1;
|
||||
}
|
||||
|
||||
HRESULT result = createResourceFunc(device, reinterpret_cast<Arg*>(&m_fixedData));
|
||||
HRESULT result = m_device.createPrivateResource(m_fixedData);
|
||||
if (FAILED(result))
|
||||
{
|
||||
throw HResultException(result);
|
||||
}
|
||||
m_handle = m_fixedData.hResource;
|
||||
|
||||
if (isPalettized)
|
||||
{
|
||||
m_fixedData.Format = D3DDDIFMT_P8;
|
||||
m_fixedData.Flags.Texture = 0;
|
||||
}
|
||||
|
||||
if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool &&
|
||||
0 != m_formatInfo.bytesPerPixel)
|
||||
{
|
||||
@ -190,16 +159,6 @@ namespace D3dDdi
|
||||
data.hResource = m_fixedData.hResource;
|
||||
}
|
||||
|
||||
Resource::Resource(Device& device, D3DDDIARG_CREATERESOURCE& data)
|
||||
: Resource(device, data, device.getOrigVtable().pfnCreateResource)
|
||||
{
|
||||
}
|
||||
|
||||
Resource::Resource(Device& device, D3DDDIARG_CREATERESOURCE2& data)
|
||||
: Resource(device, data, device.getOrigVtable().pfnCreateResource2)
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT Resource::blt(D3DDDIARG_BLT data)
|
||||
{
|
||||
if (!isValidRect(data.DstSubResourceIndex, data.DstRect))
|
||||
@ -445,7 +404,7 @@ namespace D3dDdi
|
||||
{
|
||||
LOG_FUNC("Resource::createSysMemResource", Compat::array(surfaceInfo.data(), surfaceInfo.size()));
|
||||
D3DDDIARG_CREATERESOURCE2 data = {};
|
||||
data.Format = (D3DDDIFMT_P8 == m_fixedData.Format) ? D3DDDIFMT_L8 : m_fixedData.Format;
|
||||
data.Format = m_fixedData.Format;
|
||||
data.Pool = D3DDDIPOOL_SYSTEMMEM;
|
||||
data.pSurfList = surfaceInfo.data();
|
||||
data.SurfCount = surfaceInfo.size();
|
||||
@ -653,7 +612,7 @@ namespace D3dDdi
|
||||
if (D3DDDIFMT_P8 != m_fixedData.Format)
|
||||
{
|
||||
if (data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown ||
|
||||
(data.Flags.SrcColorKey && !m_device.isSrcColorKeySupported()))
|
||||
(data.Flags.SrcColorKey && !m_device.getAdapter().isSrcColorKeySupported()))
|
||||
{
|
||||
dstLockData.qpcLastForcedLock = now;
|
||||
srcLockData.qpcLastForcedLock = now;
|
||||
|
@ -15,7 +15,6 @@ namespace D3dDdi
|
||||
class Resource
|
||||
{
|
||||
public:
|
||||
Resource(Device& device, D3DDDIARG_CREATERESOURCE& data);
|
||||
Resource(Device& device, D3DDDIARG_CREATERESOURCE2& data);
|
||||
|
||||
Resource(const Resource&) = delete;
|
||||
@ -41,8 +40,6 @@ namespace D3dDdi
|
||||
class Data : public D3DDDIARG_CREATERESOURCE2
|
||||
{
|
||||
public:
|
||||
Data();
|
||||
Data(const D3DDDIARG_CREATERESOURCE& data);
|
||||
Data(const D3DDDIARG_CREATERESOURCE2& data);
|
||||
|
||||
Data(const Data&) = delete;
|
||||
@ -74,9 +71,6 @@ namespace D3dDdi
|
||||
Device& m_device;
|
||||
};
|
||||
|
||||
template <typename Arg>
|
||||
Resource(Device& device, Arg& data, HRESULT(APIENTRY *createResourceFunc)(HANDLE, Arg*));
|
||||
|
||||
HRESULT bltLock(D3DDDIARG_LOCK& data);
|
||||
HRESULT bltUnlock(const D3DDDIARG_UNLOCK& data);
|
||||
void clipRect(UINT subResourceIndex, RECT& rect);
|
||||
|
@ -1,44 +1,62 @@
|
||||
#include <map>
|
||||
|
||||
#include <Common/Comparison.h>
|
||||
#include <Common/Log.h>
|
||||
#include <D3dDdi/Adapter.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/Resource.h>
|
||||
#include <D3dDdi/ShaderBlitter.h>
|
||||
#include <DDraw/DirectDrawSurface.h>
|
||||
#include <Shaders/PaletteLookup.h>
|
||||
|
||||
#define CONCAT_(a, b) a##b
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
#define SCOPED_STATE(state, ...) DeviceState::Scoped##state CONCAT(scopedState, __LINE__)(m_device.getState(), __VA_ARGS__)
|
||||
|
||||
namespace
|
||||
{
|
||||
std::map<LUID, CompatWeakPtr<IDirectDrawSurface7>> g_paletteTextures;
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> getPaletteTexture(CompatWeakPtr<IDirectDraw7> dd, LUID luid)
|
||||
{
|
||||
LOG_FUNC("ShaderBlitter::getPaletteTexture", dd.get(), luid);
|
||||
if (!dd)
|
||||
{
|
||||
LOG_ONCE("Failed to create palette texture: no DirectDraw repository available")
|
||||
return LOG_RESULT(nullptr);
|
||||
}
|
||||
|
||||
auto it = g_paletteTextures.find(luid);
|
||||
if (it == g_paletteTextures.end())
|
||||
{
|
||||
CompatPtr<IDirectDrawSurface7> paletteTexture;
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
|
||||
desc.dwWidth = 256;
|
||||
desc.dwHeight = 1;
|
||||
desc.ddpfPixelFormat = DDraw::DirectDraw::getRgbPixelFormat(32);
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
|
||||
|
||||
HRESULT result = dd->CreateSurface(dd, &desc, &paletteTexture.getRef(), nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
LOG_ONCE("Failed to create palette texture: " << Compat::hex(result));
|
||||
return nullptr;
|
||||
}
|
||||
it = g_paletteTextures.insert({ luid, paletteTexture.detach() }).first;
|
||||
}
|
||||
return LOG_RESULT(it->second.get());
|
||||
}
|
||||
}
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
ShaderBlitter::ShaderBlitter(Device& device)
|
||||
: m_device(device)
|
||||
, m_paletteTexture(nullptr)
|
||||
, m_psPaletteLookup(createPixelShader(g_psPaletteLookup, sizeof(g_psPaletteLookup)))
|
||||
, m_vertexShaderDecl(createVertexShaderDecl())
|
||||
{
|
||||
D3DDDI_SURFACEINFO si = {};
|
||||
si.Width = 256;
|
||||
si.Height = 1;
|
||||
|
||||
D3DDDIARG_CREATERESOURCE2 cr = {};
|
||||
cr.Format = D3DDDIFMT_X8R8G8B8;
|
||||
cr.Pool = D3DDDIPOOL_VIDEOMEMORY;
|
||||
cr.pSurfList = &si;
|
||||
cr.SurfCount = 1;
|
||||
cr.Rotation = D3DDDI_ROTATION_IDENTITY;
|
||||
cr.Flags.Texture = 1;
|
||||
|
||||
m_device.createPrivateResource(cr);
|
||||
m_paletteTexture = cr.hResource;
|
||||
}
|
||||
|
||||
ShaderBlitter::~ShaderBlitter()
|
||||
{
|
||||
if (m_paletteTexture)
|
||||
{
|
||||
m_device.getOrigVtable().pfnDestroyResource(m_device, m_paletteTexture);
|
||||
m_paletteTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderBlitter::blt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||
@ -146,32 +164,42 @@ namespace D3dDdi
|
||||
void ShaderBlitter::palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex,
|
||||
const Resource& srcResource, RGBQUAD palette[256])
|
||||
{
|
||||
LOG_FUNC("ShaderBlitter::palettizedBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex,
|
||||
static_cast<HANDLE>(srcResource), Compat::array(reinterpret_cast<void**>(palette), 256));
|
||||
|
||||
if (m_paletteTexture && FAILED(m_paletteTexture->IsLost(m_paletteTexture)))
|
||||
{
|
||||
g_paletteTextures.erase(m_device.getAdapter().getLuid());
|
||||
m_paletteTexture->Release(m_paletteTexture);
|
||||
m_paletteTexture = nullptr;
|
||||
}
|
||||
|
||||
if (!m_paletteTexture)
|
||||
{
|
||||
return;
|
||||
m_paletteTexture = getPaletteTexture(m_device.getAdapter().getRepository(), m_device.getAdapter().getLuid());
|
||||
if (!m_paletteTexture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
D3DDDIARG_LOCK lock = {};
|
||||
lock.hResource = m_paletteTexture;
|
||||
lock.Flags.Discard = 1;
|
||||
m_device.getOrigVtable().pfnLock(m_device, &lock);
|
||||
if (!lock.pSurfData)
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
m_paletteTexture->Lock(m_paletteTexture, nullptr, &desc, DDLOCK_DISCARDCONTENTS | DDLOCK_WAIT, nullptr);
|
||||
if (!desc.lpSurface)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(lock.pSurfData, palette, 256 * sizeof(RGBQUAD));
|
||||
|
||||
D3DDDIARG_UNLOCK unlock = {};
|
||||
unlock.hResource = m_paletteTexture;
|
||||
m_device.getOrigVtable().pfnUnlock(m_device, &unlock);
|
||||
memcpy(desc.lpSurface, palette, 256 * sizeof(RGBQUAD));
|
||||
m_paletteTexture->Unlock(m_paletteTexture, nullptr);
|
||||
|
||||
const auto& dstSurface = dstResource.getFixedDesc().pSurfList[dstSubResourceIndex];
|
||||
const auto& srcSurface = srcResource.getFixedDesc().pSurfList[0];
|
||||
const RECT dstRect = { 0, 0, static_cast<LONG>(dstSurface.Width), static_cast<LONG>(dstSurface.Height) };
|
||||
const RECT srcRect = { 0, 0, static_cast<LONG>(srcSurface.Width), static_cast<LONG>(srcSurface.Height) };
|
||||
|
||||
SCOPED_STATE(Texture, 1, m_paletteTexture, D3DTEXF_POINT);
|
||||
SCOPED_STATE(Texture, 1, DDraw::DirectDrawSurface::getDriverResourceHandle(*m_paletteTexture), D3DTEXF_POINT);
|
||||
blt(dstResource, dstSubResourceIndex, dstRect, srcResource, srcRect, m_psPaletteLookup, D3DTEXF_POINT);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <ddraw.h>
|
||||
|
||||
#include <Common/CompatWeakPtr.h>
|
||||
|
||||
namespace D3dDdi
|
||||
{
|
||||
@ -15,7 +17,6 @@ namespace D3dDdi
|
||||
ShaderBlitter(ShaderBlitter&&) = delete;
|
||||
ShaderBlitter& operator=(const ShaderBlitter&) = delete;
|
||||
ShaderBlitter& operator=(ShaderBlitter&&) = delete;
|
||||
~ShaderBlitter();
|
||||
|
||||
void palettizedBlt(const Resource& dstResource, UINT dstSubResourceIndex,
|
||||
const Resource& srcResource, RGBQUAD palette[256]);
|
||||
@ -28,7 +29,7 @@ namespace D3dDdi
|
||||
HANDLE createVertexShaderDecl();
|
||||
|
||||
Device& m_device;
|
||||
HANDLE m_paletteTexture;
|
||||
CompatWeakPtr<IDirectDrawSurface7> m_paletteTexture;
|
||||
HANDLE m_psPaletteLookup;
|
||||
HANDLE m_vertexShaderDecl;
|
||||
};
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include <type_traits>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
#include <Common/Comparison.h>
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <D3dDdi/Adapter.h>
|
||||
#include <D3dDdi/KernelModeThunks.h>
|
||||
#include <DDraw/DirectDraw.h>
|
||||
#include <DDraw/RealPrimarySurface.h>
|
||||
@ -11,9 +14,106 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
void logComInstantiation()
|
||||
void logSrcColorKeySupportFailure(const char* reason, UINT32 resultCode);
|
||||
|
||||
bool checkSrcColorKeySupport(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
LOG_ONCE("COM instantiation of DirectDraw detected");
|
||||
DDCAPS caps = {};
|
||||
caps.dwSize = sizeof(caps);
|
||||
dd->GetCaps(&dd, &caps, nullptr);
|
||||
if (!(caps.dwCaps & DDCAPS_COLORKEY) || !(caps.dwCKeyCaps & DDCKEYCAPS_SRCBLT))
|
||||
{
|
||||
logSrcColorKeySupportFailure("driver indicates no support", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
|
||||
desc.dwWidth = 2;
|
||||
desc.dwHeight = 1;
|
||||
desc.ddpfPixelFormat = DDraw::DirectDraw::getRgbPixelFormat(16);
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> src;
|
||||
HRESULT result = dd->CreateSurface(&dd, &desc, &src.getRef(), nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error creating source surface", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> dst;
|
||||
result = dd->CreateSurface(&dd, &desc, &dst.getRef(), nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error creating destination surface", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = src->Lock(src, nullptr, &desc, DDLOCK_WAIT, nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error locking source surface", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
const UINT16 colorKey = 0xFA9F;
|
||||
*static_cast<UINT32*>(desc.lpSurface) = colorKey;
|
||||
src->Unlock(src, nullptr);
|
||||
|
||||
result = dst->Lock(dst, nullptr, &desc, DDLOCK_WAIT, nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error locking destination surface", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
*static_cast<UINT32*>(desc.lpSurface) = 0xFFFFFFFF;
|
||||
dst->Unlock(dst, nullptr);
|
||||
|
||||
DDBLTFX fx = {};
|
||||
fx.dwSize = sizeof(fx);
|
||||
fx.ddckSrcColorkey.dwColorSpaceLowValue = colorKey;
|
||||
fx.ddckSrcColorkey.dwColorSpaceHighValue = colorKey;
|
||||
result = dst->Blt(dst, nullptr, src, nullptr, DDBLT_KEYSRCOVERRIDE | DDBLT_WAIT, &fx);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("blt error", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
result = dst->Lock(dst, nullptr, &desc, DDLOCK_WAIT, nullptr);
|
||||
if (FAILED(result))
|
||||
{
|
||||
logSrcColorKeySupportFailure("error locking destination resource after blt", result);
|
||||
return false;
|
||||
}
|
||||
|
||||
const UINT32 dstPixels = *static_cast<UINT32*>(desc.lpSurface);
|
||||
dst->Unlock(dst, nullptr);
|
||||
|
||||
if (dstPixels != 0xFFFF)
|
||||
{
|
||||
logSrcColorKeySupportFailure("test result pattern is incorrect", dstPixels);
|
||||
return false;
|
||||
}
|
||||
|
||||
Compat::Log() << "Source color key support: yes";
|
||||
return true;
|
||||
}
|
||||
|
||||
void logSrcColorKeySupportFailure(const char* reason, UINT32 resultCode)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Source color key support: no (" << reason;
|
||||
if (resultCode)
|
||||
{
|
||||
oss << ": " << Compat::hex(resultCode);
|
||||
}
|
||||
oss << ')';
|
||||
|
||||
Compat::Log() << oss.str();
|
||||
}
|
||||
|
||||
template <typename TDirectDraw, typename TSurfaceDesc, typename TSurface>
|
||||
@ -60,14 +160,6 @@ namespace
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE Initialize(TDirectDraw* This, GUID* lpGUID)
|
||||
{
|
||||
logComInstantiation();
|
||||
DDraw::DirectDraw::suppressEmulatedDirectDraw(lpGUID);
|
||||
return getOrigVtable(This).Initialize(This, lpGUID);
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE RestoreAllSurfaces(TDirectDraw* This)
|
||||
{
|
||||
@ -107,7 +199,6 @@ namespace
|
||||
vtable.CreateSurface = &CreateSurface;
|
||||
vtable.FlipToGDISurface = &FlipToGDISurface;
|
||||
vtable.GetGDISurface = &GetGDISurface;
|
||||
vtable.Initialize = &Initialize;
|
||||
vtable.WaitForVerticalBlank = &WaitForVerticalBlank;
|
||||
|
||||
if constexpr (std::is_same_v<Vtable, IDirectDraw4Vtbl> || std::is_same_v<Vtable, IDirectDraw7Vtbl>)
|
||||
@ -166,6 +257,26 @@ namespace DDraw
|
||||
return pf;
|
||||
}
|
||||
|
||||
void onCreate(GUID* guid, CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
static std::map<LUID, Repository> repositories;
|
||||
auto adapterInfo = D3dDdi::KernelModeThunks::getAdapterInfo(dd);
|
||||
auto it = repositories.find(adapterInfo.luid);
|
||||
if (it == repositories.end())
|
||||
{
|
||||
CompatPtr<IDirectDraw7> repo;
|
||||
CALL_ORIG_PROC(DirectDrawCreateEx)(guid, reinterpret_cast<void**>(&repo.getRef()), IID_IDirectDraw7, nullptr);
|
||||
if (!repo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
repo->SetCooperativeLevel(repo, nullptr, DDSCL_NORMAL);
|
||||
it = repositories.insert({ adapterInfo.luid, { repo, checkSrcColorKeySupport(*repo) } }).first;
|
||||
repo.detach();
|
||||
}
|
||||
D3dDdi::Adapter::setRepository(adapterInfo.luid, it->second);
|
||||
}
|
||||
|
||||
void suppressEmulatedDirectDraw(GUID*& guid)
|
||||
{
|
||||
if (reinterpret_cast<GUID*>(DDCREATE_EMULATIONONLY) == guid)
|
||||
|
@ -2,14 +2,22 @@
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <Common/CompatRef.h>
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
namespace DirectDraw
|
||||
{
|
||||
struct Repository
|
||||
{
|
||||
CompatWeakPtr<IDirectDraw7> repo;
|
||||
bool isSrcColorKeySupported;
|
||||
};
|
||||
|
||||
DDSURFACEDESC2 getDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
DDPIXELFORMAT getRgbPixelFormat(DWORD bpp);
|
||||
void onCreate(GUID* guid, CompatRef<IDirectDraw7> dd);
|
||||
void suppressEmulatedDirectDraw(GUID*& guid);
|
||||
|
||||
template <typename TDirectDraw>
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
decltype(IDirectDraw7Vtbl::Initialize) g_origInitialize = nullptr;
|
||||
|
||||
void hookDirectDraw(CompatPtr<IDirectDraw7> dd)
|
||||
{
|
||||
DDraw::DirectDraw::hookVtable(*CompatPtr<IDirectDraw>(dd).get()->lpVtbl);
|
||||
@ -77,6 +79,19 @@ namespace
|
||||
Compat::Log() << "ERROR: Failed to create a DirectDraw surface for hooking: " << result;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE initialize(IUnknown* This, GUID* lpGUID)
|
||||
{
|
||||
LOG_FUNC("IDirectDrawVtbl::Initialize", This, lpGUID);
|
||||
LOG_ONCE("COM instantiation of DirectDraw detected");
|
||||
DDraw::DirectDraw::suppressEmulatedDirectDraw(lpGUID);
|
||||
HRESULT result = g_origInitialize(reinterpret_cast<IDirectDraw7*>(This), lpGUID);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
DDraw::DirectDraw::onCreate(lpGUID, *CompatPtr<IDirectDraw7>::from(This));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace DDraw
|
||||
@ -90,6 +105,9 @@ namespace DDraw
|
||||
Win32::Registry::unsetValue(
|
||||
HKEY_LOCAL_MACHINE, "SOFTWARE\\WOW6432Node\\Microsoft\\DirectDraw", "EmulationOnly");
|
||||
|
||||
g_origInitialize = dd7.get()->lpVtbl->Initialize;
|
||||
Compat::hookFunction(reinterpret_cast<void*&>(g_origInitialize), initialize, "IDirectDrawVtbl::Initialize");
|
||||
|
||||
hookDirectDraw(dd7);
|
||||
hookDirectDrawClipper(*dd7);
|
||||
hookDirectDrawPalette(*dd7);
|
||||
|
@ -191,6 +191,7 @@
|
||||
</FxCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Common\Comparison.h" />
|
||||
<ClInclude Include="Common\CompatPtr.h" />
|
||||
<ClInclude Include="Common\CompatQueryInterface.h" />
|
||||
<ClInclude Include="Common\CompatRef.h" />
|
||||
|
@ -423,6 +423,9 @@
|
||||
<ClInclude Include="D3dDdi\ShaderBlitter.h">
|
||||
<Filter>Header Files\D3dDdi</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Common\Comparison.h">
|
||||
<Filter>Header Files\Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
|
@ -40,14 +40,27 @@ namespace
|
||||
#undef DEFINE_FUNC_NAME
|
||||
|
||||
void installHooks();
|
||||
void onDirectDrawCreate(GUID* lpGUID, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOuter);
|
||||
void onDirectDrawCreate(GUID* lpGUID, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOuter);
|
||||
|
||||
template <FARPROC(Dll::Procs::* origFunc), typename OrigFuncPtrType, typename FirstParam, typename... Params>
|
||||
HRESULT WINAPI directDrawFunc(FirstParam firstParam, Params... params)
|
||||
{
|
||||
LOG_FUNC(getFuncName<origFunc>(), firstParam, params...);
|
||||
LOG_FUNC(getFuncName<origFunc>(), params...);
|
||||
installHooks();
|
||||
suppressEmulatedDirectDraw(firstParam);
|
||||
return LOG_RESULT(reinterpret_cast<OrigFuncPtrType>(Dll::g_origProcs.*origFunc)(firstParam, params...));
|
||||
if constexpr (&Dll::Procs::DirectDrawCreate == origFunc || &Dll::Procs::DirectDrawCreateEx == origFunc)
|
||||
{
|
||||
DDraw::DirectDraw::suppressEmulatedDirectDraw(firstParam);
|
||||
}
|
||||
HRESULT result = reinterpret_cast<OrigFuncPtrType>(Dll::g_origProcs.*origFunc)(firstParam, params...);
|
||||
if constexpr (&Dll::Procs::DirectDrawCreate == origFunc || &Dll::Procs::DirectDrawCreateEx == origFunc)
|
||||
{
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
onDirectDrawCreate(firstParam, params...);
|
||||
}
|
||||
}
|
||||
return LOG_RESULT(result);
|
||||
}
|
||||
|
||||
void installHooks()
|
||||
@ -109,6 +122,16 @@ namespace
|
||||
(!Compat::isEqual(currentDllPath, dciman32DllPath) && GetModuleHandleW(dciman32DllPath.c_str()));
|
||||
}
|
||||
|
||||
void onDirectDrawCreate(GUID* lpGUID, LPDIRECTDRAW* lplpDD, IUnknown* /*pUnkOuter*/)
|
||||
{
|
||||
return DDraw::DirectDraw::onCreate(lpGUID, *CompatPtr<IDirectDraw7>::from(*lplpDD));
|
||||
}
|
||||
|
||||
void onDirectDrawCreate(GUID* lpGUID, LPVOID* lplpDD, REFIID /*iid*/, IUnknown* /*pUnkOuter*/)
|
||||
{
|
||||
return DDraw::DirectDraw::onCreate(lpGUID, *CompatPtr<IDirectDraw7>::from(static_cast<IDirectDraw7*>(*lplpDD)));
|
||||
}
|
||||
|
||||
void printEnvironmentVariable(const char* var)
|
||||
{
|
||||
Compat::Log() << "Environment variable " << var << " = \"" << Dll::getEnvVar(var) << '"';
|
||||
@ -128,16 +151,6 @@ namespace
|
||||
}
|
||||
SetProcessDPIAware();
|
||||
}
|
||||
|
||||
template <typename Param>
|
||||
void suppressEmulatedDirectDraw(Param)
|
||||
{
|
||||
}
|
||||
|
||||
void suppressEmulatedDirectDraw(GUID*& guid)
|
||||
{
|
||||
DDraw::DirectDraw::suppressEmulatedDirectDraw(guid);
|
||||
}
|
||||
}
|
||||
|
||||
#define LOAD_ORIG_PROC(proc) \
|
||||
|
Loading…
x
Reference in New Issue
Block a user