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

Simplified Surface implementation

This commit is contained in:
narzoul 2019-07-19 19:46:01 +02:00
parent b0c5736bbf
commit 063cefb46e
12 changed files with 131 additions and 151 deletions

View File

@ -100,7 +100,7 @@ namespace DDraw
}
else
{
return Surface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
return Surface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface, std::make_unique<Surface>());
}
}

View File

@ -6,6 +6,26 @@
namespace
{
struct AddAttachedSurfacesContext
{
IDirectDrawSurface7* rootSurface;
std::vector<CompatPtr<IDirectDrawSurface7>> surfaces;
};
HRESULT WINAPI addAttachedSurfaces(
LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 /*lpDDSurfaceDesc*/, LPVOID lpContext)
{
CompatPtr<IDirectDrawSurface7> surface(lpDDSurface);
auto& context(*static_cast<AddAttachedSurfacesContext*>(lpContext));
if (surface == context.rootSurface)
{
return DD_OK;
}
context.surfaces.push_back(surface);
surface->EnumAttachedSurfaces(surface, &context, &addAttachedSurfaces);
return DD_OK;
}
template <typename CompatMethod, CompatMethod compatMethod,
typename OrigMethod, OrigMethod origMethod,
typename TSurface, typename... Params>
@ -26,6 +46,13 @@ namespace
namespace DDraw
{
std::vector<CompatPtr<IDirectDrawSurface7>> getAllAttachedSurfaces(CompatRef<IDirectDrawSurface7> surface)
{
AddAttachedSurfacesContext context = { &surface };
surface->EnumAttachedSurfaces(&surface, &context, &addAttachedSurfaces);
return context.surfaces;
}
template <typename TSurface>
void DirectDrawSurface<TSurface>::setCompatVtable(Vtable<TSurface>& vtable)
{

View File

@ -1,5 +1,7 @@
#pragma once
#include <vector>
#include "Common/CompatPtr.h"
#include "Common/CompatRef.h"
#include "Common/CompatVtable.h"
@ -8,6 +10,20 @@
namespace DDraw
{
std::vector<CompatPtr<IDirectDrawSurface7>> getAllAttachedSurfaces(CompatRef<IDirectDrawSurface7> surface);
template <typename TSurface>
HANDLE getRuntimeResourceHandle(TSurface& surface)
{
return reinterpret_cast<HANDLE**>(&surface)[1][2];
}
template <typename TSurface>
HANDLE getDriverResourceHandle(TSurface& surface)
{
return *reinterpret_cast<HANDLE*>(getRuntimeResourceHandle(surface));
}
template <typename TSurface>
class DirectDrawSurface : public CompatVtable<Vtable<TSurface>>
{

View File

@ -548,19 +548,6 @@ namespace DDraw
{
DDraw::ScopedThreadLock lock;
auto primary(PrimarySurface::getPrimary());
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
if (isFlipEmulated && !surfaceTargetOverride)
{
surfaceTargetOverride = PrimarySurface::getBackBuffer();
}
HRESULT result = primary->Flip(primary, surfaceTargetOverride, DDFLIP_WAIT);
if (FAILED(result))
{
return result;
}
DWORD flipInterval = getFlipInterval(flags);
const auto msSinceLastUpdate = Time::qpcToMs(Time::queryPerformanceCounter() - g_qpcLastUpdate);
const bool isFlipDelayed = msSinceLastUpdate >= 0 && msSinceLastUpdate <= Config::delayedFlipModeTimeout;
@ -572,14 +559,16 @@ namespace DDraw
g_isUpdatePending = true;
}
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
if (isFlipEmulated)
{
surfaceTargetOverride->Blt(surfaceTargetOverride, nullptr, primary, nullptr, DDBLT_WAIT, nullptr);
surfaceTargetOverride->Blt(
surfaceTargetOverride, nullptr, PrimarySurface::getPrimary(), nullptr, DDBLT_WAIT, nullptr);
}
if (!isFlipDelayed)
{
updateNow(primary, flipInterval);
updateNow(PrimarySurface::getPrimary(), flipInterval);
}
if (0 != flipInterval)

View File

@ -4,6 +4,7 @@
#include "D3dDdi/Device.h"
#include "D3dDdi/KernelModeThunks.h"
#include "DDraw/DirectDraw.h"
#include "DDraw/DirectDrawSurface.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
@ -13,21 +14,10 @@ namespace
CompatWeakPtr<IDirectDrawSurface7> g_primarySurface;
HANDLE g_gdiResourceHandle = nullptr;
DWORD g_origCaps = 0;
template <typename TSurface>
HANDLE getResourceHandle(TSurface& surface)
{
return reinterpret_cast<HANDLE**>(&surface)[1][2];
}
}
namespace DDraw
{
PrimarySurface::PrimarySurface(Surface* surface) : m_surface(surface)
{
surface->AddRef();
}
PrimarySurface::~PrimarySurface()
{
LOG_FUNC("PrimarySurface::~PrimarySurface");
@ -56,11 +46,11 @@ namespace DDraw
desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
desc.dwWidth = dm.dwWidth;
desc.dwHeight = dm.dwHeight;
desc.ddsCaps.dwCaps &= ~DDSCAPS_PRIMARYSURFACE;
desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
desc.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_NONLOCALVIDMEM);
desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
desc.ddpfPixelFormat = dm.ddpfPixelFormat;
result = Surface::create(dd, desc, surface);
result = Surface::create(dd, desc, surface, std::make_unique<PrimarySurface>());
if (FAILED(result))
{
Compat::Log() << "ERROR: Failed to create the compat primary surface: " << Compat::hex(result);
@ -68,11 +58,7 @@ namespace DDraw
return result;
}
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(surface));
std::unique_ptr<Surface> privateData(new PrimarySurface(Surface::getSurface(*surface)));
attach(*surface7, privateData);
g_primarySurface = surface7;
g_primarySurface = CompatPtr<IDirectDrawSurface7>::from(surface);
g_origCaps = origCaps;
onRestore();
@ -91,11 +77,11 @@ namespace DDraw
void PrimarySurface::createImpl()
{
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>()));
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>());
}
HRESULT PrimarySurface::flipToGdiSurface()
@ -174,7 +160,7 @@ namespace DDraw
template <typename TSurface>
static bool PrimarySurface::isGdiSurface(TSurface* surface)
{
return surface && getResourceHandle(*surface) == g_gdiResourceHandle;
return surface && getRuntimeResourceHandle(*surface) == g_gdiResourceHandle;
}
template bool PrimarySurface::isGdiSurface(IDirectDrawSurface*);
@ -185,7 +171,7 @@ namespace DDraw
void PrimarySurface::onRestore()
{
g_gdiResourceHandle = getResourceHandle(*g_primarySurface);
g_gdiResourceHandle = getRuntimeResourceHandle(*g_primarySurface);
D3dDdi::Device::setGdiResourceHandle(*reinterpret_cast<HANDLE*>(g_gdiResourceHandle));
}

View File

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

View File

@ -73,11 +73,6 @@ 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,
@ -88,7 +83,7 @@ namespace DDraw
return DDERR_SURFACELOST;
}
HRESULT result = m_impl.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
HRESULT result = SurfaceImpl::Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
if (SUCCEEDED(result))
{
bltToGdi(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
@ -106,7 +101,7 @@ namespace DDraw
return DDERR_SURFACELOST;
}
HRESULT result = m_impl.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
HRESULT result = SurfaceImpl::BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
if (SUCCEEDED(result))
{
RealPrimarySurface::update();
@ -124,13 +119,28 @@ namespace DDraw
return DDERR_WASSTILLDRAWING;
}
return RealPrimarySurface::flip(CompatPtr<IDirectDrawSurface7>::from(lpDDSurfaceTargetOverride), dwFlags);
auto surfaceTargetOverride(CompatPtr<TSurface>::from(lpDDSurfaceTargetOverride));
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
if (isFlipEmulated && !surfaceTargetOverride)
{
TDdsCaps caps = {};
caps.dwCaps = DDSCAPS_BACKBUFFER;
s_origVtable.GetAttachedSurface(This, &caps, &surfaceTargetOverride.getRef());
}
HRESULT result = SurfaceImpl::Flip(This, surfaceTargetOverride, DDFLIP_WAIT);
if (FAILED(result))
{
return result;
}
return RealPrimarySurface::flip(surfaceTargetOverride, dwFlags);
}
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
{
HRESULT result = m_impl.GetCaps(This, lpDDSCaps);
HRESULT result = SurfaceImpl::GetCaps(This, lpDDSCaps);
if (SUCCEEDED(result))
{
restorePrimaryCaps(lpDDSCaps->dwCaps);
@ -141,7 +151,7 @@ namespace DDraw
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
{
HRESULT result = m_impl.GetSurfaceDesc(This, lpDDSurfaceDesc);
HRESULT result = SurfaceImpl::GetSurfaceDesc(This, lpDDSurfaceDesc);
if (SUCCEEDED(result))
{
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
@ -152,7 +162,7 @@ namespace DDraw
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::IsLost(TSurface* This)
{
HRESULT result = m_impl.IsLost(This);
HRESULT result = SurfaceImpl::IsLost(This);
if (SUCCEEDED(result))
{
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
@ -170,7 +180,7 @@ namespace DDraw
return DDERR_SURFACELOST;
}
HRESULT result = m_impl.Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
HRESULT result = SurfaceImpl::Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
if (SUCCEEDED(result))
{
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
@ -181,7 +191,7 @@ namespace DDraw
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
{
HRESULT result = m_impl.ReleaseDC(This, hDC);
HRESULT result = SurfaceImpl::ReleaseDC(This, hDC);
if (SUCCEEDED(result))
{
RealPrimarySurface::update();
@ -198,7 +208,7 @@ namespace DDraw
result = RealPrimarySurface::restore();
if (SUCCEEDED(result))
{
result = m_impl.Restore(This);
result = SurfaceImpl::Restore(This);
if (SUCCEEDED(result))
{
PrimarySurface::onRestore();
@ -220,7 +230,7 @@ namespace DDraw
return DD_OK;
}
HRESULT result = m_impl.SetPalette(This, lpDDPalette);
HRESULT result = SurfaceImpl::SetPalette(This, lpDDPalette);
if (SUCCEEDED(result))
{
PrimarySurface::s_palette = lpDDPalette;
@ -232,7 +242,7 @@ namespace DDraw
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect)
{
HRESULT result = m_impl.Unlock(This, lpRect);
HRESULT result = SurfaceImpl::Unlock(This, lpRect);
if (SUCCEEDED(result))
{
RealPrimarySurface::update();

View File

@ -13,8 +13,6 @@ 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,
@ -29,8 +27,5 @@ namespace DDraw
virtual HRESULT Restore(TSurface* This) override;
virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) override;
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect) override;
private:
SurfaceImpl& m_impl;
};
}

View File

@ -26,27 +26,6 @@ namespace
}
}
}
IID getDdIidFromVtablePtr(const void* vtablePtr)
{
if (CompatVtable<IDirectDrawVtbl>::s_origVtablePtr == vtablePtr)
{
return IID_IDirectDraw;
}
if (CompatVtable<IDirectDraw2Vtbl>::s_origVtablePtr == vtablePtr)
{
return IID_IDirectDraw2;
}
if (CompatVtable<IDirectDraw4Vtbl>::s_origVtablePtr == vtablePtr)
{
return IID_IDirectDraw4;
}
if (CompatVtable<IDirectDraw7Vtbl>::s_origVtablePtr == vtablePtr)
{
return IID_IDirectDraw7;
}
return IID_IUnknown;
}
}
namespace DDraw
@ -73,7 +52,6 @@ namespace DDraw
Surface::Surface()
: m_ddObject(nullptr)
, m_ddId()
, m_refCount(0)
{
}
@ -82,7 +60,7 @@ namespace DDraw
{
}
void Surface::attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface>& privateData)
void Surface::attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface> privateData)
{
if (SUCCEEDED(dds->SetPrivateData(&dds, IID_CompatSurfacePrivateData,
privateData.get(), sizeof(privateData.get()), DDSPD_IUNKNOWNPOINTER)))
@ -97,45 +75,32 @@ namespace DDraw
privateData->m_impl4->m_data = privateData.get();
privateData->m_impl7->m_data = privateData.get();
privateData->m_ddId = getDdIidFromVtablePtr(reinterpret_cast<void**>(dd.get())[0]);
privateData->m_ddObject = DDraw::getDdObject(*CompatPtr<IDirectDraw>(dd));
privateData.release();
}
}
HRESULT WINAPI Surface::attachToLinkedSurfaces(
IDirectDrawSurface7* surface, DDSURFACEDESC2* /*desc*/, void* rootSurface)
{
CompatPtr<IDirectDrawSurface7> surfaceReleaser(surface);
if (surface == rootSurface)
{
return DDENUMRET_CANCEL;
}
std::unique_ptr<DDraw::Surface> privateData(new Surface());
attach(*surface, privateData);
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtable.EnumAttachedSurfaces(
surface, rootSurface, &attachToLinkedSurfaces);
return DDENUMRET_OK;
}
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
HRESULT Surface::create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface)
HRESULT Surface::create(
CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr<Surface> privateData)
{
fixSurfaceDesc(desc.dwFlags, desc.ddsCaps.dwCaps);
HRESULT result = dd->CreateSurface(&dd, &desc, &surface, nullptr);
if (SUCCEEDED(result))
if (FAILED(result))
{
CompatPtr<IDirectDrawSurface7> surface7(
Compat::queryInterface<IDirectDrawSurface7>(surface));
std::unique_ptr<Surface> privateData(new Surface());
attach(*surface7, privateData);
if (desc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
return result;
}
auto surface7(CompatPtr<IDirectDrawSurface7>::from(surface));
attach(*surface7, std::move(privateData));
if (desc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
{
auto attachedSurfaces(getAllAttachedSurfaces(*surface7));
for (std::size_t i = 0; i < attachedSurfaces.size(); ++i)
{
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtable.EnumAttachedSurfaces(
surface7, surface7, &attachToLinkedSurfaces);
attach(*attachedSurfaces[i], std::make_unique<Surface>());
}
}
@ -143,13 +108,13 @@ namespace DDraw
}
template HRESULT Surface::create(
CompatRef<IDirectDraw> dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface);
CompatRef<IDirectDraw> dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface, std::unique_ptr<Surface> privateData);
template HRESULT Surface::create(
CompatRef<IDirectDraw2> dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface);
CompatRef<IDirectDraw2> dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface, std::unique_ptr<Surface> privateData);
template HRESULT Surface::create(
CompatRef<IDirectDraw4> dd, DDSURFACEDESC2 desc, IDirectDrawSurface4*& surface);
CompatRef<IDirectDraw4> dd, DDSURFACEDESC2 desc, IDirectDrawSurface4*& surface, std::unique_ptr<Surface> privateData);
template HRESULT Surface::create(
CompatRef<IDirectDraw7> dd, DDSURFACEDESC2 desc, IDirectDrawSurface7*& surface);
CompatRef<IDirectDraw7> dd, DDSURFACEDESC2 desc, IDirectDrawSurface7*& surface, std::unique_ptr<Surface> privateData);
void Surface::createImpl()
{

View File

@ -1,6 +1,7 @@
#pragma once
#include <memory>
#include <vector>
#include <ddraw.h>
@ -19,10 +20,12 @@ namespace DDraw
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
Surface();
virtual ~Surface();
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
static HRESULT create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface);
static HRESULT create(
CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr<Surface> privateData);
template <typename TSurface>
static Surface* getSurface(TSurface& dds);
@ -31,9 +34,9 @@ namespace DDraw
SurfaceImpl<TSurface>* getImpl() const;
protected:
Surface();
static void attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface> privateData);
static void attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface>& privateData);
virtual void createImpl();
void* m_ddObject;
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
@ -43,14 +46,11 @@ namespace DDraw
std::unique_ptr<SurfaceImpl<IDirectDrawSurface7>> m_impl7;
private:
template <typename TDirectDrawSurface>
friend class SurfaceImpl;
template <typename TDirectDrawSurface>
friend class SurfaceImpl2;
static HRESULT WINAPI attachToLinkedSurfaces(
IDirectDrawSurface7* surface, DDSURFACEDESC2* desc, void* rootSurface);
virtual void createImpl();
IID m_ddId;
DWORD m_refCount;
};
}

