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

Removed CompatVtable dependency on derived interface

This commit is contained in:
narzoul 2016-09-18 19:01:41 +02:00
parent 30bf0435f8
commit aabe85db65
23 changed files with 138 additions and 101 deletions

View File

@ -91,7 +91,8 @@ namespace Compat
template <typename NewIntf>
void queryInterface(IUnknown& origIntf, NewIntf*& newIntf)
{
CompatVtableBase<NewIntf>::getOrigVtable(reinterpret_cast<NewIntf&>(origIntf)).QueryInterface(
auto vtable(reinterpret_cast<NewIntf&>(origIntf).lpVtbl);
CompatVtable<Vtable<NewIntf>>::getOrigVtable(*vtable).QueryInterface(
reinterpret_cast<NewIntf*>(&origIntf),
getIntfId<NewIntf>(),
reinterpret_cast<void**>(&newIntf));
@ -100,7 +101,7 @@ namespace Compat
template <typename OrigIntf>
void queryInterface(OrigIntf& origIntf, IUnknown*& newIntf)
{
CompatVtableBase<OrigIntf>::getOrigVtable(origIntf).QueryInterface(
CompatVtable<Vtable<OrigIntf>>::getOrigVtable(*origIntf.lpVtbl).QueryInterface(
&origIntf, IID_IUnknown, reinterpret_cast<void**>(&newIntf));
}
@ -108,7 +109,7 @@ namespace Compat
std::enable_if_t<IsConvertible<OrigIntf, NewIntf>::value>
queryInterface(OrigIntf& origIntf, NewIntf*& newIntf)
{
CompatVtableBase<OrigIntf>::getOrigVtable(origIntf).QueryInterface(
CompatVtable<Vtable<OrigIntf>>::getOrigVtable(*origIntf.lpVtbl).QueryInterface(
&origIntf, getIntfId<NewIntf>(), reinterpret_cast<void**>(&newIntf));
}

View File

@ -12,7 +12,7 @@ public:
const Vtable<Intf>* operator->() const
{
return &CompatVtableBase<Intf>::getOrigVtable(m_intf);
return &CompatVtable<Vtable<Intf>>::getOrigVtable(*m_intf.lpVtbl);
}
Intf* operator&() const

View File

@ -9,44 +9,46 @@
#include "Common/VtableVisitor.h"
#include "DDraw/ScopedThreadLock.h"
#define SET_COMPAT_VTABLE(Vtable, CompatInterface) \
namespace Compat \
{ \
inline void setCompatVtable(Vtable& vtable) \
{ \
CompatInterface::setCompatVtable(vtable); \
} \
}
template <typename Interface>
using Vtable = typename std::remove_pointer<decltype(Interface::lpVtbl)>::type;
template <typename Interface>
class CompatVtableBase
template <typename Vtable>
class CompatVtable
{
public:
typedef Interface Interface;
static const Vtable<Interface>& getOrigVtable(Interface& intf)
static const Vtable& getOrigVtable(const Vtable& vtable)
{
return s_origVtable.AddRef ? s_origVtable : *intf.lpVtbl;
return s_origVtable.AddRef ? s_origVtable : vtable;
}
static Vtable<Interface> s_origVtable;
static const Vtable<Interface>* s_origVtablePtr;
};
template <typename CompatInterface, typename Interface>
class CompatVtable : public CompatVtableBase<Interface>
{
public:
static void hookVtable(const Vtable<Interface>* vtable)
static void hookVtable(const Vtable* vtable)
{
if (vtable && !s_origVtablePtr)
{
s_origVtablePtr = vtable;
InitVisitor visitor(*vtable);
forEach<Vtable<Interface>>(visitor);
forEach<Vtable>(visitor);
}
}
static Vtable s_origVtable;
static const Vtable* s_origVtablePtr;
private:
class InitVisitor
{
public:
InitVisitor(const Vtable<Interface>& origVtable) : m_origVtable(origVtable) {}
InitVisitor(const Vtable& origVtable) : m_origVtable(origVtable) {}
template <typename MemberDataPtr, MemberDataPtr ptr>
void visit()
@ -137,38 +139,38 @@ private:
#endif
}
const Vtable<Interface>& m_origVtable;
const Vtable& m_origVtable;
};
static Vtable<Interface> createCompatVtable()
static Vtable createCompatVtable()
{
Vtable<Interface> vtable = {};
CompatInterface::setCompatVtable(vtable);
Vtable vtable = {};
Compat::setCompatVtable(vtable);
return vtable;
}
static Vtable<Interface>& getCompatVtable()
static Vtable& getCompatVtable()
{
static Vtable<Interface> vtable(createCompatVtable());
static Vtable vtable(createCompatVtable());
return vtable;
}
static Vtable<Interface> s_compatVtable;
static Vtable<Interface> s_threadSafeVtable;
static Vtable s_compatVtable;
static Vtable s_threadSafeVtable;
static std::map<std::vector<unsigned char>, std::string> s_funcNames;
};
template <typename Interface>
Vtable<Interface> CompatVtableBase<Interface>::s_origVtable = {};
template <typename Vtable>
Vtable CompatVtable<Vtable>::s_origVtable = {};
template <typename Interface>
const Vtable<Interface>* CompatVtableBase<Interface>::s_origVtablePtr = nullptr;
template <typename Vtable>
const Vtable* CompatVtable<Vtable>::s_origVtablePtr = nullptr;
template <typename CompatInterface, typename Interface>
Vtable<Interface> CompatVtable<CompatInterface, Interface>::s_compatVtable(getCompatVtable());
template <typename Vtable>
Vtable CompatVtable<Vtable>::s_compatVtable(getCompatVtable());
template <typename CompatInterface, typename Interface>
Vtable<Interface> CompatVtable<CompatInterface, Interface>::s_threadSafeVtable = {};
template <typename Vtable>
Vtable CompatVtable<Vtable>::s_threadSafeVtable = {};
template <typename CompatInterface, typename Interface>
std::map<std::vector<unsigned char>, std::string> CompatVtable<CompatInterface, Interface>::s_funcNames;
template <typename Vtable>
std::map<std::vector<unsigned char>, std::string> CompatVtable<Vtable>::s_funcNames;

View File

@ -17,7 +17,7 @@ public:
const Vtable<Intf>* operator->() const
{
return &CompatVtableBase<Intf>::getOrigVtable(*m_intf);
return &CompatVtable<Vtable<Intf>>::getOrigVtable(*m_intf->lpVtbl);
}
operator Intf*() const

View File

@ -5,10 +5,11 @@
namespace D3dDdi
{
class AdapterCallbacks :
public CompatVtable<AdapterCallbacks, AdapterCallbacksIntf>
class AdapterCallbacks : public CompatVtable<D3DDDI_ADAPTERCALLBACKS>
{
public:
static void setCompatVtable(D3DDDI_ADAPTERCALLBACKS& vtable);
};
}
SET_COMPAT_VTABLE(D3DDDI_ADAPTERCALLBACKS, D3dDdi::AdapterCallbacks);

View File

@ -5,9 +5,11 @@
namespace D3dDdi
{
class AdapterFuncs : public CompatVtable<AdapterFuncs, AdapterFuncsIntf>
class AdapterFuncs : public CompatVtable<D3DDDI_ADAPTERFUNCS>
{
public:
static void setCompatVtable(D3DDDI_ADAPTERFUNCS& vtable);
};
}
SET_COMPAT_VTABLE(D3DDDI_ADAPTERFUNCS, D3dDdi::AdapterFuncs);

View File

@ -14,9 +14,11 @@ std::ostream& operator<<(std::ostream& os, const D3DDDICB_UNLOCK2& data);
namespace D3dDdi
{
class DeviceCallbacks : public CompatVtable<DeviceCallbacks, DeviceCallbacksIntf>
class DeviceCallbacks : public CompatVtable<D3DDDI_DEVICECALLBACKS>
{
public:
static void setCompatVtable(D3DDDI_DEVICECALLBACKS& vtable);
};
}
SET_COMPAT_VTABLE(D3DDDI_DEVICECALLBACKS, D3dDdi::DeviceCallbacks);

View File

@ -14,9 +14,11 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIBOX& val);
namespace D3dDdi
{
class DeviceFuncs : public CompatVtable<DeviceFuncs, DeviceFuncsIntf>
class DeviceFuncs : public CompatVtable<D3DDDI_DEVICEFUNCS>
{
public:
static void setCompatVtable(D3DDDI_DEVICEFUNCS& vtable);
};
}
SET_COMPAT_VTABLE(D3DDDI_DEVICEFUNCS, D3dDdi::DeviceFuncs);

View File

@ -7,7 +7,7 @@
namespace DDraw
{
template <typename TDirectDraw>
class DirectDraw: public CompatVtable<DirectDraw<TDirectDraw>, TDirectDraw>
class DirectDraw: public CompatVtable<Vtable<TDirectDraw>>
{
public:
typedef typename Types<TDirectDraw>::TCreatedSurface TSurface;
@ -34,3 +34,8 @@ namespace DDraw
Params... params);
};
}
SET_COMPAT_VTABLE(IDirectDrawVtbl, DDraw::DirectDraw<IDirectDraw>);
SET_COMPAT_VTABLE(IDirectDraw2Vtbl, DDraw::DirectDraw<IDirectDraw2>);
SET_COMPAT_VTABLE(IDirectDraw4Vtbl, DDraw::DirectDraw<IDirectDraw4>);
SET_COMPAT_VTABLE(IDirectDraw7Vtbl, DDraw::DirectDraw<IDirectDraw7>);

View File

@ -5,7 +5,7 @@
namespace DDraw
{
class DirectDrawPalette : public CompatVtable<DirectDrawPalette, IDirectDrawPalette>
class DirectDrawPalette : public CompatVtable<IDirectDrawPaletteVtbl>
{
public:
static void setCompatVtable(IDirectDrawPaletteVtbl& vtable);
@ -20,3 +20,5 @@ namespace DDraw
static void waitForNextUpdate();
};
}
SET_COMPAT_VTABLE(IDirectDrawPaletteVtbl, DDraw::DirectDrawPalette);

View File

@ -14,7 +14,7 @@ namespace
DDraw::Surface* surface = This ? DDraw::Surface::getSurface(*This) : nullptr;
if (!surface)
{
return (CompatVtableBase<TSurface>::s_origVtable.*origMethod)(This, params...);
return (CompatVtable<Vtable<TSurface>>::s_origVtable.*origMethod)(This, params...);
}
return (surface->getImpl<TSurface>()->*compatMethod)(This, params...);
}

