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

Allow PrimarySurface to wrap different surface implementations

This commit is contained in:
narzoul 2016-09-11 22:44:30 +02:00
parent 47f02667bf
commit d163787437
7 changed files with 77 additions and 49 deletions

View File

@ -11,13 +11,12 @@ namespace
typename TSurface, typename... Params> typename TSurface, typename... Params>
HRESULT STDMETHODCALLTYPE callImpl(TSurface* This, Params... params) HRESULT STDMETHODCALLTYPE callImpl(TSurface* This, Params... params)
{ {
DDraw::SurfaceImpl<TSurface>* surfaceImpl = DDraw::Surface* surface = This ? DDraw::Surface::getSurface(*This) : nullptr;
This ? DDraw::Surface::getImpl<TSurface>(*This) : nullptr; if (!surface)
if (!surfaceImpl)
{ {
return (CompatVtableBase<TSurface>::s_origVtable.*origMethod)(This, params...); return (CompatVtableBase<TSurface>::s_origVtable.*origMethod)(This, params...);
} }
return (surfaceImpl->*compatMethod)(This, params...); return (surface->getImpl<TSurface>()->*compatMethod)(This, params...);
} }
} }

View File

@ -12,6 +12,11 @@ namespace
namespace DDraw namespace DDraw
{ {
PrimarySurface::PrimarySurface(Surface* surface) : m_surface(surface)
{
surface->AddRef();
}
PrimarySurface::~PrimarySurface() PrimarySurface::~PrimarySurface()
{ {
Compat::LogEnter("PrimarySurface::~PrimarySurface"); Compat::LogEnter("PrimarySurface::~PrimarySurface");
@ -53,7 +58,7 @@ namespace DDraw
} }
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(surface)); CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(surface));
std::unique_ptr<Surface> privateData(new PrimarySurface()); std::unique_ptr<Surface> privateData(new PrimarySurface(Surface::getSurface(*surface)));
attach(*surface7, privateData); attach(*surface7, privateData);
CompatPtr<IDirectDrawSurface> surface1(Compat::queryInterface<IDirectDrawSurface>(surface)); CompatPtr<IDirectDrawSurface> surface1(Compat::queryInterface<IDirectDrawSurface>(surface));
@ -77,11 +82,11 @@ namespace DDraw
void PrimarySurface::createImpl() void PrimarySurface::createImpl()
{ {
m_impl.reset(new PrimarySurfaceImpl<IDirectDrawSurface>()); m_impl.reset(new PrimarySurfaceImpl<IDirectDrawSurface>(*m_surface->getImpl<IDirectDrawSurface>()));
m_impl2.reset(new PrimarySurfaceImpl<IDirectDrawSurface2>()); m_impl2.reset(new PrimarySurfaceImpl<IDirectDrawSurface2>(*m_surface->getImpl<IDirectDrawSurface2>()));
m_impl3.reset(new PrimarySurfaceImpl<IDirectDrawSurface3>()); m_impl3.reset(new PrimarySurfaceImpl<IDirectDrawSurface3>(*m_surface->getImpl<IDirectDrawSurface3>()));
m_impl4.reset(new PrimarySurfaceImpl<IDirectDrawSurface4>()); m_impl4.reset(new PrimarySurfaceImpl<IDirectDrawSurface4>(*m_surface->getImpl<IDirectDrawSurface4>()));
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>()); m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>(*m_surface->getImpl<IDirectDrawSurface7>()));
} }
const DDSURFACEDESC2& PrimarySurface::getDesc() const DDSURFACEDESC2& PrimarySurface::getDesc()

View File

@ -20,6 +20,10 @@ namespace DDraw
static PALETTEENTRY s_paletteEntries[256]; static PALETTEENTRY s_paletteEntries[256];
private: private:
PrimarySurface(Surface* surface);
virtual void createImpl() override; virtual void createImpl() override;
std::unique_ptr<Surface> m_surface;
}; };
} }

View File

