diff --git a/DDrawCompat/DDraw/DirectDraw.cpp b/DDrawCompat/DDraw/DirectDraw.cpp index 452f9e3..4ce4b42 100644 --- a/DDrawCompat/DDraw/DirectDraw.cpp +++ b/DDrawCompat/DDraw/DirectDraw.cpp @@ -91,8 +91,7 @@ namespace tagSurface->setFullscreenWindow(isFullscreen ? hWnd : nullptr); if (DDraw::RealPrimarySurface::getSurface()) { - DDraw::RealPrimarySurface::release(); - DDraw::RealPrimarySurface::create(CompatRef(*This)); + DDraw::RealPrimarySurface::restore(); } } } diff --git a/DDrawCompat/DDraw/DirectDrawClipper.cpp b/DDrawCompat/DDraw/DirectDrawClipper.cpp index 471f99a..3394cfe 100644 --- a/DDrawCompat/DDraw/DirectDrawClipper.cpp +++ b/DDrawCompat/DDraw/DirectDrawClipper.cpp @@ -150,7 +150,7 @@ namespace DDraw auto it = g_surfaceToClipperData.find(&surface); if (it != g_surfaceToClipperData.end()) { - auto& [prevClipper, prevClipperData] = *it->second; + auto [prevClipper, prevClipperData] = *it->second; if (prevClipper == clipper) { return; diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index 838744b..5c2a10e 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -50,6 +50,7 @@ namespace bool g_isFullscreen = false; DDraw::Surface* g_lastFlipSurface = nullptr; + DDraw::TagSurface* g_tagSurface = nullptr; Compat::CriticalSection g_presentCs; bool g_isDelayedFlipPending = false; @@ -169,22 +170,9 @@ namespace CALL_ORIG_PROC(DirectDrawEnumerateExA)(createDefaultPrimaryEnum, &dm.deviceName, DDENUM_ATTACHEDSECONDARYDEVICES); } - CompatPtr createWindowedBackBuffer(DDRAWI_DIRECTDRAW_LCL* ddLcl, DWORD width, DWORD height) + CompatPtr createWindowedBackBuffer(DWORD width, DWORD height) { - if (!ddLcl) - { - 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()); + auto resource = DDraw::DirectDrawSurface::getDriverResourceHandle(*g_tagSurface->getDDS()); if (!resource) { LOG_INFO << "ERROR: createWindowedBackBuffer: driver resource handle not found"; @@ -283,6 +271,7 @@ namespace g_clipper.release(); g_isFullscreen = false; g_surfaceDesc = {}; + g_tagSurface = nullptr; DDraw::RealPrimarySurface::updateDevicePresentationWindowPos(); g_devicePresentationWindow = nullptr; @@ -439,21 +428,20 @@ namespace namespace DDraw { - template - HRESULT RealPrimarySurface::create(CompatRef dd) + HRESULT RealPrimarySurface::create(CompatRef dd) { LOG_FUNC("RealPrimarySurface::create", &dd); DDraw::ScopedThreadLock lock; g_monitorRect = D3dDdi::KernelModeThunks::getAdapterInfo(*CompatPtr::from(&dd)).monitorInfo.rcMonitor; - typename Types::TSurfaceDesc desc = {}; + DDSURFACEDESC desc = {}; desc.dwSize = sizeof(desc); desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; desc.dwBackBufferCount = 2; g_isFullscreen = true; - CompatPtr::TCreatedSurface> surface; + CompatPtr surface; HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr); if (DDERR_NOEXCLUSIVEMODE == result) @@ -472,13 +460,23 @@ namespace DDraw 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) { - 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(); if (!g_windowedBackBuffer) { g_monitorRect = {}; + g_tagSurface = nullptr; return DDERR_GENERIC; } } @@ -507,11 +505,6 @@ namespace DDraw return DD_OK; } - template HRESULT RealPrimarySurface::create(CompatRef); - template HRESULT RealPrimarySurface::create(CompatRef); - template HRESULT RealPrimarySurface::create(CompatRef); - template HRESULT RealPrimarySurface::create(CompatRef); - void RealPrimarySurface::destroyDefaultPrimary() { if (g_defaultPrimary) @@ -594,6 +587,10 @@ namespace DDraw } createDefaultPrimary(); + if (!g_defaultPrimary && g_frontBuffer && FAILED(g_frontBuffer->IsLost(g_frontBuffer))) + { + restore(); + } updatePresentationWindowPos(); auto src(g_isDelayedFlipPending ? g_lastFlipSurface->getDDS() : DDraw::PrimarySurface::getPrimary()); @@ -678,12 +675,21 @@ namespace DDraw HRESULT RealPrimarySurface::restore() { DDraw::ScopedThreadLock lock; - HRESULT result = g_frontBuffer->Restore(g_frontBuffer); - if (SUCCEEDED(result)) + if (g_defaultPrimary) { - 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::from(dd.get())); } void RealPrimarySurface::scheduleUpdate() diff --git a/DDrawCompat/DDraw/RealPrimarySurface.h b/DDrawCompat/DDraw/RealPrimarySurface.h index a1f4f1f..4d0ef4b 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.h +++ b/DDrawCompat/DDraw/RealPrimarySurface.h @@ -12,9 +12,7 @@ namespace DDraw class RealPrimarySurface { public: - template - static HRESULT create(CompatRef dd); - + static HRESULT create(CompatRef dd); static void destroyDefaultPrimary(); static HRESULT flip(CompatPtr surfaceTargetOverride, DWORD flags); static int flush(); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp index 60dcc1c..6f00b87 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -63,7 +63,7 @@ namespace DDraw g_monitorRect.right = g_monitorRect.left + dm.dwWidth; g_monitorRect.bottom = g_monitorRect.top + dm.dwHeight; - HRESULT result = RealPrimarySurface::create(dd); + HRESULT result = RealPrimarySurface::create(*CompatPtr::from(&dd)); if (FAILED(result)) { return LOG_RESULT(result); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp index 3492147..1205f7e 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp @@ -244,7 +244,8 @@ namespace DDraw HRESULT result = IsLost(This); if (FAILED(result)) { - result = RealPrimarySurface::restore(); + auto realPrimary = RealPrimarySurface::getSurface(); + result = SUCCEEDED(realPrimary->IsLost(realPrimary)) ? DD_OK : RealPrimarySurface::restore(); if (SUCCEEDED(result)) { return SurfaceImpl::Restore(This);