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:
parent
47f02667bf
commit
d163787437
@ -11,13 +11,12 @@ namespace
|
||||
typename TSurface, typename... Params>
|
||||
HRESULT STDMETHODCALLTYPE callImpl(TSurface* This, Params... params)
|
||||
{
|
||||
DDraw::SurfaceImpl<TSurface>* surfaceImpl =
|
||||
This ? DDraw::Surface::getImpl<TSurface>(*This) : nullptr;
|
||||
if (!surfaceImpl)
|
||||
DDraw::Surface* surface = This ? DDraw::Surface::getSurface(*This) : nullptr;
|
||||
if (!surface)
|
||||
{
|
||||
return (CompatVtableBase<TSurface>::s_origVtable.*origMethod)(This, params...);
|
||||
}
|
||||
return (surfaceImpl->*compatMethod)(This, params...);
|
||||
return (surface->getImpl<TSurface>()->*compatMethod)(This, params...);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,11 @@ namespace
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
PrimarySurface::PrimarySurface(Surface* surface) : m_surface(surface)
|
||||
{
|
||||
surface->AddRef();
|
||||
}
|
||||
|
||||
PrimarySurface::~PrimarySurface()
|
||||
{
|
||||
Compat::LogEnter("PrimarySurface::~PrimarySurface");
|
||||
@ -53,7 +58,7 @@ namespace DDraw
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
CompatPtr<IDirectDrawSurface> surface1(Compat::queryInterface<IDirectDrawSurface>(surface));
|
||||
@ -77,11 +82,11 @@ namespace DDraw
|
||||
|
||||
void PrimarySurface::createImpl()
|
||||
{
|
||||
m_impl.reset(new PrimarySurfaceImpl<IDirectDrawSurface>());
|
||||
m_impl2.reset(new PrimarySurfaceImpl<IDirectDrawSurface2>());
|
||||
m_impl3.reset(new PrimarySurfaceImpl<IDirectDrawSurface3>());
|
||||
m_impl4.reset(new PrimarySurfaceImpl<IDirectDrawSurface4>());
|
||||
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>());
|
||||
m_impl.reset(new PrimarySurfaceImpl<IDirectDrawSurface>(*m_surface->getImpl<IDirectDrawSurface>()));
|
||||
m_impl2.reset(new PrimarySurfaceImpl<IDirectDrawSurface2>(*m_surface->getImpl<IDirectDrawSurface2>()));
|
||||
m_impl3.reset(new PrimarySurfaceImpl<IDirectDrawSurface3>(*m_surface->getImpl<IDirectDrawSurface3>()));
|
||||
m_impl4.reset(new PrimarySurfaceImpl<IDirectDrawSurface4>(*m_surface->getImpl<IDirectDrawSurface4>()));
|
||||
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>(*m_surface->getImpl<IDirectDrawSurface7>()));
|
||||
}
|
||||
|
||||
const DDSURFACEDESC2& PrimarySurface::getDesc()
|
||||
|
@ -20,6 +20,10 @@ namespace DDraw
|
||||
static PALETTEENTRY s_paletteEntries[256];
|
||||
|
||||
private:
|
||||
PrimarySurface(Surface* surface);
|
||||
|
||||
virtual void createImpl() override;
|
||||
|
||||
std::unique_ptr<Surface> m_surface;
|
||||
};
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ namespace
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
template <typename TSurface>
|
||||
PrimarySurfaceImpl<TSurface>::PrimarySurfaceImpl(SurfaceImpl& impl) : m_impl(impl)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT PrimarySurfaceImpl<TSurface>::Blt(
|
||||
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
||||
@ -25,7 +30,7 @@ namespace DDraw
|
||||
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))
|
||||
{
|
||||
RealPrimarySurface::invalidate(lpDestRect);
|
||||
@ -43,7 +48,7 @@ namespace DDraw
|
||||
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))
|
||||
{
|
||||
const LONG x = dwX;
|
||||
@ -76,7 +81,7 @@ namespace DDraw
|
||||
return DDERR_SURFACELOST;
|
||||
}
|
||||
|
||||
HRESULT result = SurfaceImpl::Flip(This, lpDDSurfaceTargetOverride, dwFlags);
|
||||
HRESULT result = m_impl.Flip(This, lpDDSurfaceTargetOverride, dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = RealPrimarySurface::flip(dwFlags);
|
||||
@ -87,7 +92,7 @@ namespace DDraw
|
||||
template <typename TSurface>
|
||||
HRESULT PrimarySurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
|
||||
{
|
||||
HRESULT result = SurfaceImpl::GetCaps(This, lpDDSCaps);
|
||||
HRESULT result = m_impl.GetCaps(This, lpDDSCaps);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
restorePrimaryCaps(lpDDSCaps->dwCaps);
|
||||
@ -98,7 +103,7 @@ namespace DDraw
|
||||
template <typename TSurface>
|
||||
HRESULT PrimarySurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
|
||||
{
|
||||
HRESULT result = SurfaceImpl::GetSurfaceDesc(This, lpDDSurfaceDesc);
|
||||
HRESULT result = m_impl.GetSurfaceDesc(This, lpDDSurfaceDesc);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
||||
@ -109,7 +114,7 @@ namespace DDraw
|
||||
template <typename TSurface>
|
||||
HRESULT PrimarySurfaceImpl<TSurface>::IsLost(TSurface* This)
|
||||
{
|
||||
HRESULT result = SurfaceImpl::IsLost(This);
|
||||
HRESULT result = m_impl.IsLost(This);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
|
||||
@ -127,7 +132,7 @@ namespace DDraw
|
||||
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))
|
||||
{
|
||||
RealPrimarySurface::invalidate(lpDestRect);
|
||||
@ -144,13 +149,13 @@ namespace DDraw
|
||||
auto realPrimary(RealPrimarySurface::getSurface());
|
||||
return realPrimary->QueryInterface(realPrimary, riid, obp);
|
||||
}
|
||||
return SurfaceImpl::QueryInterface(This, riid, obp);
|
||||
return m_impl.QueryInterface(This, riid, obp);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT PrimarySurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
|
||||
{
|
||||
HRESULT result = SurfaceImpl::ReleaseDC(This, hDC);
|
||||
HRESULT result = m_impl.ReleaseDC(This, hDC);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
RealPrimarySurface::invalidate(nullptr);
|
||||
@ -168,7 +173,7 @@ namespace DDraw
|
||||
result = RealPrimarySurface::restore();
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
result = SurfaceImpl::Restore(This);
|
||||
result = m_impl.Restore(This);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
fixSurfacePtrs(*This);
|
||||
@ -182,7 +187,7 @@ namespace DDraw
|
||||
template <typename TSurface>
|
||||
HRESULT PrimarySurfaceImpl<TSurface>::SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper)
|
||||
{
|
||||
HRESULT result = SurfaceImpl::SetClipper(This, lpDDClipper);
|
||||
HRESULT result = m_impl.SetClipper(This, lpDDClipper);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
RealPrimarySurface::setClipper(lpDDClipper);
|
||||
@ -202,7 +207,7 @@ namespace DDraw
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
HRESULT result = SurfaceImpl::SetPalette(This, lpDDPalette);
|
||||
HRESULT result = m_impl.SetPalette(This, lpDDPalette);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
PrimarySurface::s_palette = lpDDPalette;
|
||||
@ -214,7 +219,7 @@ namespace DDraw
|
||||
template <typename TSurface>
|
||||
HRESULT PrimarySurfaceImpl<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect)
|
||||
{
|
||||
HRESULT result = SurfaceImpl::Unlock(This, lpRect);
|
||||
HRESULT result = m_impl.Unlock(This, lpRect);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
RealPrimarySurface::update();
|
||||
|
@ -15,6 +15,8 @@ namespace DDraw
|
||||
class PrimarySurfaceImpl : public SurfaceImpl<TSurface>
|
||||
{
|
||||
public:
|
||||
PrimarySurfaceImpl(SurfaceImpl& impl);
|
||||
|
||||
virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
||||
DWORD dwFlags, LPDDBLTFX lpDDBltFx) override;
|
||||
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 SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) override;
|
||||
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect) override;
|
||||
|
||||
private:
|
||||
SurfaceImpl& m_impl;
|
||||
};
|
||||
}
|
||||
|
@ -43,13 +43,21 @@ namespace DDraw
|
||||
|
||||
ULONG STDMETHODCALLTYPE Surface::AddRef()
|
||||
{
|
||||
return 0;
|
||||
return ++m_refCount;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE Surface::Release()
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
DWORD refCount = --m_refCount;
|
||||
if (0 == refCount)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
Surface::Surface() : m_refCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
Surface::~Surface()
|
||||
@ -124,28 +132,6 @@ namespace DDraw
|
||||
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 <>
|
||||
SurfaceImpl<IDirectDrawSurface>* Surface::getImpl<IDirectDrawSurface>() const { return m_impl.get(); }
|
||||
template <>
|
||||
@ -156,4 +142,24 @@ namespace DDraw
|
||||
SurfaceImpl<IDirectDrawSurface4>* Surface::getImpl<IDirectDrawSurface4>() const { return m_impl4.get(); }
|
||||
template <>
|
||||
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);
|
||||
}
|
||||
|
@ -26,12 +26,14 @@ namespace DDraw
|
||||
static HRESULT create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface);
|
||||
|
||||
template <typename TSurface>
|
||||
static SurfaceImpl<TSurface>* getImpl(CompatRef<TSurface> dds);
|
||||
static Surface* getSurface(TSurface& dds);
|
||||
|
||||
template <typename TSurface>
|
||||
SurfaceImpl<TSurface>* getImpl() const;
|
||||
|
||||
protected:
|
||||
Surface();
|
||||
|
||||
static void attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface>& privateData);
|
||||
|
||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
|
||||
@ -44,5 +46,7 @@ namespace DDraw
|
||||
static HRESULT WINAPI attachToLinkedSurfaces(
|
||||
IDirectDrawSurface7* surface, DDSURFACEDESC2* desc, void* rootSurface);
|
||||
virtual void createImpl();
|
||||
|
||||
DWORD m_refCount;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user