@ -15,6 +15,11 @@ namespace
namespace DDraw namespace DDraw
{ {
template <typename TSurface>
PrimarySurfaceImpl<TSurface>::PrimarySurfaceImpl(SurfaceImpl& impl) : m_impl(impl)
{
}
template <typename TSurface> template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Blt( HRESULT PrimarySurfaceImpl<TSurface>::Blt(
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
@ -25,7 +30,7 @@ namespace DDraw
return DDERR_SURFACELOST; return DDERR_SURFACELOST;
} }
HRESULT result = SurfaceImpl::Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx); HRESULT result = m_impl.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
RealPrimarySurface::invalidate(lpDestRect); RealPrimarySurface::invalidate(lpDestRect);
@ -43,7 +48,7 @@ namespace DDraw
return DDERR_SURFACELOST; return DDERR_SURFACELOST;
} }
HRESULT result = SurfaceImpl::BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans); HRESULT result = m_impl.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
const LONG x = dwX; const LONG x = dwX;
@ -76,7 +81,7 @@ namespace DDraw
return DDERR_SURFACELOST; return DDERR_SURFACELOST;
} }
HRESULT result = SurfaceImpl::Flip(This, lpDDSurfaceTargetOverride, dwFlags); HRESULT result = m_impl.Flip(This, lpDDSurfaceTargetOverride, dwFlags);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
result = RealPrimarySurface::flip(dwFlags); result = RealPrimarySurface::flip(dwFlags);
@ -87,7 +92,7 @@ namespace DDraw
template <typename TSurface> template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps) HRESULT PrimarySurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
{ {
HRESULT result = SurfaceImpl::GetCaps(This, lpDDSCaps); HRESULT result = m_impl.GetCaps(This, lpDDSCaps);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
restorePrimaryCaps(lpDDSCaps->dwCaps); restorePrimaryCaps(lpDDSCaps->dwCaps);
@ -98,7 +103,7 @@ namespace DDraw
template <typename TSurface> template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc) HRESULT PrimarySurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
{ {
HRESULT result = SurfaceImpl::GetSurfaceDesc(This, lpDDSurfaceDesc); HRESULT result = m_impl.GetSurfaceDesc(This, lpDDSurfaceDesc);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps); restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
@ -109,7 +114,7 @@ namespace DDraw
template <typename TSurface> template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::IsLost(TSurface* This) HRESULT PrimarySurfaceImpl<TSurface>::IsLost(TSurface* This)
{ {
HRESULT result = SurfaceImpl::IsLost(This); HRESULT result = m_impl.IsLost(This);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK; result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
@ -127,7 +132,7 @@ namespace DDraw
return DDERR_SURFACELOST; return DDERR_SURFACELOST;
} }
HRESULT result = SurfaceImpl::Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent); HRESULT result = m_impl.Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
RealPrimarySurface::invalidate(lpDestRect); RealPrimarySurface::invalidate(lpDestRect);
@ -144,13 +149,13 @@ namespace DDraw
auto realPrimary(RealPrimarySurface::getSurface()); auto realPrimary(RealPrimarySurface::getSurface());
return realPrimary->QueryInterface(realPrimary, riid, obp); return realPrimary->QueryInterface(realPrimary, riid, obp);
} }
return SurfaceImpl::QueryInterface(This, riid, obp); return m_impl.QueryInterface(This, riid, obp);
} }
template <typename TSurface> template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC) HRESULT PrimarySurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
{ {
HRESULT result = SurfaceImpl::ReleaseDC(This, hDC); HRESULT result = m_impl.ReleaseDC(This, hDC);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
RealPrimarySurface::invalidate(nullptr); RealPrimarySurface::invalidate(nullptr);
@ -168,7 +173,7 @@ namespace DDraw
result = RealPrimarySurface::restore(); result = RealPrimarySurface::restore();
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
result = SurfaceImpl::Restore(This); result = m_impl.Restore(This);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
fixSurfacePtrs(*This); fixSurfacePtrs(*This);
@ -182,7 +187,7 @@ namespace DDraw
template <typename TSurface> template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper) HRESULT PrimarySurfaceImpl<TSurface>::SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper)
{ {
HRESULT result = SurfaceImpl::SetClipper(This, lpDDClipper); HRESULT result = m_impl.SetClipper(This, lpDDClipper);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
RealPrimarySurface::setClipper(lpDDClipper); RealPrimarySurface::setClipper(lpDDClipper);
@ -202,7 +207,7 @@ namespace DDraw
return DD_OK; return DD_OK;
} }
HRESULT result = SurfaceImpl::SetPalette(This, lpDDPalette); HRESULT result = m_impl.SetPalette(This, lpDDPalette);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
PrimarySurface::s_palette = lpDDPalette; PrimarySurface::s_palette = lpDDPalette;
@ -214,7 +219,7 @@ namespace DDraw
template <typename TSurface> template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect) HRESULT PrimarySurfaceImpl<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect)
{ {
HRESULT result = SurfaceImpl::Unlock(This, lpRect); HRESULT result = m_impl.Unlock(This, lpRect);
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
RealPrimarySurface::update(); RealPrimarySurface::update();

View File

@ -15,6 +15,8 @@ namespace DDraw
class PrimarySurfaceImpl : public SurfaceImpl<TSurface> class PrimarySurfaceImpl : public SurfaceImpl<TSurface>
{ {
public: public:
PrimarySurfaceImpl(SurfaceImpl& impl);
virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx) override; DWORD dwFlags, LPDDBLTFX lpDDBltFx) override;
virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY, virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY,
@ -31,5 +33,8 @@ namespace DDraw
virtual HRESULT SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper) override; virtual HRESULT SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper) override;
virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) override; virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) override;
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect) override; virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect) override;
private:
SurfaceImpl& m_impl;
}; };
} }

View File

