diff --git a/DDrawCompat/D3dDdi/Device.cpp b/DDrawCompat/D3dDdi/Device.cpp index 538a331..0e12ec5 100644 --- a/DDrawCompat/D3dDdi/Device.cpp +++ b/DDrawCompat/D3dDdi/Device.cpp @@ -48,8 +48,9 @@ namespace D3dDdi HRESULT Device::createPrivateResource(D3DDDIARG_CREATERESOURCE2& data) { - const bool isPalettizedOffScreen = D3DDDIFMT_P8 == data.Format && !data.Flags.Texture; - if (isPalettizedOffScreen) + const bool isPalettized = D3DDDIFMT_P8 == data.Format; + const bool isTexture = data.Flags.Texture; + if (isPalettized) { data.Format = D3DDDIFMT_L8; data.Flags.Texture = 1; @@ -59,10 +60,10 @@ namespace D3dDdi ? m_origVtable.pfnCreateResource2(m_device, &data) : m_origVtable.pfnCreateResource(m_device, reinterpret_cast(&data)); - if (isPalettizedOffScreen) + if (isPalettized) { data.Format = D3DDDIFMT_P8; - data.Flags.Texture = 0; + data.Flags.Texture = isTexture; } return result; @@ -114,6 +115,7 @@ namespace D3dDdi void Device::setGdiResourceHandle(HANDLE resource) { + LOG_FUNC("Device::setGdiResourceHandle", resource); ScopedCriticalSection lock; if ((!resource && !g_gdiResource) || (g_gdiResource && resource == *g_gdiResource)) diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index 540fd30..ea28003 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -478,6 +478,11 @@ namespace D3dDdi } } + if (D3DDDIFMT_P8 == m_fixedData.Format) + { + data.Color <<= 16; + } + prepareForBltDst(data.hResource, data.SubResourceIndex, data.DstRect); return LOG_RESULT(m_device.getOrigVtable().pfnColorFill(m_device, &data)); } @@ -924,7 +929,7 @@ namespace D3dDdi return prepareForBltDst(data.hDstResource, data.DstSubResourceIndex, data.DstRect); } - Resource& Resource::prepareForBltDst(HANDLE& resource, UINT& subResourceIndex, RECT& rect) + Resource& Resource::prepareForBltDst(HANDLE& resource, UINT subResourceIndex, RECT& rect) { if (m_lockResource) { @@ -1241,6 +1246,8 @@ namespace D3dDdi return; } + DDraw::PrimarySurface::updatePalette(); + if (isFullscreen) { g_presentationRect = calculatePresentationRect(); diff --git a/DDrawCompat/D3dDdi/Resource.h b/DDrawCompat/D3dDdi/Resource.h index 70d164f..e0bf4e8 100644 --- a/DDrawCompat/D3dDdi/Resource.h +++ b/DDrawCompat/D3dDdi/Resource.h @@ -40,7 +40,7 @@ namespace D3dDdi void onDestroyResource(HANDLE resource); Resource& prepareForBltSrc(const D3DDDIARG_BLT& data); Resource& prepareForBltDst(D3DDDIARG_BLT& data); - Resource& prepareForBltDst(HANDLE& resource, UINT& subResourceIndex, RECT& rect); + Resource& prepareForBltDst(HANDLE& resource, UINT subResourceIndex, RECT& rect); void prepareForCpuRead(UINT subResourceIndex); void prepareForCpuWrite(UINT subResourceIndex); Resource& prepareForGpuRead(UINT subResourceIndex); diff --git a/DDrawCompat/DDraw/DirectDraw.cpp b/DDrawCompat/DDraw/DirectDraw.cpp index 5ddfcb2..452f9e3 100644 --- a/DDrawCompat/DDraw/DirectDraw.cpp +++ b/DDrawCompat/DDraw/DirectDraw.cpp @@ -79,18 +79,21 @@ namespace HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags) { HRESULT result = getOrigVtable(This).SetCooperativeLevel(This, hWnd, dwFlags); - if (SUCCEEDED(result)) + if (SUCCEEDED(result) && (dwFlags & (DDSCL_FULLSCREEN | DDSCL_NORMAL))) { auto tagSurface = DDraw::TagSurface::get(*CompatPtr::from(This)); if (tagSurface) { - if (dwFlags & DDSCL_FULLSCREEN) + const bool wasFullscreen = tagSurface->isFullscreen(); + const bool isFullscreen = dwFlags & DDSCL_FULLSCREEN; + if (wasFullscreen != isFullscreen) { - tagSurface->setFullscreenWindow(hWnd); - } - else if (dwFlags & DDSCL_NORMAL) - { - tagSurface->setFullscreenWindow(nullptr); + tagSurface->setFullscreenWindow(isFullscreen ? hWnd : nullptr); + if (DDraw::RealPrimarySurface::getSurface()) + { + DDraw::RealPrimarySurface::release(); + DDraw::RealPrimarySurface::create(CompatRef(*This)); + } } } } diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index ccf1688..5244696 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -293,12 +293,9 @@ namespace g_clipper.release(); CALL_ORIG_PROC(DirectDrawCreateClipper)(0, &g_clipper.getRef(), nullptr); g_frontBuffer->SetClipper(g_frontBuffer, g_clipper); - - const bool isFlippable = 0 != (desc.ddsCaps.dwCaps & DDSCAPS_FLIP); g_surfaceDesc = desc; - g_isFullscreen = isFlippable; - if (isFlippable) + if (0 != (desc.ddsCaps.dwCaps & DDSCAPS_FLIP)) { g_frontBuffer->Flip(g_frontBuffer, getLastSurface(), DDFLIP_WAIT); D3dDdi::KernelModeThunks::waitForVsyncCounter(D3dDdi::KernelModeThunks::getVsyncCounter() + 1); @@ -341,7 +338,7 @@ namespace Input::updateCursor(); }); - if (!g_frontBuffer || !src || DDraw::RealPrimarySurface::isLost()) + if (!g_frontBuffer || !src || DDraw::RealPrimarySurface::isLost() || FAILED(src->IsLost(src))) { Gdi::Window::present(nullptr); return; @@ -381,12 +378,16 @@ namespace bool isFullscreen = false; if (SUCCEEDED(g_frontBuffer->IsLost(g_frontBuffer))) { - HWND foregroundWindow = GetForegroundWindow(); - if (foregroundWindow) + auto primary(DDraw::PrimarySurface::getPrimary()); + if (primary && SUCCEEDED(primary->IsLost(primary))) { - DWORD pid = 0; - GetWindowThreadProcessId(foregroundWindow, &pid); - isFullscreen = GetCurrentProcessId() == pid && Gdi::Window::hasFullscreenWindow(); + HWND foregroundWindow = GetForegroundWindow(); + if (foregroundWindow) + { + DWORD pid = 0; + GetWindowThreadProcessId(foregroundWindow, &pid); + isFullscreen = GetCurrentProcessId() == pid && Gdi::Window::hasFullscreenWindow(); + } } } @@ -446,11 +447,13 @@ namespace DDraw desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; desc.dwBackBufferCount = 2; + g_isFullscreen = true; CompatPtr::TCreatedSurface> surface; HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr); if (DDERR_NOEXCLUSIVEMODE == result) { + g_isFullscreen = false; desc.dwFlags = DDSD_CAPS; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; desc.dwBackBufferCount = 0; diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp index 70fd6b1..97f332f 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -255,6 +255,10 @@ namespace DDraw { if (!s_palette) { + if (DDraw::RealPrimarySurface::isFullscreen()) + { + Gdi::Palette::setHardwarePalette(Gdi::Palette::getSystemPalette().data()); + } return; } diff --git a/DDrawCompat/DDraw/Surfaces/TagSurface.h b/DDrawCompat/DDraw/Surfaces/TagSurface.h index b56f066..22e7099 100644 --- a/DDrawCompat/DDraw/Surfaces/TagSurface.h +++ b/DDrawCompat/DDraw/Surfaces/TagSurface.h @@ -20,6 +20,7 @@ namespace DDraw static bool doesFullscreenDirectDrawExist(); + bool isFullscreen() const { return m_fullscreenWindow; } void setFullscreenWindow(HWND hwnd); LONG setWindowStyle(LONG style); LONG setWindowExStyle(LONG exStyle); diff --git a/DDrawCompat/Gdi/PresentationWindow.cpp b/DDrawCompat/Gdi/PresentationWindow.cpp index fbc7253..cef30a7 100644 --- a/DDrawCompat/Gdi/PresentationWindow.cpp +++ b/DDrawCompat/Gdi/PresentationWindow.cpp @@ -21,6 +21,7 @@ namespace Gdi { HWND create(HWND owner) { + LOG_FUNC("PresentationWindow::create", owner); HWND presentationWindow = nullptr; GuiThread::execute([&]() { @@ -40,7 +41,7 @@ namespace Gdi CALL_ORIG_FUNC(SetLayeredWindowAttributes)(presentationWindow, 0, 255, LWA_ALPHA); } }); - return presentationWindow; + return LOG_RESULT(presentationWindow); } void installHooks() diff --git a/DDrawCompat/Gdi/VirtualScreen.cpp b/DDrawCompat/Gdi/VirtualScreen.cpp index 1f5ca5b..2eb417d 100644 --- a/DDrawCompat/Gdi/VirtualScreen.cpp +++ b/DDrawCompat/Gdi/VirtualScreen.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -270,6 +271,8 @@ namespace Gdi prevDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness(); prevIsFullscreen = g_isFullscreen; + + auto gdiResource = D3dDdi::Device::getGdiResource(); D3dDdi::Device::setGdiResourceHandle(nullptr); if (g_isFullscreen) @@ -307,6 +310,11 @@ namespace Gdi { SelectObject(dc.first, createDib(dc.second.useDefaultPalette)); } + + if (gdiResource && DDraw::PrimarySurface::getPrimary()) + { + D3dDdi::Device::setGdiResourceHandle(*gdiResource); + } } Gdi::Window::updateAll();