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

Fixed alt-tabbing in Titanic: Adventure Out of Time

This commit is contained in:
narzoul 2022-07-24 17:07:24 +02:00
parent 6fdc7ad21a
commit 9bca0a6ba0
6 changed files with 41 additions and 37 deletions

View File

@ -91,8 +91,7 @@ namespace
tagSurface->setFullscreenWindow(isFullscreen ? hWnd : nullptr); tagSurface->setFullscreenWindow(isFullscreen ? hWnd : nullptr);
if (DDraw::RealPrimarySurface::getSurface()) if (DDraw::RealPrimarySurface::getSurface())
{ {
DDraw::RealPrimarySurface::release(); DDraw::RealPrimarySurface::restore();
DDraw::RealPrimarySurface::create(CompatRef<TDirectDraw>(*This));
} }
} }
} }

View File

@ -150,7 +150,7 @@ namespace DDraw
auto it = g_surfaceToClipperData.find(&surface); auto it = g_surfaceToClipperData.find(&surface);
if (it != g_surfaceToClipperData.end()) if (it != g_surfaceToClipperData.end())
{ {
auto& [prevClipper, prevClipperData] = *it->second; auto [prevClipper, prevClipperData] = *it->second;
if (prevClipper == clipper) if (prevClipper == clipper)
{ {
return; return;

View File

@ -50,6 +50,7 @@ namespace
bool g_isFullscreen = false; bool g_isFullscreen = false;
DDraw::Surface* g_lastFlipSurface = nullptr; DDraw::Surface* g_lastFlipSurface = nullptr;
DDraw::TagSurface* g_tagSurface = nullptr;
Compat::CriticalSection g_presentCs; Compat::CriticalSection g_presentCs;
bool g_isDelayedFlipPending = false; bool g_isDelayedFlipPending = false;
@ -169,22 +170,9 @@ namespace
CALL_ORIG_PROC(DirectDrawEnumerateExA)(createDefaultPrimaryEnum, &dm.deviceName, DDENUM_ATTACHEDSECONDARYDEVICES); CALL_ORIG_PROC(DirectDrawEnumerateExA)(createDefaultPrimaryEnum, &dm.deviceName, DDENUM_ATTACHEDSECONDARYDEVICES);
} }
CompatPtr<IDirectDrawSurface7> createWindowedBackBuffer(DDRAWI_DIRECTDRAW_LCL* ddLcl, DWORD width, DWORD height) CompatPtr<IDirectDrawSurface7> createWindowedBackBuffer(DWORD width, DWORD height)
{ {
if (!ddLcl) auto resource = DDraw::DirectDrawSurface::getDriverResourceHandle(*g_tagSurface->getDDS());
{
LOG_INFO << "ERROR: createWindowedBackBuffer: ddLcl is null";
return nullptr;
}
auto tagSurface = DDraw::TagSurface::get(ddLcl);
if (!tagSurface)
{
LOG_INFO << "ERROR: createWindowedBackBuffer: TagSurface not found";
return nullptr;
}
auto resource = DDraw::DirectDrawSurface::getDriverResourceHandle(*tagSurface->getDDS());
if (!resource) if (!resource)
{ {
LOG_INFO << "ERROR: createWindowedBackBuffer: driver resource handle not found"; LOG_INFO << "ERROR: createWindowedBackBuffer: driver resource handle not found";
@ -283,6 +271,7 @@ namespace
g_clipper.release(); g_clipper.release();
g_isFullscreen = false; g_isFullscreen = false;
g_surfaceDesc = {}; g_surfaceDesc = {};
g_tagSurface = nullptr;
DDraw::RealPrimarySurface::updateDevicePresentationWindowPos(); DDraw::RealPrimarySurface::updateDevicePresentationWindowPos();
g_devicePresentationWindow = nullptr; g_devicePresentationWindow = nullptr;
@ -439,21 +428,20 @@ namespace
namespace DDraw namespace DDraw
{ {
template <typename DirectDraw> HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw> dd)
HRESULT RealPrimarySurface::create(CompatRef<DirectDraw> dd)
{ {
LOG_FUNC("RealPrimarySurface::create", &dd); LOG_FUNC("RealPrimarySurface::create", &dd);
DDraw::ScopedThreadLock lock; DDraw::ScopedThreadLock lock;
g_monitorRect = D3dDdi::KernelModeThunks::getAdapterInfo(*CompatPtr<IDirectDraw7>::from(&dd)).monitorInfo.rcMonitor; g_monitorRect = D3dDdi::KernelModeThunks::getAdapterInfo(*CompatPtr<IDirectDraw7>::from(&dd)).monitorInfo.rcMonitor;
typename Types<DirectDraw>::TSurfaceDesc desc = {}; DDSURFACEDESC desc = {};
desc.dwSize = sizeof(desc); desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
desc.dwBackBufferCount = 2; desc.dwBackBufferCount = 2;
g_isFullscreen = true; g_isFullscreen = true;
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface; CompatPtr<IDirectDrawSurface> surface;
HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr); HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);
if (DDERR_NOEXCLUSIVEMODE == result) if (DDERR_NOEXCLUSIVEMODE == result)
@ -472,13 +460,23 @@ namespace DDraw
return result; return result;
} }
auto ddLcl = DDraw::DirectDraw::getInt(dd.get()).lpLcl;
g_tagSurface = DDraw::TagSurface::get(ddLcl);
if (!g_tagSurface)
{
LOG_INFO << "ERROR: TagSurface not found";
g_monitorRect = {};
return DDERR_GENERIC;
}
if (0 == desc.dwBackBufferCount) if (0 == desc.dwBackBufferCount)
{ {
g_windowedBackBuffer = createWindowedBackBuffer(DDraw::DirectDraw::getInt(dd.get()).lpLcl, g_windowedBackBuffer = createWindowedBackBuffer(
g_monitorRect.right - g_monitorRect.left, g_monitorRect.bottom - g_monitorRect.top).detach(); g_monitorRect.right - g_monitorRect.left, g_monitorRect.bottom - g_monitorRect.top).detach();
if (!g_windowedBackBuffer) if (!g_windowedBackBuffer)
{ {
g_monitorRect = {}; g_monitorRect = {};
g_tagSurface = nullptr;
return DDERR_GENERIC; return DDERR_GENERIC;
} }
} }
@ -507,11 +505,6 @@ namespace DDraw
return DD_OK; return DD_OK;
} }
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw>);
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw2>);
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw4>);
template HRESULT RealPrimarySurface::create(CompatRef<IDirectDraw7>);
void RealPrimarySurface::destroyDefaultPrimary() void RealPrimarySurface::destroyDefaultPrimary()
{ {
if (g_defaultPrimary) if (g_defaultPrimary)
@ -594,6 +587,10 @@ namespace DDraw
} }
createDefaultPrimary(); createDefaultPrimary();
if (!g_defaultPrimary && g_frontBuffer && FAILED(g_frontBuffer->IsLost(g_frontBuffer)))
{
restore();
}
updatePresentationWindowPos(); updatePresentationWindowPos();
auto src(g_isDelayedFlipPending ? g_lastFlipSurface->getDDS() : DDraw::PrimarySurface::getPrimary()); auto src(g_isDelayedFlipPending ? g_lastFlipSurface->getDDS() : DDraw::PrimarySurface::getPrimary());
@ -678,12 +675,21 @@ namespace DDraw
HRESULT RealPrimarySurface::restore() HRESULT RealPrimarySurface::restore()
{ {
DDraw::ScopedThreadLock lock; DDraw::ScopedThreadLock lock;
HRESULT result = g_frontBuffer->Restore(g_frontBuffer); if (g_defaultPrimary)
if (SUCCEEDED(result))
{ {
onRestore(); destroyDefaultPrimary();
createDefaultPrimary();
return DD_OK;
} }
return result;
auto dd(g_tagSurface->getDD());
if (g_isFullscreen && FAILED(dd->TestCooperativeLevel(dd)))
{
return DDERR_NOEXCLUSIVEMODE;
}
release();
return create(*CompatPtr<IDirectDraw>::from(dd.get()));
} }
void RealPrimarySurface::scheduleUpdate() void RealPrimarySurface::scheduleUpdate()

