#pragma once #include #include #include namespace Compat { template struct GetBaseIntf { typedef Intf Type; }; template struct IsConvertible : std::integral_constant::Type, typename GetBaseIntf::Type>::value> { }; template struct IsConvertible : std::true_type {}; template struct IsConvertible : std::true_type {}; template<> struct IsConvertible : std::false_type {}; template<> struct IsConvertible : std::false_type {}; template<> struct IsConvertible : std::false_type {}; template<> struct IsConvertible : std::false_type {}; template<> struct IsConvertible : std::false_type {}; template<> struct IsConvertible : std::false_type {}; #define DEFINE_BASE_INTF(Intf, BaseIntf) \ template<> struct GetBaseIntf { typedef BaseIntf Type; } DEFINE_BASE_INTF(IDirectDraw2, IDirectDraw); DEFINE_BASE_INTF(IDirectDraw4, IDirectDraw); DEFINE_BASE_INTF(IDirectDraw7, IDirectDraw); DEFINE_BASE_INTF(IDirectDrawSurface2, IDirectDrawSurface); DEFINE_BASE_INTF(IDirectDrawSurface3, IDirectDrawSurface); DEFINE_BASE_INTF(IDirectDrawSurface4, IDirectDrawSurface); DEFINE_BASE_INTF(IDirectDrawSurface7, IDirectDrawSurface); DEFINE_BASE_INTF(IDirectDrawGammaControl, IDirectDrawSurface); DEFINE_BASE_INTF(IDirect3D, IDirectDraw); DEFINE_BASE_INTF(IDirect3D2, IDirectDraw); DEFINE_BASE_INTF(IDirect3D3, IDirectDraw); DEFINE_BASE_INTF(IDirect3D7, IDirectDraw); DEFINE_BASE_INTF(IDirect3DDevice2, IDirect3DDevice); DEFINE_BASE_INTF(IDirect3DDevice3, IDirect3DDevice); DEFINE_BASE_INTF(IDirect3DMaterial2, IDirect3DMaterial); DEFINE_BASE_INTF(IDirect3DMaterial3, IDirect3DMaterial); DEFINE_BASE_INTF(IDirect3DTexture, IDirectDrawSurface); DEFINE_BASE_INTF(IDirect3DTexture2, IDirectDrawSurface); DEFINE_BASE_INTF(IDirect3DViewport2, IDirect3DViewport); DEFINE_BASE_INTF(IDirect3DViewport3, IDirect3DViewport); #undef DEFINE_BASE_INTF template const IID& getIntfId(); #define DEFINE_INTF_ID(Intf) \ template<> inline const IID& getIntfId() { return IID_##Intf; } DEFINE_INTF_ID(IUnknown); DEFINE_INTF_ID(IDirectDraw); DEFINE_INTF_ID(IDirectDraw2); DEFINE_INTF_ID(IDirectDraw4); DEFINE_INTF_ID(IDirectDraw7); DEFINE_INTF_ID(IDirectDrawSurface); DEFINE_INTF_ID(IDirectDrawSurface2); DEFINE_INTF_ID(IDirectDrawSurface3); DEFINE_INTF_ID(IDirectDrawSurface4); DEFINE_INTF_ID(IDirectDrawSurface7); DEFINE_INTF_ID(IDirectDrawPalette); DEFINE_INTF_ID(IDirectDrawClipper); DEFINE_INTF_ID(IDirectDrawColorControl); DEFINE_INTF_ID(IDirectDrawGammaControl); DEFINE_INTF_ID(IDirect3D); DEFINE_INTF_ID(IDirect3D2); DEFINE_INTF_ID(IDirect3D3); DEFINE_INTF_ID(IDirect3D7); DEFINE_INTF_ID(IDirect3DDevice); DEFINE_INTF_ID(IDirect3DDevice2); DEFINE_INTF_ID(IDirect3DDevice3); DEFINE_INTF_ID(IDirect3DDevice7); DEFINE_INTF_ID(IDirect3DMaterial); DEFINE_INTF_ID(IDirect3DMaterial2); DEFINE_INTF_ID(IDirect3DMaterial3); DEFINE_INTF_ID(IDirect3DTexture); DEFINE_INTF_ID(IDirect3DTexture2); DEFINE_INTF_ID(IDirect3DViewport); DEFINE_INTF_ID(IDirect3DViewport2); DEFINE_INTF_ID(IDirect3DViewport3); #undef DEFINE_INTF_ID template std::enable_if_t::value> queryInterface(OrigIntf& origIntf, NewIntf*& newIntf) { getOrigVtable(&origIntf).QueryInterface(&origIntf, getIntfId(), reinterpret_cast(&newIntf)); } template void queryInterface(Intf& origIntf, Intf*& newIntf) { newIntf = &origIntf; getOrigVtable(newIntf).AddRef(newIntf); } template NewIntf* queryInterface(OrigIntf* origIntf) { if (!origIntf) { return nullptr; } NewIntf* newIntf = nullptr; queryInterface(*origIntf, newIntf); return newIntf; } }