2016-09-11 17:34:39 +02:00
|
|
|
#include "DDraw/DirectDrawPalette.h"
|
|
|
|
#include "DDraw/RealPrimarySurface.h"
|
|
|
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
|
|
|
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
|
|
|
|
#include "Gdi/Gdi.h"
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
void restorePrimaryCaps(DWORD& caps)
|
|
|
|
{
|
|
|
|
caps &= ~DDSCAPS_OFFSCREENPLAIN;
|
|
|
|
caps |= DDSCAPS_PRIMARYSURFACE | DDSCAPS_VISIBLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace DDraw
|
|
|
|
{
|
2016-09-11 22:44:30 +02:00
|
|
|
template <typename TSurface>
|
|
|
|
PrimarySurfaceImpl<TSurface>::PrimarySurfaceImpl(SurfaceImpl& impl) : m_impl(impl)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-09-11 17:34:39 +02:00
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::Blt(
|
|
|
|
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
|
|
|
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
|
|
|
|
{
|
|
|
|
if (RealPrimarySurface::isLost())
|
|
|
|
{
|
|
|
|
return DDERR_SURFACELOST;
|
|
|
|
}
|
|
|
|
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
RealPrimarySurface::update();
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::BltFast(
|
|
|
|
TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
|
|
|
|
{
|
|
|
|
if (RealPrimarySurface::isLost())
|
|
|
|
{
|
|
|
|
return DDERR_SURFACELOST;
|
|
|
|
}
|
|
|
|
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
const LONG x = dwX;
|
|
|
|
const LONG y = dwY;
|
|
|
|
RECT destRect = { x, y, x, y };
|
|
|
|
if (lpSrcRect)
|
|
|
|
{
|
|
|
|
destRect.right += lpSrcRect->right - lpSrcRect->left;
|
|
|
|
destRect.bottom += lpSrcRect->bottom - lpSrcRect->top;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TSurfaceDesc desc = {};
|
|
|
|
desc.dwSize = sizeof(desc);
|
2016-09-18 19:01:41 +02:00
|
|
|
CompatVtable<Vtable<TSurface>>::s_origVtable.GetSurfaceDesc(lpDDSrcSurface, &desc);
|
2016-09-11 17:34:39 +02:00
|
|
|
destRect.right += desc.dwWidth;
|
|
|
|
destRect.bottom += desc.dwHeight;
|
|
|
|
}
|
|
|
|
RealPrimarySurface::update();
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags)
|
|
|
|
{
|
|
|
|
if (RealPrimarySurface::isLost())
|
|
|
|
{
|
|
|
|
return DDERR_SURFACELOST;
|
|
|
|
}
|
|
|
|
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.Flip(This, lpDDSurfaceTargetOverride, dwFlags);
|
2017-07-25 21:27:40 +02:00
|
|
|
if (FAILED(result))
|
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = RealPrimarySurface::flip(dwFlags);
|
|
|
|
if (SUCCEEDED(result) && !PrimarySurface::isFlipEmulated())
|
|
|
|
{
|
|
|
|
static_cast<PrimarySurface*>(m_data)->updateGdiSurfacePtr(
|
|
|
|
CompatPtr<IDirectDrawSurface>::from(lpDDSurfaceTargetOverride));
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
undoFlip(This, lpDDSurfaceTargetOverride);
|
|
|
|
|
|
|
|
if (SUCCEEDED(result) && PrimarySurface::isFlipEmulated())
|
2016-09-11 17:34:39 +02:00
|
|
|
{
|
2017-07-25 21:27:40 +02:00
|
|
|
if (lpDDSurfaceTargetOverride)
|
2016-11-01 17:13:07 +01:00
|
|
|
{
|
2017-07-25 21:27:40 +02:00
|
|
|
s_origVtable.BltFast(This, 0, 0, lpDDSurfaceTargetOverride, nullptr, DDBLTFAST_WAIT);
|
2016-11-01 17:13:07 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-07-25 21:27:40 +02:00
|
|
|
TDdsCaps caps = {};
|
|
|
|
caps.dwCaps = DDSCAPS_BACKBUFFER;
|
|
|
|
CompatPtr<TSurface> backBuffer;
|
|
|
|
s_origVtable.GetAttachedSurface(This, &caps, &backBuffer.getRef());
|
|
|
|
|
|
|
|
s_origVtable.BltFast(This, 0, 0, backBuffer, nullptr, DDBLTFAST_WAIT);
|
2016-11-01 17:13:07 +01:00
|
|
|
}
|
2016-09-11 17:34:39 +02:00
|
|
|
}
|
2017-07-25 21:27:40 +02:00
|
|
|
|
2016-09-11 17:34:39 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
|
|
|
|
{
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.GetCaps(This, lpDDSCaps);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
restorePrimaryCaps(lpDDSCaps->dwCaps);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
|
|
|
|
{
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.GetSurfaceDesc(This, lpDDSurfaceDesc);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::IsLost(TSurface* This)
|
|
|
|
{
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.IsLost(This);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
result = RealPrimarySurface::isLost() ? DDERR_SURFACELOST : DD_OK;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::Lock(
|
|
|
|
TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
|
|
|
|
DWORD dwFlags, HANDLE hEvent)
|
|
|
|
{
|
|
|
|
if (RealPrimarySurface::isLost())
|
|
|
|
{
|
|
|
|
return DDERR_SURFACELOST;
|
|
|
|
}
|
|
|
|
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::ReleaseDC(TSurface* This, HDC hDC)
|
|
|
|
{
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.ReleaseDC(This, hDC);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
RealPrimarySurface::update();
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::Restore(TSurface* This)
|
|
|
|
{
|
|
|
|
HRESULT result = IsLost(This);
|
|
|
|
if (FAILED(result))
|
|
|
|
{
|
|
|
|
result = RealPrimarySurface::restore();
|
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
2016-09-11 22:44:30 +02:00
|
|
|
result = m_impl.Restore(This);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
2017-03-12 17:00:16 +01:00
|
|
|
Gdi::redraw(nullptr);
|
2016-09-11 17:34:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper)
|
|
|
|
{
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.SetClipper(This, lpDDClipper);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
RealPrimarySurface::setClipper(lpDDClipper);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette)
|
|
|
|
{
|
|
|
|
if (lpDDPalette)
|
|
|
|
{
|
|
|
|
DirectDrawPalette::waitForNextUpdate();
|
|
|
|
}
|
|
|
|
if (lpDDPalette == PrimarySurface::s_palette)
|
|
|
|
{
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.SetPalette(This, lpDDPalette);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
PrimarySurface::s_palette = lpDDPalette;
|
|
|
|
RealPrimarySurface::setPalette();
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename TSurface>
|
|
|
|
HRESULT PrimarySurfaceImpl<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect)
|
|
|
|
{
|
2016-09-11 22:44:30 +02:00
|
|
|
HRESULT result = m_impl.Unlock(This, lpRect);
|
2016-09-11 17:34:39 +02:00
|
|
|
if (SUCCEEDED(result))
|
|
|
|
{
|
|
|
|
RealPrimarySurface::update();
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template PrimarySurfaceImpl<IDirectDrawSurface>;
|
|
|
|
template PrimarySurfaceImpl<IDirectDrawSurface2>;
|
|
|
|
template PrimarySurfaceImpl<IDirectDrawSurface3>;
|
|
|
|
template PrimarySurfaceImpl<IDirectDrawSurface4>;
|
|
|
|
template PrimarySurfaceImpl<IDirectDrawSurface7>;
|
|
|
|
}
|