@ -43,13 +43,21 @@ namespace DDraw
ULONG STDMETHODCALLTYPE Surface::AddRef() ULONG STDMETHODCALLTYPE Surface::AddRef()
{ {
return 0; return ++m_refCount;
} }
ULONG STDMETHODCALLTYPE Surface::Release() ULONG STDMETHODCALLTYPE Surface::Release()
{ {
delete this; DWORD refCount = --m_refCount;
return 0; if (0 == refCount)
{
delete this;
}
return refCount;
}
Surface::Surface() : m_refCount(0)
{
} }
Surface::~Surface() Surface::~Surface()
@ -124,28 +132,6 @@ namespace DDraw
m_impl7.reset(new SurfaceImpl<IDirectDrawSurface7>()); m_impl7.reset(new SurfaceImpl<IDirectDrawSurface7>());
} }
template <typename TSurface>
SurfaceImpl<TSurface>* Surface::getImpl(CompatRef<TSurface> dds)
{
Surface* surface = nullptr;
DWORD surfacePtrSize = sizeof(surface);
CompatVtableBase<IDirectDrawSurface7>::s_origVtable.GetPrivateData(
reinterpret_cast<IDirectDrawSurface7*>(&dds),
IID_CompatSurfacePrivateData, &surface, &surfacePtrSize);
if (!surface)
{
return nullptr;
}
return surface->getImpl<TSurface>();
}
template SurfaceImpl<IDirectDrawSurface>* Surface::getImpl(CompatRef<IDirectDrawSurface> dds);
template SurfaceImpl<IDirectDrawSurface2>* Surface::getImpl(CompatRef<IDirectDrawSurface2> dds);
template SurfaceImpl<IDirectDrawSurface3>* Surface::getImpl(CompatRef<IDirectDrawSurface3> dds);
template SurfaceImpl<IDirectDrawSurface4>* Surface::getImpl(CompatRef<IDirectDrawSurface4> dds);
template SurfaceImpl<IDirectDrawSurface7>* Surface::getImpl(CompatRef<IDirectDrawSurface7> dds);
template <> template <>
SurfaceImpl<IDirectDrawSurface>* Surface::getImpl<IDirectDrawSurface>() const { return m_impl.get(); } SurfaceImpl<IDirectDrawSurface>* Surface::getImpl<IDirectDrawSurface>() const { return m_impl.get(); }
template <> template <>
@ -156,4 +142,24 @@ namespace DDraw
SurfaceImpl<IDirectDrawSurface4>* Surface::getImpl<IDirectDrawSurface4>() const { return m_impl4.get(); } SurfaceImpl<IDirectDrawSurface4>* Surface::getImpl<IDirectDrawSurface4>() const { return m_impl4.get(); }
template <> template <>
SurfaceImpl<IDirectDrawSurface7>* Surface::getImpl<IDirectDrawSurface7>() const { return m_impl7.get(); } SurfaceImpl<IDirectDrawSurface7>* Surface::getImpl<IDirectDrawSurface7>() const { return m_impl7.get(); }
template <typename TSurface>
Surface* Surface::getSurface(TSurface& dds)
{
Surface* surface = nullptr;
DWORD surfacePtrSize = sizeof(surface);
// This can get called during surface release so a proper QueryInterface would be dangerous
CompatVtableBase<IDirectDrawSurface7>::s_origVtable.GetPrivateData(
reinterpret_cast<IDirectDrawSurface7*>(&dds),
IID_CompatSurfacePrivateData, &surface, &surfacePtrSize);
return surface;
}
template Surface* Surface::getSurface(IDirectDrawSurface& dds);
template Surface* Surface::getSurface(IDirectDrawSurface2& dds);
template Surface* Surface::getSurface(IDirectDrawSurface3& dds);
template Surface* Surface::getSurface(IDirectDrawSurface4& dds);
template Surface* Surface::getSurface(IDirectDrawSurface7& dds);
} }

View File

@ -26,12 +26,14 @@ namespace DDraw
static HRESULT create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface); static HRESULT create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface);
template <typename TSurface> template <typename TSurface>
static SurfaceImpl<TSurface>* getImpl(CompatRef<TSurface> dds); static Surface* getSurface(TSurface& dds);
template <typename TSurface> template <typename TSurface>
SurfaceImpl<TSurface>* getImpl() const; SurfaceImpl<TSurface>* getImpl() const;
protected: protected:
Surface();
static void attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface>& privateData); static void attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface>& privateData);
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl; std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
@ -44,5 +46,7 @@ namespace DDraw
static HRESULT WINAPI attachToLinkedSurfaces( static HRESULT WINAPI attachToLinkedSurfaces(
IDirectDrawSurface7* surface, DDSURFACEDESC2* desc, void* rootSurface); IDirectDrawSurface7* surface, DDSURFACEDESC2* desc, void* rootSurface);
virtual void createImpl(); virtual void createImpl();
DWORD m_refCount;
}; };
} }