View File

@ -8,7 +8,7 @@
namespace DDraw
{
template <typename TSurface>
class DirectDrawSurface : public CompatVtable<DirectDrawSurface<TSurface>, TSurface>
class DirectDrawSurface : public CompatVtable<Vtable<TSurface>>
{
public:
typedef typename Types<TSurface>::TSurfaceDesc TSurfaceDesc;
@ -19,3 +19,9 @@ namespace DDraw
static void setCompatVtable2(Vtable<TSurface>& vtable);
};
}
SET_COMPAT_VTABLE(IDirectDrawSurfaceVtbl, DDraw::DirectDrawSurface<IDirectDrawSurface>);
SET_COMPAT_VTABLE(IDirectDrawSurface2Vtbl, DDraw::DirectDrawSurface<IDirectDrawSurface2>);
SET_COMPAT_VTABLE(IDirectDrawSurface3Vtbl, DDraw::DirectDrawSurface<IDirectDrawSurface3>);
SET_COMPAT_VTABLE(IDirectDrawSurface4Vtbl, DDraw::DirectDrawSurface<IDirectDrawSurface4>);
SET_COMPAT_VTABLE(IDirectDrawSurface7Vtbl, DDraw::DirectDrawSurface<IDirectDrawSurface7>);

View File

@ -16,17 +16,17 @@
namespace
{
template <typename CompatInterface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf);
template <typename Interface>
void hookVtable(const CompatPtr<Interface>& intf);
void hookDirectDraw(CompatRef<IDirectDraw7> dd)
{
DDraw::DirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl;
CompatPtr<IDirectDraw7> dd7(&dd);
hookVtable<DDraw::DirectDraw<IDirectDraw>>(dd7);
hookVtable<DDraw::DirectDraw<IDirectDraw2>>(dd7);
hookVtable<DDraw::DirectDraw<IDirectDraw4>>(dd7);
hookVtable<DDraw::DirectDraw<IDirectDraw7>>(dd7);
hookVtable<IDirectDraw>(dd7);
hookVtable<IDirectDraw2>(dd7);
hookVtable<IDirectDraw4>(dd7);
hookVtable<IDirectDraw7>(dd7);
dd7.detach();
}
@ -60,11 +60,11 @@ namespace
if (SUCCEEDED(result))
{
DDraw::DirectDrawSurface<IDirectDrawSurface7>::s_origVtable = *surface.get()->lpVtbl;
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface>>(surface);
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface2>>(surface);
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface3>>(surface);
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface4>>(surface);
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface7>>(surface);
hookVtable<IDirectDrawSurface>(surface);
hookVtable<IDirectDrawSurface2>(surface);
hookVtable<IDirectDrawSurface3>(surface);
hookVtable<IDirectDrawSurface4>(surface);
hookVtable<IDirectDrawSurface7>(surface);
}
else
{
@ -72,10 +72,10 @@ namespace
}
}
template <typename CompatInterface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf)
template <typename Interface>
void hookVtable(const CompatPtr<Interface>& intf)
{
CompatInterface::hookVtable(intf.get()->lpVtbl);
CompatVtable<Vtable<Interface>>::hookVtable(intf.get()->lpVtbl);
}
}

