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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,9 +5,11 @@
namespace D3dDdi namespace D3dDdi
{ {
class AdapterFuncs : public CompatVtable<AdapterFuncs, AdapterFuncsIntf> class AdapterFuncs : public CompatVtable<D3DDDI_ADAPTERFUNCS>
{ {
public: public:
static void setCompatVtable(D3DDDI_ADAPTERFUNCS& vtable); 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 namespace D3dDdi
{ {
class DeviceCallbacks : public CompatVtable<DeviceCallbacks, DeviceCallbacksIntf> class DeviceCallbacks : public CompatVtable<D3DDDI_DEVICECALLBACKS>
{ {
public: public:
static void setCompatVtable(D3DDDI_DEVICECALLBACKS& vtable); 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 namespace D3dDdi
{ {
class DeviceFuncs : public CompatVtable<DeviceFuncs, DeviceFuncsIntf> class DeviceFuncs : public CompatVtable<D3DDDI_DEVICEFUNCS>
{ {
public: public:
static void setCompatVtable(D3DDDI_DEVICEFUNCS& vtable); static void setCompatVtable(D3DDDI_DEVICEFUNCS& vtable);
}; };
} }
SET_COMPAT_VTABLE(D3DDDI_DEVICEFUNCS, D3dDdi::DeviceFuncs);

View File

@ -7,7 +7,7 @@
namespace DDraw namespace DDraw
{ {
template <typename TDirectDraw> template <typename TDirectDraw>
class DirectDraw: public CompatVtable<DirectDraw<TDirectDraw>, TDirectDraw> class DirectDraw: public CompatVtable<Vtable<TDirectDraw>>
{ {
public: public:
typedef typename Types<TDirectDraw>::TCreatedSurface TSurface; typedef typename Types<TDirectDraw>::TCreatedSurface TSurface;
@ -34,3 +34,8 @@ namespace DDraw
Params... params); 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 namespace DDraw
{ {
class DirectDrawPalette : public CompatVtable<DirectDrawPalette, IDirectDrawPalette> class DirectDrawPalette : public CompatVtable<IDirectDrawPaletteVtbl>
{ {
public: public:
static void setCompatVtable(IDirectDrawPaletteVtbl& vtable); static void setCompatVtable(IDirectDrawPaletteVtbl& vtable);
@ -20,3 +20,5 @@ namespace DDraw
static void waitForNextUpdate(); 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; DDraw::Surface* surface = This ? DDraw::Surface::getSurface(*This) : nullptr;
if (!surface) 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...); return (surface->getImpl<TSurface>()->*compatMethod)(This, params...);
} }

View File

@ -8,7 +8,7 @@
namespace DDraw namespace DDraw
{ {
template <typename TSurface> template <typename TSurface>
class DirectDrawSurface : public CompatVtable<DirectDrawSurface<TSurface>, TSurface> class DirectDrawSurface : public CompatVtable<Vtable<TSurface>>
{ {
public: public:
typedef typename Types<TSurface>::TSurfaceDesc TSurfaceDesc; typedef typename Types<TSurface>::TSurfaceDesc TSurfaceDesc;
@ -19,3 +19,9 @@ namespace DDraw
static void setCompatVtable2(Vtable<TSurface>& vtable); 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 namespace
{ {
template <typename CompatInterface> template <typename Interface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf); void hookVtable(const CompatPtr<Interface>& intf);
void hookDirectDraw(CompatRef<IDirectDraw7> dd) void hookDirectDraw(CompatRef<IDirectDraw7> dd)
{ {
DDraw::DirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl; DDraw::DirectDraw<IDirectDraw7>::s_origVtable = *(&dd)->lpVtbl;
CompatPtr<IDirectDraw7> dd7(&dd); CompatPtr<IDirectDraw7> dd7(&dd);
hookVtable<DDraw::DirectDraw<IDirectDraw>>(dd7); hookVtable<IDirectDraw>(dd7);
hookVtable<DDraw::DirectDraw<IDirectDraw2>>(dd7); hookVtable<IDirectDraw2>(dd7);
hookVtable<DDraw::DirectDraw<IDirectDraw4>>(dd7); hookVtable<IDirectDraw4>(dd7);
hookVtable<DDraw::DirectDraw<IDirectDraw7>>(dd7); hookVtable<IDirectDraw7>(dd7);
dd7.detach(); dd7.detach();
} }
@ -60,11 +60,11 @@ namespace
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
DDraw::DirectDrawSurface<IDirectDrawSurface7>::s_origVtable = *surface.get()->lpVtbl; DDraw::DirectDrawSurface<IDirectDrawSurface7>::s_origVtable = *surface.get()->lpVtbl;
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface>>(surface); hookVtable<IDirectDrawSurface>(surface);
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface2>>(surface); hookVtable<IDirectDrawSurface2>(surface);
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface3>>(surface); hookVtable<IDirectDrawSurface3>(surface);
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface4>>(surface); hookVtable<IDirectDrawSurface4>(surface);
hookVtable<DDraw::DirectDrawSurface<IDirectDrawSurface7>>(surface); hookVtable<IDirectDrawSurface7>(surface);
} }
else else
{ {
@ -72,10 +72,10 @@ namespace
} }
} }
template <typename CompatInterface> template <typename Interface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf) 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)); ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
g_primarySurfaceDesc.dwSize = 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; return DD_OK;
} }

View File

@ -63,7 +63,7 @@ namespace DDraw
{ {
TSurfaceDesc desc = {}; TSurfaceDesc desc = {};
desc.dwSize = sizeof(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.right += desc.dwWidth;
destRect.bottom += desc.dwHeight; destRect.bottom += desc.dwHeight;
} }

View File

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

View File

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

View File

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

View File

@ -6,9 +6,14 @@
namespace Direct3d namespace Direct3d
{ {
template <typename TDirect3d> template <typename TDirect3d>
class Direct3d : public CompatVtable<Direct3d<TDirect3d>, TDirect3d> class Direct3d : public CompatVtable<Vtable<TDirect3d>>
{ {
public: public:
static void setCompatVtable(Vtable<TDirect3d>& vtable); 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; typedef typename Direct3d::Types<TDirect3dDevice>::TDirect3d TDirect3d;
CompatPtr<TDirect3d> d3d; CompatPtr<TDirect3d> d3d;
if (SUCCEEDED(CompatVtableBase<TDirect3dDevice>::s_origVtable.GetDirect3D( if (SUCCEEDED(CompatVtable<Vtable<TDirect3dDevice>>::s_origVtable.GetDirect3D(
&d3dDevice, &d3d.getRef()))) &d3dDevice, &d3d.getRef())))
{ {
typedef typename Direct3d::Types<TDirect3dDevice>::TDirect3dHighest TDirect3dHighest; typedef typename Direct3d::Types<TDirect3dDevice>::TDirect3dHighest TDirect3dHighest;
@ -25,7 +25,7 @@ namespace
TD3dDeviceDesc* lpD3DHWDevDesc, TD3dDeviceDesc* lpD3DHWDevDesc,
Params... params) Params... params)
{ {
HRESULT result = CompatVtableBase<TDirect3dDevice>::s_origVtable.GetCaps( HRESULT result = CompatVtable<Vtable<TDirect3dDevice>>::s_origVtable.GetCaps(
This, lpD3DHWDevDesc, params...); This, lpD3DHWDevDesc, params...);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {

View File

@ -6,9 +6,14 @@
namespace Direct3d namespace Direct3d
{ {
template <typename TDirect3dDevice> template <typename TDirect3dDevice>
class Direct3dDevice : public CompatVtable<Direct3dDevice<TDirect3dDevice>, TDirect3dDevice> class Direct3dDevice : public CompatVtable<Vtable<TDirect3dDevice>>
{ {
public: public:
static void setCompatVtable(Vtable<TDirect3dDevice>& vtable); 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 hookDirect3dDevice(CompatRef<IDirect3D3> d3d, CompatRef<IDirectDrawSurface4> renderTarget);
void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget); void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget);
template <typename CompatInterface> template <typename Interface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf); void hookVtable(const CompatPtr<Interface>& intf);
template <typename TDirect3d, typename TDirectDraw> template <typename TDirect3d, typename TDirectDraw>
CompatPtr<TDirect3d> createDirect3d(CompatRef<TDirectDraw> dd) CompatPtr<TDirect3d> createDirect3d(CompatRef<TDirectDraw> dd)
@ -76,9 +76,9 @@ namespace
CompatPtr<IDirect3D3> d3d(createDirect3d<IDirect3D3>(dd)); CompatPtr<IDirect3D3> d3d(createDirect3d<IDirect3D3>(dd));
if (d3d) if (d3d)
{ {
hookVtable<Direct3d::Direct3d<IDirect3D>>(d3d); hookVtable<IDirect3D>(d3d);
hookVtable<Direct3d::Direct3d<IDirect3D2>>(d3d); hookVtable<IDirect3D2>(d3d);
hookVtable<Direct3d::Direct3d<IDirect3D3>>(d3d); hookVtable<IDirect3D3>(d3d);
hookDirect3dDevice(*d3d, renderTarget); hookDirect3dDevice(*d3d, renderTarget);
} }
} }
@ -88,7 +88,7 @@ namespace
CompatPtr<IDirect3D7> d3d(createDirect3d<IDirect3D7>(dd)); CompatPtr<IDirect3D7> d3d(createDirect3d<IDirect3D7>(dd));
if (d3d) if (d3d)
{ {
hookVtable<Direct3d::Direct3d<IDirect3D7>>(d3d); hookVtable<IDirect3D7>(d3d);
hookDirect3dDevice7(*d3d, renderTarget); hookDirect3dDevice7(*d3d, renderTarget);
} }
} }
@ -98,9 +98,9 @@ namespace
CompatPtr<IDirect3DDevice3> d3dDevice( CompatPtr<IDirect3DDevice3> d3dDevice(
createDirect3dDevice<IDirect3DDevice3>(d3d, renderTarget, nullptr)); createDirect3dDevice<IDirect3DDevice3>(d3d, renderTarget, nullptr));
hookVtable<Direct3d::Direct3dDevice<IDirect3DDevice>>(d3dDevice); hookVtable<IDirect3DDevice>(d3dDevice);
hookVtable<Direct3d::Direct3dDevice<IDirect3DDevice2>>(d3dDevice); hookVtable<IDirect3DDevice2>(d3dDevice);
hookVtable<Direct3d::Direct3dDevice<IDirect3DDevice3>>(d3dDevice); hookVtable<IDirect3DDevice3>(d3dDevice);
} }
void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget) void hookDirect3dDevice7(CompatRef<IDirect3D7> d3d, CompatRef<IDirectDrawSurface7> renderTarget)
@ -108,13 +108,13 @@ namespace
CompatPtr<IDirect3DDevice7> d3dDevice( CompatPtr<IDirect3DDevice7> d3dDevice(
createDirect3dDevice<IDirect3DDevice7>(d3d, renderTarget)); createDirect3dDevice<IDirect3DDevice7>(d3d, renderTarget));
hookVtable<Direct3d::Direct3dDevice<IDirect3DDevice7>>(d3dDevice); hookVtable<IDirect3DDevice7>(d3dDevice);
} }
template <typename CompatInterface> template <typename Interface>
void hookVtable(const CompatPtr<typename CompatInterface::Interface>& intf) 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 = {}; DDSURFACEDESC2 desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
auto primary(DDraw::PrimarySurface::getPrimary()); 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; return false;
} }
@ -80,11 +80,14 @@ namespace
{ {
GdiFlush(); GdiFlush();
auto primary(DDraw::PrimarySurface::getPrimary()); auto primary(DDraw::PrimarySurface::getPrimary());
primary->Unlock(primary, nullptr); if (primary)
if (DDLOCK_READONLY != g_ddLockFlags)
{ {
DDraw::RealPrimarySurface::invalidate(nullptr); primary->Unlock(primary, nullptr);
DDraw::RealPrimarySurface::update(); if (DDLOCK_READONLY != g_ddLockFlags)
{
DDraw::RealPrimarySurface::invalidate(nullptr);
DDraw::RealPrimarySurface::update();
}
} }
if (0 != g_ddLockFlags) if (0 != g_ddLockFlags)