mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Simplified Surface implementation
This commit is contained in:
parent
b0c5736bbf
commit
063cefb46e
@ -100,7 +100,7 @@ namespace DDraw
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Surface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
|
return Surface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface, std::make_unique<Surface>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,26 @@
|
|||||||
|
|
||||||
namespace
|
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,
|
template <typename CompatMethod, CompatMethod compatMethod,
|
||||||
typename OrigMethod, OrigMethod origMethod,
|
typename OrigMethod, OrigMethod origMethod,
|
||||||
typename TSurface, typename... Params>
|
typename TSurface, typename... Params>
|
||||||
@ -26,6 +46,13 @@ namespace
|
|||||||
|
|
||||||
namespace DDraw
|
namespace DDraw
|
||||||
{
|
{
|
||||||
|
std::vector<CompatPtr<IDirectDrawSurface7>> getAllAttachedSurfaces(CompatRef<IDirectDrawSurface7> surface)
|
||||||
|
{
|
||||||
|
AddAttachedSurfacesContext context = { &surface };
|
||||||
|
surface->EnumAttachedSurfaces(&surface, &context, &addAttachedSurfaces);
|
||||||
|
return context.surfaces;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
void DirectDrawSurface<TSurface>::setCompatVtable(Vtable<TSurface>& vtable)
|
void DirectDrawSurface<TSurface>::setCompatVtable(Vtable<TSurface>& vtable)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CompatPtr.h"
|
#include "Common/CompatPtr.h"
|
||||||
#include "Common/CompatRef.h"
|
#include "Common/CompatRef.h"
|
||||||
#include "Common/CompatVtable.h"
|
#include "Common/CompatVtable.h"
|
||||||
@ -8,6 +10,20 @@
|
|||||||
|
|
||||||
namespace DDraw
|
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>
|
template <typename TSurface>
|
||||||
class DirectDrawSurface : public CompatVtable<Vtable<TSurface>>
|
class DirectDrawSurface : public CompatVtable<Vtable<TSurface>>
|
||||||
{
|
{
|
||||||
|
@ -548,19 +548,6 @@ namespace DDraw
|
|||||||
{
|
{
|
||||||
DDraw::ScopedThreadLock lock;
|
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);
|
DWORD flipInterval = getFlipInterval(flags);
|
||||||
const auto msSinceLastUpdate = Time::qpcToMs(Time::queryPerformanceCounter() - g_qpcLastUpdate);
|
const auto msSinceLastUpdate = Time::qpcToMs(Time::queryPerformanceCounter() - g_qpcLastUpdate);
|
||||||
const bool isFlipDelayed = msSinceLastUpdate >= 0 && msSinceLastUpdate <= Config::delayedFlipModeTimeout;
|
const bool isFlipDelayed = msSinceLastUpdate >= 0 && msSinceLastUpdate <= Config::delayedFlipModeTimeout;
|
||||||
@ -572,14 +559,16 @@ namespace DDraw
|
|||||||
g_isUpdatePending = true;
|
g_isUpdatePending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
|
||||||
if (isFlipEmulated)
|
if (isFlipEmulated)
|
||||||
{
|
{
|
||||||
surfaceTargetOverride->Blt(surfaceTargetOverride, nullptr, primary, nullptr, DDBLT_WAIT, nullptr);
|
surfaceTargetOverride->Blt(
|
||||||
|
surfaceTargetOverride, nullptr, PrimarySurface::getPrimary(), nullptr, DDBLT_WAIT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isFlipDelayed)
|
if (!isFlipDelayed)
|
||||||
{
|
{
|
||||||
updateNow(primary, flipInterval);
|
updateNow(PrimarySurface::getPrimary(), flipInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != flipInterval)
|
if (0 != flipInterval)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "D3dDdi/Device.h"
|
#include "D3dDdi/Device.h"
|
||||||
#include "D3dDdi/KernelModeThunks.h"
|
#include "D3dDdi/KernelModeThunks.h"
|
||||||
#include "DDraw/DirectDraw.h"
|
#include "DDraw/DirectDraw.h"
|
||||||
|
#include "DDraw/DirectDrawSurface.h"
|
||||||
#include "DDraw/RealPrimarySurface.h"
|
#include "DDraw/RealPrimarySurface.h"
|
||||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||||
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
|
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
|
||||||
@ -13,21 +14,10 @@ namespace
|
|||||||
CompatWeakPtr<IDirectDrawSurface7> g_primarySurface;
|
CompatWeakPtr<IDirectDrawSurface7> g_primarySurface;
|
||||||
HANDLE g_gdiResourceHandle = nullptr;
|
HANDLE g_gdiResourceHandle = nullptr;
|
||||||
DWORD g_origCaps = 0;
|
DWORD g_origCaps = 0;
|
||||||
|
|
||||||
template <typename TSurface>
|
|
||||||
HANDLE getResourceHandle(TSurface& surface)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<HANDLE**>(&surface)[1][2];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace DDraw
|
namespace DDraw
|
||||||
{
|
{
|
||||||
PrimarySurface::PrimarySurface(Surface* surface) : m_surface(surface)
|
|
||||||
{
|
|
||||||
surface->AddRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
PrimarySurface::~PrimarySurface()
|
PrimarySurface::~PrimarySurface()
|
||||||
{
|
{
|
||||||
LOG_FUNC("PrimarySurface::~PrimarySurface");
|
LOG_FUNC("PrimarySurface::~PrimarySurface");
|
||||||
@ -56,11 +46,11 @@ namespace DDraw
|
|||||||
desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
|
desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
|
||||||
desc.dwWidth = dm.dwWidth;
|
desc.dwWidth = dm.dwWidth;
|
||||||
desc.dwHeight = dm.dwHeight;
|
desc.dwHeight = dm.dwHeight;
|
||||||
desc.ddsCaps.dwCaps &= ~DDSCAPS_PRIMARYSURFACE;
|
desc.ddsCaps.dwCaps &= ~(DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_NONLOCALVIDMEM);
|
||||||
desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
|
desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
|
||||||
desc.ddpfPixelFormat = dm.ddpfPixelFormat;
|
desc.ddpfPixelFormat = dm.ddpfPixelFormat;
|
||||||
|
|
||||||
result = Surface::create(dd, desc, surface);
|
result = Surface::create(dd, desc, surface, std::make_unique<PrimarySurface>());
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
Compat::Log() << "ERROR: Failed to create the compat primary surface: " << Compat::hex(result);
|
Compat::Log() << "ERROR: Failed to create the compat primary surface: " << Compat::hex(result);
|
||||||
@ -68,11 +58,7 @@ namespace DDraw
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(surface));
|
g_primarySurface = CompatPtr<IDirectDrawSurface7>::from(surface);
|
||||||
std::unique_ptr<Surface> privateData(new PrimarySurface(Surface::getSurface(*surface)));
|
|
||||||
attach(*surface7, privateData);
|
|
||||||
|
|
||||||
g_primarySurface = surface7;
|
|
||||||
g_origCaps = origCaps;
|
g_origCaps = origCaps;
|
||||||
|
|
||||||
onRestore();
|
onRestore();
|
||||||
@ -91,11 +77,11 @@ namespace DDraw
|
|||||||
|
|
||||||
void PrimarySurface::createImpl()
|
void PrimarySurface::createImpl()
|
||||||
{
|
{
|
||||||
m_impl.reset(new PrimarySurfaceImpl<IDirectDrawSurface>(*m_surface->getImpl<IDirectDrawSurface>()));
|
m_impl.reset(new PrimarySurfaceImpl<IDirectDrawSurface>());
|
||||||
m_impl2.reset(new PrimarySurfaceImpl<IDirectDrawSurface2>(*m_surface->getImpl<IDirectDrawSurface2>()));
|
m_impl2.reset(new PrimarySurfaceImpl<IDirectDrawSurface2>());
|
||||||
m_impl3.reset(new PrimarySurfaceImpl<IDirectDrawSurface3>(*m_surface->getImpl<IDirectDrawSurface3>()));
|
m_impl3.reset(new PrimarySurfaceImpl<IDirectDrawSurface3>());
|
||||||
m_impl4.reset(new PrimarySurfaceImpl<IDirectDrawSurface4>(*m_surface->getImpl<IDirectDrawSurface4>()));
|
m_impl4.reset(new PrimarySurfaceImpl<IDirectDrawSurface4>());
|
||||||
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>(*m_surface->getImpl<IDirectDrawSurface7>()));
|
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>());
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT PrimarySurface::flipToGdiSurface()
|
HRESULT PrimarySurface::flipToGdiSurface()
|
||||||
@ -174,7 +160,7 @@ namespace DDraw
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
static bool PrimarySurface::isGdiSurface(TSurface* surface)
|
static bool PrimarySurface::isGdiSurface(TSurface* surface)
|
||||||
{
|
{
|
||||||
return surface && getResourceHandle(*surface) == g_gdiResourceHandle;
|
return surface && getRuntimeResourceHandle(*surface) == g_gdiResourceHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
template bool PrimarySurface::isGdiSurface(IDirectDrawSurface*);
|
template bool PrimarySurface::isGdiSurface(IDirectDrawSurface*);
|
||||||
@ -185,7 +171,7 @@ namespace DDraw
|
|||||||
|
|
||||||
void PrimarySurface::onRestore()
|
void PrimarySurface::onRestore()
|
||||||
{
|
{
|
||||||
g_gdiResourceHandle = getResourceHandle(*g_primarySurface);
|
g_gdiResourceHandle = getRuntimeResourceHandle(*g_primarySurface);
|
||||||
D3dDdi::Device::setGdiResourceHandle(*reinterpret_cast<HANDLE*>(g_gdiResourceHandle));
|
D3dDdi::Device::setGdiResourceHandle(*reinterpret_cast<HANDLE*>(g_gdiResourceHandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,10 +32,6 @@ 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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -73,11 +73,6 @@ 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,
|
||||||
@ -88,7 +83,7 @@ namespace DDraw
|
|||||||
return DDERR_SURFACELOST;
|
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))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
bltToGdi(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
bltToGdi(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||||
@ -106,7 +101,7 @@ namespace DDraw
|
|||||||
return DDERR_SURFACELOST;
|
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))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
RealPrimarySurface::update();
|
RealPrimarySurface::update();
|
||||||
@ -124,13 +119,28 @@ namespace DDraw
|
|||||||
return DDERR_WASSTILLDRAWING;
|
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>
|
template <typename TSurface>
|
||||||
HRESULT PrimarySurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
|
HRESULT PrimarySurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
|
||||||
{
|
{
|
||||||
HRESULT result = m_impl.GetCaps(This, lpDDSCaps);
|
HRESULT result = SurfaceImpl::GetCaps(This, lpDDSCaps);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
restorePrimaryCaps(lpDDSCaps->dwCaps);
|
restorePrimaryCaps(lpDDSCaps->dwCaps);
|
||||||
@ -141,7 +151,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 = m_impl.GetSurfaceDesc(This, lpDDSurfaceDesc);
|
HRESULT result = SurfaceImpl::GetSurfaceDesc(This, lpDDSurfaceDesc);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
||||||
@ -152,7 +162,7 @@ namespace DDraw
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
HRESULT PrimarySurfaceImpl<TSurface>::IsLost(TSurface* This)
|
HRESULT PrimarySurfaceImpl<TSurface>::IsLost(TSurface* This)
|
||||||
{
|
{
|
||||||
HRESULT result = m_impl.IsLost(This);
|
HRESULT result = SurfaceImpl::IsLost(This);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
|
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
|
||||||
@ -170,7 +180,7 @@ namespace DDraw
|
|||||||
return DDERR_SURFACELOST;
|
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))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
||||||
@ -181,7 +191,7 @@ namespace DDraw
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
HRESULT PrimarySurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
|
HRESULT PrimarySurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
|
||||||
{
|
{
|
||||||
HRESULT result = m_impl.ReleaseDC(This, hDC);
|
HRESULT result = SurfaceImpl::ReleaseDC(This, hDC);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
RealPrimarySurface::update();
|
RealPrimarySurface::update();
|
||||||
@ -198,7 +208,7 @@ namespace DDraw
|
|||||||
result = RealPrimarySurface::restore();
|
result = RealPrimarySurface::restore();
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
result = m_impl.Restore(This);
|
result = SurfaceImpl::Restore(This);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
PrimarySurface::onRestore();
|
PrimarySurface::onRestore();
|
||||||
@ -220,7 +230,7 @@ namespace DDraw
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT result = m_impl.SetPalette(This, lpDDPalette);
|
HRESULT result = SurfaceImpl::SetPalette(This, lpDDPalette);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
PrimarySurface::s_palette = lpDDPalette;
|
PrimarySurface::s_palette = lpDDPalette;
|
||||||
@ -232,7 +242,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 = m_impl.Unlock(This, lpRect);
|
HRESULT result = SurfaceImpl::Unlock(This, lpRect);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
RealPrimarySurface::update();
|
RealPrimarySurface::update();
|
||||||
|
@ -13,8 +13,6 @@ 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,
|
||||||
@ -29,8 +27,5 @@ namespace DDraw
|
|||||||
virtual HRESULT Restore(TSurface* This) override;
|
virtual HRESULT Restore(TSurface* This) 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;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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
|
namespace DDraw
|
||||||
@ -73,7 +52,6 @@ namespace DDraw
|
|||||||
|
|
||||||
Surface::Surface()
|
Surface::Surface()
|
||||||
: m_ddObject(nullptr)
|
: m_ddObject(nullptr)
|
||||||
, m_ddId()
|
|
||||||
, m_refCount(0)
|
, 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,
|
if (SUCCEEDED(dds->SetPrivateData(&dds, IID_CompatSurfacePrivateData,
|
||||||
privateData.get(), sizeof(privateData.get()), DDSPD_IUNKNOWNPOINTER)))
|
privateData.get(), sizeof(privateData.get()), DDSPD_IUNKNOWNPOINTER)))
|
||||||
@ -97,45 +75,32 @@ namespace DDraw
|
|||||||
privateData->m_impl4->m_data = privateData.get();
|
privateData->m_impl4->m_data = privateData.get();
|
||||||
privateData->m_impl7->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->m_ddObject = DDraw::getDdObject(*CompatPtr<IDirectDraw>(dd));
|
||||||
|
|
||||||
privateData.release();
|
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>
|
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);
|
fixSurfaceDesc(desc.dwFlags, desc.ddsCaps.dwCaps);
|
||||||
HRESULT result = dd->CreateSurface(&dd, &desc, &surface, nullptr);
|
HRESULT result = dd->CreateSurface(&dd, &desc, &surface, nullptr);
|
||||||
|
if (FAILED(result))
|
||||||
if (SUCCEEDED(result))
|
|
||||||
{
|
{
|
||||||
CompatPtr<IDirectDrawSurface7> surface7(
|
return result;
|
||||||
Compat::queryInterface<IDirectDrawSurface7>(surface));
|
}
|
||||||
std::unique_ptr<Surface> privateData(new Surface());
|
|
||||||
attach(*surface7, privateData);
|
auto surface7(CompatPtr<IDirectDrawSurface7>::from(surface));
|
||||||
if (desc.ddsCaps.dwCaps & DDSCAPS_COMPLEX)
|
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(
|
attach(*attachedSurfaces[i], std::make_unique<Surface>());
|
||||||
surface7, surface7, &attachToLinkedSurfaces);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,13 +108,13 @@ namespace DDraw
|
|||||||
}
|
}
|
||||||
|
|
||||||
template HRESULT Surface::create(
|
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(
|
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(
|
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(
|
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()
|
void Surface::createImpl()
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <ddraw.h>
|
#include <ddraw.h>
|
||||||
|
|
||||||
@ -19,10 +20,12 @@ namespace DDraw
|
|||||||
virtual ULONG STDMETHODCALLTYPE AddRef();
|
virtual ULONG STDMETHODCALLTYPE AddRef();
|
||||||
virtual ULONG STDMETHODCALLTYPE Release();
|
virtual ULONG STDMETHODCALLTYPE Release();
|
||||||
|
|
||||||
|
Surface();
|
||||||
virtual ~Surface();
|
virtual ~Surface();
|
||||||
|
|
||||||
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
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>
|
template <typename TSurface>
|
||||||
static Surface* getSurface(TSurface& dds);
|
static Surface* getSurface(TSurface& dds);
|
||||||
@ -31,9 +34,9 @@ namespace DDraw
|
|||||||
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);
|
virtual void createImpl();
|
||||||
|
|
||||||
void* m_ddObject;
|
void* m_ddObject;
|
||||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
|
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
|
||||||
@ -43,14 +46,11 @@ namespace DDraw
|
|||||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface7>> m_impl7;
|
std::unique_ptr<SurfaceImpl<IDirectDrawSurface7>> m_impl7;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <typename TDirectDrawSurface>
|
||||||
|
friend class SurfaceImpl;
|
||||||
template <typename TDirectDrawSurface>
|
template <typename TDirectDrawSurface>
|
||||||
friend class SurfaceImpl2;
|
friend class SurfaceImpl2;
|
||||||
|
|
||||||
static HRESULT WINAPI attachToLinkedSurfaces(
|
|
||||||
IDirectDrawSurface7* surface, DDSURFACEDESC2* desc, void* rootSurface);
|
|
||||||
virtual void createImpl();
|
|
||||||
|
|
||||||
IID m_ddId;
|
|
||||||
DWORD m_refCount;
|
DWORD m_refCount;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "DDraw/DirectDrawSurface.h"
|
||||||
#include "DDraw/RealPrimarySurface.h"
|
#include "DDraw/RealPrimarySurface.h"
|
||||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||||
#include "DDraw/Surfaces/Surface.h"
|
#include "DDraw/Surfaces/Surface.h"
|
||||||
@ -17,20 +18,6 @@ namespace
|
|||||||
DWORD unknown1;
|
DWORD unknown1;
|
||||||
DWORD unknown2;
|
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
|
namespace DDraw
|
||||||
@ -82,7 +69,7 @@ namespace DDraw
|
|||||||
if (SUCCEEDED(result) && (dwFlags & DDGBS_CANBLT))
|
if (SUCCEEDED(result) && (dwFlags & DDGBS_CANBLT))
|
||||||
{
|
{
|
||||||
const bool wait = false;
|
const bool wait = false;
|
||||||
if (!RealPrimarySurface::waitForFlip(Surface::getSurface(*This), wait))
|
if (!RealPrimarySurface::waitForFlip(m_data, wait))
|
||||||
{
|
{
|
||||||
return DDERR_WASSTILLDRAWING;
|
return DDERR_WASSTILLDRAWING;
|
||||||
}
|
}
|
||||||
@ -95,7 +82,7 @@ namespace DDraw
|
|||||||
{
|
{
|
||||||
return s_origVtable.GetCaps(This, lpDDSCaps);
|
return s_origVtable.GetCaps(This, lpDDSCaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
|
HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
|
||||||
{
|
{
|
||||||
@ -108,7 +95,7 @@ namespace DDraw
|
|||||||
|
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
RealPrimarySurface::waitForFlip(Surface::getSurface(*This));
|
RealPrimarySurface::waitForFlip(m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -118,12 +105,10 @@ namespace DDraw
|
|||||||
HRESULT SurfaceImpl2<TSurface>::GetDDInterface(TSurface* /*This*/, LPVOID* lplpDD)
|
HRESULT SurfaceImpl2<TSurface>::GetDDInterface(TSurface* /*This*/, LPVOID* lplpDD)
|
||||||
{
|
{
|
||||||
DirectDrawInterface dd = {};
|
DirectDrawInterface dd = {};
|
||||||
dd.vtable = IID_IDirectDraw7 == m_data->m_ddId
|
dd.vtable = static_cast<const void*>(CompatVtable<IDirectDraw7Vtbl>::s_origVtablePtr);
|
||||||
? static_cast<const void*>(CompatVtable<IDirectDrawVtbl>::s_origVtablePtr)
|
|
||||||
: static_cast<const void*>(CompatVtable<IDirectDraw7Vtbl>::s_origVtablePtr);
|
|
||||||
dd.ddObject = m_data->m_ddObject;
|
dd.ddObject = m_data->m_ddObject;
|
||||||
return CompatVtable<IDirectDrawVtbl>::s_origVtable.QueryInterface(
|
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>
|
template <typename TSurface>
|
||||||
@ -133,7 +118,7 @@ namespace DDraw
|
|||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
const bool wait = false;
|
const bool wait = false;
|
||||||
if (!RealPrimarySurface::waitForFlip(Surface::getSurface(*This), wait))
|
if (!RealPrimarySurface::waitForFlip(m_data, wait))
|
||||||
{
|
{
|
||||||
return DDERR_WASSTILLDRAWING;
|
return DDERR_WASSTILLDRAWING;
|
||||||
}
|
}
|
||||||
@ -207,6 +192,14 @@ namespace DDraw
|
|||||||
return s_origVtable.Unlock(This, lpRect);
|
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>
|
template <typename TSurface>
|
||||||
const Vtable<TSurface>& SurfaceImpl<TSurface>::s_origVtable =
|
const Vtable<TSurface>& SurfaceImpl<TSurface>::s_origVtable =
|
||||||
CompatVtable<Vtable<TSurface>>::s_origVtable;
|
CompatVtable<Vtable<TSurface>>::s_origVtable;
|
||||||
|
@ -55,5 +55,8 @@ namespace DDraw
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const Vtable<TSurface>& s_origVtable;
|
static const Vtable<TSurface>& s_origVtable;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user