View File

@ -12,9 +12,7 @@ namespace DDraw
class RealPrimarySurface class RealPrimarySurface
{ {
public: public:
template <typename DirectDraw> static HRESULT create(CompatRef<IDirectDraw> dd);
static HRESULT create(CompatRef<DirectDraw> dd);
static void destroyDefaultPrimary(); static void destroyDefaultPrimary();
static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags); static HRESULT flip(CompatPtr<IDirectDrawSurface7> surfaceTargetOverride, DWORD flags);
static int flush(); static int flush();

View File

@ -63,7 +63,7 @@ namespace DDraw
g_monitorRect.right = g_monitorRect.left + dm.dwWidth; g_monitorRect.right = g_monitorRect.left + dm.dwWidth;
g_monitorRect.bottom = g_monitorRect.top + dm.dwHeight; g_monitorRect.bottom = g_monitorRect.top + dm.dwHeight;
HRESULT result = RealPrimarySurface::create(dd); HRESULT result = RealPrimarySurface::create(*CompatPtr<IDirectDraw>::from(&dd));
if (FAILED(result)) if (FAILED(result))
{ {
return LOG_RESULT(result); return LOG_RESULT(result);

View File

@ -244,7 +244,8 @@ namespace DDraw
HRESULT result = IsLost(This); HRESULT result = IsLost(This);
if (FAILED(result)) if (FAILED(result))
{ {
result = RealPrimarySurface::restore(); auto realPrimary = RealPrimarySurface::getSurface();
result = SUCCEEDED(realPrimary->IsLost(realPrimary)) ? DD_OK : RealPrimarySurface::restore();
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
return SurfaceImpl::Restore(This); return SurfaceImpl::Restore(This);