mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Implemented GetGDISurface and FlipToGDISurface
This commit is contained in:
parent
fbe34c0341
commit
1d14b606c2
@ -9,6 +9,12 @@ template <typename Intf>
|
|||||||
class CompatPtr : public CompatWeakPtr<Intf>
|
class CompatPtr : public CompatWeakPtr<Intf>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
template <typename OtherIntf>
|
||||||
|
static CompatPtr from(OtherIntf* other)
|
||||||
|
{
|
||||||
|
return CompatPtr(Compat::queryInterface<Intf>(other));
|
||||||
|
}
|
||||||
|
|
||||||
CompatPtr(std::nullptr_t = nullptr)
|
CompatPtr(std::nullptr_t = nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,9 @@ namespace DDraw
|
|||||||
void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
|
void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
|
||||||
{
|
{
|
||||||
vtable.CreateSurface = &CreateSurface;
|
vtable.CreateSurface = &CreateSurface;
|
||||||
|
vtable.FlipToGDISurface = &FlipToGDISurface;
|
||||||
vtable.GetDisplayMode = &GetDisplayMode;
|
vtable.GetDisplayMode = &GetDisplayMode;
|
||||||
|
vtable.GetGDISurface = &GetGDISurface;
|
||||||
vtable.RestoreDisplayMode = &RestoreDisplayMode;
|
vtable.RestoreDisplayMode = &RestoreDisplayMode;
|
||||||
vtable.SetCooperativeLevel = &SetCooperativeLevel;
|
vtable.SetCooperativeLevel = &SetCooperativeLevel;
|
||||||
vtable.SetDisplayMode = &SetDisplayMode;
|
vtable.SetDisplayMode = &SetDisplayMode;
|
||||||
@ -74,6 +76,12 @@ namespace DDraw
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TDirectDraw>
|
||||||
|
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::FlipToGDISurface(TDirectDraw* /*This*/)
|
||||||
|
{
|
||||||
|
return PrimarySurface::flipToGdiSurface();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TDirectDraw>
|
template <typename TDirectDraw>
|
||||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetDisplayMode(
|
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetDisplayMode(
|
||||||
TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc)
|
TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc)
|
||||||
@ -92,6 +100,25 @@ namespace DDraw
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TDirectDraw>
|
||||||
|
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetGDISurface(
|
||||||
|
TDirectDraw* /*This*/, TSurface** lplpGDIDDSSurface)
|
||||||
|
{
|
||||||
|
if (!lplpGDIDDSSurface)
|
||||||
|
{
|
||||||
|
return DDERR_INVALIDPARAMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto gdiSurface(PrimarySurface::getGdiSurface());
|
||||||
|
if (!gdiSurface)
|
||||||
|
{
|
||||||
|
return DDERR_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lplpGDIDDSSurface = CompatPtr<TSurface>::from(gdiSurface.get()).detach();
|
||||||
|
return DD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TDirectDraw>
|
template <typename TDirectDraw>
|
||||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::RestoreDisplayMode(TDirectDraw* This)
|
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::RestoreDisplayMode(TDirectDraw* This)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,9 @@ namespace DDraw
|
|||||||
TSurface** lplpDDSurface,
|
TSurface** lplpDDSurface,
|
||||||
IUnknown* pUnkOuter);
|
IUnknown* pUnkOuter);
|
||||||
|
|
||||||
|
static HRESULT STDMETHODCALLTYPE FlipToGDISurface(TDirectDraw* This);
|
||||||
static HRESULT STDMETHODCALLTYPE GetDisplayMode(TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc);
|
static HRESULT STDMETHODCALLTYPE GetDisplayMode(TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||||
|
static HRESULT STDMETHODCALLTYPE GetGDISurface(TDirectDraw* This, TSurface** lplpGDIDDSSurface);
|
||||||
static HRESULT STDMETHODCALLTYPE RestoreDisplayMode(TDirectDraw* This);
|
static HRESULT STDMETHODCALLTYPE RestoreDisplayMode(TDirectDraw* This);
|
||||||
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
|
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
DDSURFACEDESC2 g_primarySurfaceDesc = {};
|
DDSURFACEDESC2 g_primarySurfaceDesc = {};
|
||||||
|
CompatWeakPtr<IDirectDrawSurface> g_gdiSurface = nullptr;
|
||||||
CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr;
|
CompatWeakPtr<IDirectDrawSurface> g_primarySurface = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ namespace DDraw
|
|||||||
{
|
{
|
||||||
Compat::LogEnter("PrimarySurface::~PrimarySurface");
|
Compat::LogEnter("PrimarySurface::~PrimarySurface");
|
||||||
|
|
||||||
|
g_gdiSurface = nullptr;
|
||||||
g_primarySurface = nullptr;
|
g_primarySurface = nullptr;
|
||||||
s_palette = nullptr;
|
s_palette = nullptr;
|
||||||
ZeroMemory(&s_paletteEntries, sizeof(s_paletteEntries));
|
ZeroMemory(&s_paletteEntries, sizeof(s_paletteEntries));
|
||||||
@ -62,6 +64,7 @@ namespace DDraw
|
|||||||
attach(*surface7, privateData);
|
attach(*surface7, privateData);
|
||||||
|
|
||||||
CompatPtr<IDirectDrawSurface> surface1(Compat::queryInterface<IDirectDrawSurface>(surface));
|
CompatPtr<IDirectDrawSurface> surface1(Compat::queryInterface<IDirectDrawSurface>(surface));
|
||||||
|
g_gdiSurface = surface1;
|
||||||
g_primarySurface = surface1;
|
g_primarySurface = surface1;
|
||||||
|
|
||||||
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
|
ZeroMemory(&g_primarySurfaceDesc, sizeof(g_primarySurfaceDesc));
|
||||||
@ -89,11 +92,25 @@ namespace DDraw
|
|||||||
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>(*m_surface->getImpl<IDirectDrawSurface7>()));
|
m_impl7.reset(new PrimarySurfaceImpl<IDirectDrawSurface7>(*m_surface->getImpl<IDirectDrawSurface7>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT PrimarySurface::flipToGdiSurface()
|
||||||
|
{
|
||||||
|
if (!g_primarySurface)
|
||||||
|
{
|
||||||
|
return DDERR_NOTFOUND;
|
||||||
|
}
|
||||||
|
return g_primarySurface.get()->lpVtbl->Flip(g_primarySurface, g_gdiSurface, DDFLIP_WAIT);
|
||||||
|
}
|
||||||
|
|
||||||
const DDSURFACEDESC2& PrimarySurface::getDesc()
|
const DDSURFACEDESC2& PrimarySurface::getDesc()
|
||||||
{
|
{
|
||||||
return g_primarySurfaceDesc;
|
return g_primarySurfaceDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompatPtr<IDirectDrawSurface7> PrimarySurface::getGdiSurface()
|
||||||
|
{
|
||||||
|
return CompatPtr<IDirectDrawSurface7>::from(g_gdiSurface.get());
|
||||||
|
}
|
||||||
|
|
||||||
CompatPtr<IDirectDrawSurface7> PrimarySurface::getPrimary()
|
CompatPtr<IDirectDrawSurface7> PrimarySurface::getPrimary()
|
||||||
{
|
{
|
||||||
if (!g_primarySurface)
|
if (!g_primarySurface)
|
||||||
@ -104,6 +121,36 @@ namespace DDraw
|
|||||||
Compat::queryInterface<IDirectDrawSurface7>(g_primarySurface.get()));
|
Compat::queryInterface<IDirectDrawSurface7>(g_primarySurface.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrimarySurface::updateGdiSurfacePtr(IDirectDrawSurface* flipTargetOverride)
|
||||||
|
{
|
||||||
|
auto primary(CompatPtr<IDirectDrawSurface>::from(m_surface->getDirectDrawSurface().get()));
|
||||||
|
if (flipTargetOverride)
|
||||||
|
{
|
||||||
|
if (g_gdiSurface.get() == flipTargetOverride)
|
||||||
|
{
|
||||||
|
g_gdiSurface = primary;
|
||||||
|
}
|
||||||
|
else if (g_gdiSurface.get() == primary)
|
||||||
|
{
|
||||||
|
g_gdiSurface = flipTargetOverride;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDSCAPS caps = {};
|
||||||
|
caps.dwCaps = DDSCAPS_FLIP;
|
||||||
|
CompatPtr<IDirectDrawSurface> current(primary);
|
||||||
|
CompatPtr<IDirectDrawSurface> next;
|
||||||
|
HRESULT result = current->GetAttachedSurface(current, &caps, &next.getRef());
|
||||||
|
while (SUCCEEDED(result) && next.get() != g_gdiSurface.get() && next.get() != primary)
|
||||||
|
{
|
||||||
|
current = next;
|
||||||
|
result = current->GetAttachedSurface(current, &caps, &next.getRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
g_gdiSurface = current;
|
||||||
|
}
|
||||||
|
|
||||||
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
|
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
|
||||||
PALETTEENTRY PrimarySurface::s_paletteEntries[256] = {};
|
PALETTEENTRY PrimarySurface::s_paletteEntries[256] = {};
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,13 @@ namespace DDraw
|
|||||||
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);
|
||||||
|
|
||||||
|
static HRESULT flipToGdiSurface();
|
||||||
static const DDSURFACEDESC2& getDesc();
|
static const DDSURFACEDESC2& getDesc();
|
||||||
|
static CompatPtr<IDirectDrawSurface7> getGdiSurface();
|
||||||
static CompatPtr<IDirectDrawSurface7> getPrimary();
|
static CompatPtr<IDirectDrawSurface7> getPrimary();
|
||||||
|
|
||||||
|
void updateGdiSurfacePtr(IDirectDrawSurface* flipTargetOverride);
|
||||||
|
|
||||||
static CompatWeakPtr<IDirectDrawPalette> s_palette;
|
static CompatWeakPtr<IDirectDrawPalette> s_palette;
|
||||||
static PALETTEENTRY s_paletteEntries[256];
|
static PALETTEENTRY s_paletteEntries[256];
|
||||||
|
|
||||||
|
@ -85,6 +85,15 @@ namespace DDraw
|
|||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
result = RealPrimarySurface::flip(dwFlags);
|
result = RealPrimarySurface::flip(dwFlags);
|
||||||
|
if (SUCCEEDED(result))
|
||||||
|
{
|
||||||
|
static_cast<PrimarySurface*>(m_data)->updateGdiSurfacePtr(
|
||||||
|
CompatPtr<IDirectDrawSurface>::from(lpDDSurfaceTargetOverride));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
undoFlip(This, lpDDSurfaceTargetOverride);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,26 @@ namespace DDraw
|
|||||||
::fixSurfacePtrs(*surface7);
|
::fixSurfacePtrs(*surface7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TSurface>
|
||||||
|
void SurfaceImpl<TSurface>::undoFlip(TSurface* This, TSurface* targetOverride)
|
||||||
|
{
|
||||||
|
if (targetOverride)
|
||||||
|
{
|
||||||
|
SurfaceImpl::Flip(This, targetOverride, DDFLIP_WAIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TSurfaceDesc desc = {};
|
||||||
|
desc.dwSize = sizeof(desc);
|
||||||
|
s_origVtable.GetSurfaceDesc(This, &desc);
|
||||||
|
|
||||||
|
for (DWORD i = 0; i < desc.dwBackBufferCount; ++i)
|
||||||
|
{
|
||||||
|
SurfaceImpl::Flip(This, nullptr, DDFLIP_WAIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
HRESULT SurfaceImpl<TSurface>::Blt(
|
HRESULT SurfaceImpl<TSurface>::Blt(
|
||||||
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
||||||
|
@ -55,6 +55,9 @@ namespace DDraw
|
|||||||
virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette);
|
virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette);
|
||||||
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
|
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void undoFlip(TSurface* This, TSurface* targetOverride);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const Vtable<TSurface>& s_origVtable;
|
static const Vtable<TSurface>& s_origVtable;
|
||||||
};
|
};
|
||||||
|
@ -54,12 +54,13 @@ namespace
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lockPrimarySurface(DWORD lockFlags)
|
bool lockGdiSurface(DWORD lockFlags)
|
||||||
{
|
{
|
||||||
DDSURFACEDESC2 desc = {};
|
DDSURFACEDESC2 desc = {};
|
||||||
desc.dwSize = sizeof(desc);
|
desc.dwSize = sizeof(desc);
|
||||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
auto gdiSurface(DDraw::PrimarySurface::getGdiSurface());
|
||||||
if (!primary || FAILED(primary->Lock(primary, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
|
if (!gdiSurface || FAILED(gdiSurface.get()->lpVtbl->Lock(
|
||||||
|
gdiSurface, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -76,13 +77,13 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlockPrimarySurface()
|
void unlockGdiSurface()
|
||||||
{
|
{
|
||||||
GdiFlush();
|
GdiFlush();
|
||||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
auto gdiSurface(DDraw::PrimarySurface::getGdiSurface());
|
||||||
if (primary)
|
if (gdiSurface)
|
||||||
{
|
{
|
||||||
primary->Unlock(primary, nullptr);
|
gdiSurface.get()->lpVtbl->Unlock(gdiSurface, nullptr);
|
||||||
if (DDLOCK_READONLY != g_ddLockFlags)
|
if (DDLOCK_READONLY != g_ddLockFlags)
|
||||||
{
|
{
|
||||||
DDraw::RealPrimarySurface::invalidate(nullptr);
|
DDraw::RealPrimarySurface::invalidate(nullptr);
|
||||||
@ -118,7 +119,7 @@ namespace Gdi
|
|||||||
LeaveCriticalSection(&g_gdiCriticalSection);
|
LeaveCriticalSection(&g_gdiCriticalSection);
|
||||||
Dll::g_origProcs.AcquireDDThreadLock();
|
Dll::g_origProcs.AcquireDDThreadLock();
|
||||||
EnterCriticalSection(&g_gdiCriticalSection);
|
EnterCriticalSection(&g_gdiCriticalSection);
|
||||||
if (!lockPrimarySurface(lockFlags))
|
if (!lockGdiSurface(lockFlags))
|
||||||
{
|
{
|
||||||
Dll::g_origProcs.ReleaseDDThreadLock();
|
Dll::g_origProcs.ReleaseDDThreadLock();
|
||||||
return false;
|
return false;
|
||||||
@ -142,7 +143,7 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
if (1 == g_renderingRefCount)
|
if (1 == g_renderingRefCount)
|
||||||
{
|
{
|
||||||
unlockPrimarySurface();
|
unlockGdiSurface();
|
||||||
g_ddLockThreadRenderingRefCount = 0;
|
g_ddLockThreadRenderingRefCount = 0;
|
||||||
g_renderingRefCount = 0;
|
g_renderingRefCount = 0;
|
||||||
}
|
}
|
||||||
@ -151,7 +152,7 @@ namespace Gdi
|
|||||||
g_isDelayedUnlockPending = true;
|
g_isDelayedUnlockPending = true;
|
||||||
gdiLock.unlock();
|
gdiLock.unlock();
|
||||||
WaitForSingleObject(g_ddUnlockBeginEvent, INFINITE);
|
WaitForSingleObject(g_ddUnlockBeginEvent, INFINITE);
|
||||||
unlockPrimarySurface();
|
unlockGdiSurface();
|
||||||
g_ddLockThreadRenderingRefCount = 0;
|
g_ddLockThreadRenderingRefCount = 0;
|
||||||
g_renderingRefCount = 0;
|
g_renderingRefCount = 0;
|
||||||
SetEvent(g_ddUnlockEndEvent);
|
SetEvent(g_ddUnlockEndEvent);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user