View File

@ -66,7 +66,7 @@ namespace DDraw
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
g_primarySurfaceDesc.dwSize = sizeof(g_primarySurfaceDesc);
CompatVtableBase<IDirectDrawSurface7>::s_origVtable.GetSurfaceDesc(surface7, &g_primarySurfaceDesc);
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtable.GetSurfaceDesc(surface7, &g_primarySurfaceDesc);
return DD_OK;
}

View File

@ -63,7 +63,7 @@ namespace DDraw
{
TSurfaceDesc desc = {};
desc.dwSize = sizeof(desc);
CompatVtableBase<TSurface>::s_origVtable.GetSurfaceDesc(lpDDSrcSurface, &desc);
CompatVtable<Vtable<TSurface>>::s_origVtable.GetSurfaceDesc(lpDDSrcSurface, &desc);
destRect.right += desc.dwWidth;
destRect.bottom += desc.dwHeight;
}

View File

@ -35,19 +35,19 @@ namespace
IID getDdIidFromVtablePtr(const void* vtablePtr)
{
if (CompatVtableBase<IDirectDraw>::s_origVtablePtr == vtablePtr)
if (CompatVtable<IDirectDrawVtbl>::s_origVtablePtr == vtablePtr)
{
return IID_IDirectDraw;
}
if (CompatVtableBase<IDirectDraw2>::s_origVtablePtr == vtablePtr)
if (CompatVtable<IDirectDraw2Vtbl>::s_origVtablePtr == vtablePtr)
{
return IID_IDirectDraw2;
}
if (CompatVtableBase<IDirectDraw4>::s_origVtablePtr == vtablePtr)
if (CompatVtable<IDirectDraw4Vtbl>::s_origVtablePtr == vtablePtr)
{
return IID_IDirectDraw4;
}
if (CompatVtableBase<IDirectDraw7>::s_origVtablePtr == vtablePtr)
if (CompatVtable<IDirectDraw7Vtbl>::s_origVtablePtr == vtablePtr)
{
return IID_IDirectDraw7;
}
@ -94,7 +94,7 @@ namespace DDraw
privateData.get(), sizeof(privateData.get()), DDSPD_IUNKNOWNPOINTER)))
{
CompatPtr<IUnknown> dd;
CompatVtableBase<IDirectDrawSurface7>::s_origVtable.GetDDInterface(
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtable.GetDDInterface(
&dds, reinterpret_cast<void**>(&dd.getRef()));
privateData->createImpl();
@ -122,7 +122,7 @@ namespace DDraw
std::unique_ptr<DDraw::Surface> privateData(new Surface());
attach(*surface, privateData);
CompatVtableBase<IDirectDrawSurface7>::s_origVtable.EnumAttachedSurfaces(
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtable.EnumAttachedSurfaces(
surface, rootSurface, &attachToLinkedSurfaces);
return DDENUMRET_OK;
}
@ -144,7 +144,7 @@ namespace DDraw
attach(*surface7, privateData);
if (desc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
{
CompatVtableBase<IDirectDrawSurface7>::s_origVtable.EnumAttachedSurfaces(
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtable.EnumAttachedSurfaces(
surface7, surface7, &attachToLinkedSurfaces);
}
}
@ -188,7 +188,7 @@ namespace DDraw
DWORD surfacePtrSize = sizeof(surface);
// This can get called during surface release so a proper QueryInterface would be dangerous
CompatVtableBase<IDirectDrawSurface7>::s_origVtable.GetPrivateData(
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtable.GetPrivateData(
reinterpret_cast<IDirectDrawSurface7*>(&dds),
IID_CompatSurfacePrivateData, &surface, &surfacePtrSize);

View File

@ -248,10 +248,10 @@ namespace DDraw
{
DirectDrawInterface dd = {};
dd.vtable = IID_IDirectDraw7 == m_data->m_ddId
? static_cast<const void*>(CompatVtableBase<IDirectDraw>::s_origVtablePtr)
: static_cast<const void*>(CompatVtableBase<IDirectDraw7>::s_origVtablePtr);
? static_cast<const void*>(CompatVtable<IDirectDrawVtbl>::s_origVtablePtr)
: static_cast<const void*>(CompatVtable<IDirectDraw7Vtbl>::s_origVtablePtr);
dd.ddObject = m_data->m_ddObject;
return CompatVtableBase<IDirectDraw>::s_origVtable.QueryInterface(
return CompatVtable<IDirectDrawVtbl>::s_origVtable.QueryInterface(
reinterpret_cast<IDirectDraw*>(&dd), m_data->m_ddId, lplpDD);
}
@ -325,7 +325,8 @@ namespace DDraw
}
template <typename TSurface>
const Vtable<TSurface>& SurfaceImpl<TSurface>::s_origVtable = CompatVtableBase<TSurface>::s_origVtable;
const Vtable<TSurface>& SurfaceImpl<TSurface>::s_origVtable =
CompatVtable<Vtable<TSurface>>::s_origVtable;
template SurfaceImpl<IDirectDrawSurface>;
template SurfaceImpl<IDirectDrawSurface2>;

View File

@ -45,7 +45,7 @@ namespace
{
if (!lpEnumDevicesCallback)
{
return CompatVtableBase<TDirect3d>::s_origVtable.EnumDevices(
return CompatVtable<Vtable<TDirect3d>>::s_origVtable.EnumDevices(
This, lpEnumDevicesCallback, lpUserArg);
}
@ -53,7 +53,7 @@ namespace
CompatPtr<TDirect3dHighest> d3d(Compat::queryInterface<TDirect3dHighest>(This));
EnumDevicesParams<TDirect3dHighest> params = { d3d, lpEnumDevicesCallback, lpUserArg };
return CompatVtableBase<TDirect3d>::s_origVtable.EnumDevices(
return CompatVtable<Vtable<TDirect3d>>::s_origVtable.EnumDevices(
This, &d3dEnumDevicesCallback, &params);
}
}

View File

@ -6,9 +6,14 @@
namespace Direct3d
{
template <typename TDirect3d>
class Direct3d : public CompatVtable<Direct3d<TDirect3d>, TDirect3d>
class Direct3d : public CompatVtable<Vtable<TDirect3d>>
{
public:
static void setCompatVtable(Vtable<TDirect3d>& vtable);
};
}
SET_COMPAT_VTABLE(IDirect3DVtbl, Direct3d::Direct3d<IDirect3D>);
SET_COMPAT_VTABLE(IDirect3D2Vtbl, Direct3d::Direct3d<IDirect3D2>);
SET_COMPAT_VTABLE(IDirect3D3Vtbl, Direct3d::Direct3d<IDirect3D3>);
SET_COMPAT_VTABLE(IDirect3D7Vtbl, Direct3d::Direct3d<IDirect3D7>);

View File

@ -11,7 +11,7 @@ namespace
{
typedef typename Direct3d::Types<TDirect3dDevice>::TDirect3d TDirect3d;
CompatPtr<TDirect3d> d3d;
if (SUCCEEDED(CompatVtableBase<TDirect3dDevice>::s_origVtable.GetDirect3D(
if (SUCCEEDED(CompatVtable<Vtable<TDirect3dDevice>>::s_origVtable.GetDirect3D(
&d3dDevice, &d3d.getRef())))
{
typedef typename Direct3d::Types<TDirect3dDevice>::TDirect3dHighest TDirect3dHighest;
@ -25,7 +25,7 @@ namespace
TD3dDeviceDesc* lpD3DHWDevDesc,
Params... params)
{
HRESULT result = CompatVtableBase<TDirect3dDevice>::s_origVtable.GetCaps(
HRESULT result = CompatVtable<Vtable<TDirect3dDevice>>::s_origVtable.GetCaps(
This, lpD3DHWDevDesc, params...);
if (SUCCEEDED(result))
{

View File

@ -6,9 +6,14 @@
namespace Direct3d
{
template <typename TDirect3dDevice>
class Direct3dDevice : public CompatVtable<Direct3dDevice<TDirect3dDevice>, TDirect3dDevice>
class Direct3dDevice : public CompatVtable<Vtable<TDirect3dDevice>>
{
public:
static void setCompatVtable(Vtable<TDirect3dDevice>& vtable);
};
}
SET_COMPAT_VTABLE(IDirect3DDeviceVtbl, Direct3d::Direct3dDevice<IDirect3DDevice>);
SET_COMPAT_VTABLE(IDirect3DDevice2Vtbl, Direct3d::Direct3dDevice<IDirect3DDevice2>);
SET_COMPAT_VTABLE(IDirect3DDevice3Vtbl, Direct3d::Direct3dDevice<IDirect3DDevice3>);
SET_COMPAT_VTABLE(IDirect3DDevice7Vtbl, Direct3d::Direct3dDevice<IDirect3DDevice7>);

View File

@ -16,8 +16,8 @@ namespace
void hookDirect3dDevice(CompatRef<IDirect3D3> d3d, CompatRef<IDirectDrawSurface4> renderTarget);
void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget);
template <typename CompatInterface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf);
template <typename Interface>
void hookVtable(const CompatPtr<Interface>& intf);
template <typename TDirect3d, typename TDirectDraw>
CompatPtr<TDirect3d> createDirect3d(CompatRef<TDirectDraw> dd)
@ -76,9 +76,9 @@ namespace
CompatPtr<IDirect3D3> d3d(createDirect3d<IDirect3D3>(dd));
if (d3d)
{
hookVtable<Direct3d::Direct3d<IDirect3D>>(d3d);
hookVtable<Direct3d::Direct3d<IDirect3D2>>(d3d);
hookVtable<Direct3d::Direct3d<IDirect3D3>>(d3d);
hookVtable<IDirect3D>(d3d);
hookVtable<IDirect3D2>(d3d);
hookVtable<IDirect3D3>(d3d);
hookDirect3dDevice(*d3d, renderTarget);
}
}
@ -88,7 +88,7 @@ namespace
CompatPtr<IDirect3D7> d3d(createDirect3d<IDirect3D7>(dd));
if (d3d)
{
hookVtable<Direct3d::Direct3d<IDirect3D7>>(d3d);
hookVtable<IDirect3D7>(d3d);
hookDirect3dDevice7(*d3d, renderTarget);
}
}
@ -98,9 +98,9 @@ namespace
CompatPtr<IDirect3DDevice3> d3dDevice(
createDirect3dDevice<IDirect3DDevice3>(d3d, renderTarget, nullptr));
hookVtable<Direct3d::Direct3dDevice<IDirect3DDevice>>(d3dDevice);
hookVtable<Direct3d::Direct3dDevice<IDirect3DDevice2>>(d3dDevice);
hookVtable<Direct3d::Direct3dDevice<IDirect3DDevice3>>(d3dDevice);
hookVtable<IDirect3DDevice>(d3dDevice);
hookVtable<IDirect3DDevice2>(d3dDevice);
hookVtable<IDirect3DDevice3>(d3dDevice);
}
void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget)
@ -108,13 +108,13 @@ namespace
CompatPtr<IDirect3DDevice7> d3dDevice(
createDirect3dDevice<IDirect3DDevice7>(d3d, renderTarget));
hookVtable<Direct3d::Direct3dDevice<IDirect3DDevice7>>(d3dDevice);
hookVtable<IDirect3DDevice7>(d3dDevice);
}
template <typename CompatInterface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf)
template <typename Interface>
void hookVtable(const CompatPtr<Interface>& intf)
{
CompatInterface::hookVtable(intf.get()->lpVtbl);
CompatVtable<Vtable<Interface>>::hookVtable(intf.get()->lpVtbl);
}
}

View File

@ -59,7 +59,7 @@ namespace
DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc);
auto primary(DDraw::PrimarySurface::getPrimary());
if (FAILED(primary->Lock(primary, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
if (!primary || FAILED(primary->Lock(primary, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
{
return false;
}
@ -80,11 +80,14 @@ namespace
{
GdiFlush();
auto primary(DDraw::PrimarySurface::getPrimary());
primary->Unlock(primary, nullptr);
if (DDLOCK_READONLY != g_ddLockFlags)
if (primary)
{
DDraw::RealPrimarySurface::invalidate(nullptr);
DDraw::RealPrimarySurface::update();
primary->Unlock(primary, nullptr);
if (DDLOCK_READONLY != g_ddLockFlags)
{
DDraw::RealPrimarySurface::invalidate(nullptr);
DDraw::RealPrimarySurface::update();
}
}
if (0 != g_ddLockFlags)