View File

@ -1,5 +1,6 @@
#include <set>
#include "DDraw/DirectDrawSurface.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Surfaces/Surface.h"
@ -17,20 +18,6 @@ namespace
DWORD unknown1;
DWORD unknown2;
};
template <typename TSurface>
bool waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag)
{
if (!This)
{
return true;
}
const bool wait = (flags & waitFlag) || !(flags & doNotWaitFlag) &&
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtablePtr == static_cast<void*>(This->lpVtbl);
return DDraw::RealPrimarySurface::waitForFlip(DDraw::Surface::getSurface(*This), wait);
}
}
namespace DDraw
@ -82,7 +69,7 @@ namespace DDraw
if (SUCCEEDED(result) && (dwFlags & DDGBS_CANBLT))
{
const bool wait = false;
if (!RealPrimarySurface::waitForFlip(Surface::getSurface(*This), wait))
if (!RealPrimarySurface::waitForFlip(m_data, wait))
{
return DDERR_WASSTILLDRAWING;
}
@ -95,7 +82,7 @@ namespace DDraw
{
return s_origVtable.GetCaps(This, lpDDSCaps);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
{
@ -108,7 +95,7 @@ namespace DDraw
if (SUCCEEDED(result))
{
RealPrimarySurface::waitForFlip(Surface::getSurface(*This));
RealPrimarySurface::waitForFlip(m_data);
}
return result;
@ -118,12 +105,10 @@ namespace DDraw
HRESULT SurfaceImpl2<TSurface>::GetDDInterface(TSurface* /*This*/, LPVOID* lplpDD)
{
DirectDrawInterface dd = {};
dd.vtable = IID_IDirectDraw7 == m_data->m_ddId
? static_cast<const void*>(CompatVtable<IDirectDrawVtbl>::s_origVtablePtr)
: static_cast<const void*>(CompatVtable<IDirectDraw7Vtbl>::s_origVtablePtr);
dd.vtable = static_cast<const void*>(CompatVtable<IDirectDraw7Vtbl>::s_origVtablePtr);
dd.ddObject = m_data->m_ddObject;
return CompatVtable<IDirectDrawVtbl>::s_origVtable.QueryInterface(
reinterpret_cast<IDirectDraw*>(&dd), m_data->m_ddId, lplpDD);
reinterpret_cast<IDirectDraw*>(&dd), IID_IDirectDraw, lplpDD);
}
template <typename TSurface>
@ -133,7 +118,7 @@ namespace DDraw
if (SUCCEEDED(result))
{
const bool wait = false;
if (!RealPrimarySurface::waitForFlip(Surface::getSurface(*This), wait))
if (!RealPrimarySurface::waitForFlip(m_data, wait))
{
return DDERR_WASSTILLDRAWING;
}
@ -207,6 +192,14 @@ namespace DDraw
return s_origVtable.Unlock(This, lpRect);
}
template <typename TSurface>
bool SurfaceImpl<TSurface>::waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag)
{
const bool wait = (flags & waitFlag) || !(flags & doNotWaitFlag) &&
CompatVtable<IDirectDrawSurface7Vtbl>::s_origVtablePtr == static_cast<void*>(This->lpVtbl);
return DDraw::RealPrimarySurface::waitForFlip(m_data, wait);
}
template <typename TSurface>
const Vtable<TSurface>& SurfaceImpl<TSurface>::s_origVtable =
CompatVtable<Vtable<TSurface>>::s_origVtable;

View File

@ -55,5 +55,8 @@ namespace DDraw
protected:
static const Vtable<TSurface>& s_origVtable;
private:
bool waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag);
};
}