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

Restrict GDI redirection to main monitor in fullscreen mode

Fixes display issues with games not respecting surface pitch
This commit is contained in:
narzoul 2021-06-21 23:15:25 +02:00
parent 0584a0007a
commit 7dfb030ae2
9 changed files with 39 additions and 20 deletions

View File

@ -123,6 +123,7 @@ namespace D3dDdi
{ {
Gdi::Cursor::setEmulated(true); Gdi::Cursor::setEmulated(true);
} }
Gdi::VirtualScreen::setFullscreenMode(true);
} }
fixResourceData(); fixResourceData();
@ -155,6 +156,7 @@ namespace D3dDdi
{ {
if (m_origData.Flags.Primary) if (m_origData.Flags.Primary)
{ {
Gdi::VirtualScreen::setFullscreenMode(false);
Gdi::Cursor::setEmulated(false); Gdi::Cursor::setEmulated(false);
Gdi::Cursor::setMonitorClipRect({}); Gdi::Cursor::setMonitorClipRect({});
} }
@ -328,7 +330,7 @@ namespace D3dDdi
void Resource::createGdiLockResource() void Resource::createGdiLockResource()
{ {
auto gdiSurfaceDesc(Gdi::VirtualScreen::getSurfaceDesc(DDraw::RealPrimarySurface::getMonitorRect())); auto gdiSurfaceDesc(Gdi::VirtualScreen::getSurfaceDesc(DDraw::PrimarySurface::getMonitorRect()));
if (!gdiSurfaceDesc.lpSurface) if (!gdiSurfaceDesc.lpSurface)
{ {
return; return;

View File

@ -35,7 +35,7 @@ namespace
DDSURFACEDESC2 g_surfaceDesc = {}; DDSURFACEDESC2 g_surfaceDesc = {};
DDraw::IReleaseNotifier g_releaseNotifier(onRelease); DDraw::IReleaseNotifier g_releaseNotifier(onRelease);
bool g_isFullScreen = false; bool g_isFullscreen = false;
DDraw::Surface* g_lastFlipSurface = nullptr; DDraw::Surface* g_lastFlipSurface = nullptr;
bool g_isUpdatePending = false; bool g_isUpdatePending = false;
@ -49,7 +49,7 @@ namespace
void bltToPrimaryChain(CompatRef<IDirectDrawSurface7> src) void bltToPrimaryChain(CompatRef<IDirectDrawSurface7> src)
{ {
if (!g_isFullScreen) if (!g_isFullscreen)
{ {
Gdi::Window::present(*g_frontBuffer, src, *g_clipper); Gdi::Window::present(*g_frontBuffer, src, *g_clipper);
return; return;
@ -123,7 +123,7 @@ namespace
g_frontBuffer = nullptr; g_frontBuffer = nullptr;
g_clipper.release(); g_clipper.release();
g_isFullScreen = false; g_isFullscreen = false;
g_waitingForPrimaryUnlock = false; g_waitingForPrimaryUnlock = false;
g_surfaceDesc = {}; g_surfaceDesc = {};
g_monitorRect = {}; g_monitorRect = {};
@ -145,7 +145,7 @@ namespace
} }
g_surfaceDesc = desc; g_surfaceDesc = desc;
g_isFullScreen = isFlippable; g_isFullscreen = isFlippable;
g_isUpdatePending = true; g_isUpdatePending = true;
g_qpcLastUpdate = Time::queryPerformanceCounter() - Time::msToQpc(Config::delayedFlipModeTimeout); g_qpcLastUpdate = Time::queryPerformanceCounter() - Time::msToQpc(Config::delayedFlipModeTimeout);
@ -185,7 +185,7 @@ namespace
g_isUpdatePending = false; g_isUpdatePending = false;
g_waitingForPrimaryUnlock = false; g_waitingForPrimaryUnlock = false;
if (g_isFullScreen) if (g_isFullscreen)
{ {
g_frontBuffer->Flip(g_frontBuffer, getBackBuffer(), DDFLIP_WAIT); g_frontBuffer->Flip(g_frontBuffer, getBackBuffer(), DDFLIP_WAIT);
} }
@ -367,9 +367,9 @@ namespace DDraw
Dll::createThread(&updateThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL); Dll::createThread(&updateThreadProc, nullptr, THREAD_PRIORITY_TIME_CRITICAL);
} }
bool RealPrimarySurface::isFullScreen() bool RealPrimarySurface::isFullscreen()
{ {
return g_isFullScreen; return g_isFullscreen;
} }
bool RealPrimarySurface::isLost() bool RealPrimarySurface::isLost()

View File

@ -21,7 +21,7 @@ namespace DDraw
static RECT getMonitorRect(); static RECT getMonitorRect();
static CompatWeakPtr<IDirectDrawSurface7> getSurface(); static CompatWeakPtr<IDirectDrawSurface7> getSurface();
static void init(); static void init();
static bool isFullScreen(); static bool isFullscreen();
static bool isLost(); static bool isLost();
static void release(); static void release();
static HRESULT restore(); static HRESULT restore();

View File

@ -250,7 +250,7 @@ namespace DDraw
PALETTEENTRY entries[256] = {}; PALETTEENTRY entries[256] = {};
PrimarySurface::s_palette->GetEntries(s_palette, 0, 0, 256, entries); PrimarySurface::s_palette->GetEntries(s_palette, 0, 0, 256, entries);
if (RealPrimarySurface::isFullScreen()) if (RealPrimarySurface::isFullscreen())
{ {
Gdi::Palette::setHardwarePalette(entries); Gdi::Palette::setHardwarePalette(entries);
} }

View File

@ -18,7 +18,7 @@ namespace
void bltToGdi(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, void bltToGdi(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx) DWORD dwFlags, LPDDBLTFX lpDDBltFx)
{ {
if (!lpDestRect) if (!lpDestRect || DDraw::RealPrimarySurface::isFullscreen())
{ {
return; return;
} }

View File

@ -196,12 +196,10 @@ namespace Gdi
if (GetDesktopWindow() == hwnd) if (GetDesktopWindow() == hwnd)
{ {
hwnd = nullptr; hwnd = nullptr;
origin = {};
} }
else origin.x -= virtualScreenBounds.left;
{ origin.y -= virtualScreenBounds.top;
origin.x -= virtualScreenBounds.left;
origin.y -= virtualScreenBounds.top;
}
} }
compatDc.refCount = 1; compatDc.refCount = 1;

View File

@ -30,6 +30,7 @@ namespace
DWORD g_pitch = 0; DWORD g_pitch = 0;
HANDLE g_surfaceFileMapping = nullptr; HANDLE g_surfaceFileMapping = nullptr;
void* g_surfaceView = nullptr; void* g_surfaceView = nullptr;
bool g_isFullscreen = false;
HGDIOBJ g_stockBitmap = nullptr; HGDIOBJ g_stockBitmap = nullptr;
RGBQUAD g_defaultPalette[256] = {}; RGBQUAD g_defaultPalette[256] = {};
@ -226,11 +227,19 @@ namespace Gdi
update(); update();
} }
void setFullscreenMode(bool isFullscreen)
{
g_isFullscreen = isFullscreen;
update();
}
bool update() bool update()
{ {
LOG_FUNC("VirtualScreen::update"); LOG_FUNC("VirtualScreen::update");
static auto prevDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness() - 1; static auto prevDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness() - 1;
static bool prevIsFullscreen = false;
if (prevIsFullscreen == g_isFullscreen)
{ {
Compat::ScopedCriticalSection lock(g_cs); Compat::ScopedCriticalSection lock(g_cs);
if (Win32::DisplayMode::queryDisplaySettingsUniqueness() == prevDisplaySettingsUniqueness && if (Win32::DisplayMode::queryDisplaySettingsUniqueness() == prevDisplaySettingsUniqueness &&
@ -245,11 +254,20 @@ namespace Gdi
Compat::ScopedCriticalSection lock(g_cs); Compat::ScopedCriticalSection lock(g_cs);
prevDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness(); prevDisplaySettingsUniqueness = Win32::DisplayMode::queryDisplaySettingsUniqueness();
prevIsFullscreen = g_isFullscreen;
D3dDdi::Device::setGdiResourceHandle(nullptr); D3dDdi::Device::setGdiResourceHandle(nullptr);
g_region = Region(); if (g_isFullscreen)
EnumDisplayMonitors(nullptr, nullptr, addMonitorRectToRegion, reinterpret_cast<LPARAM>(&g_region)); {
GetRgnBox(g_region, &g_bounds); g_bounds = DDraw::PrimarySurface::getMonitorRect();
g_region = g_bounds;
}
else
{
g_region = Region();
EnumDisplayMonitors(nullptr, nullptr, addMonitorRectToRegion, reinterpret_cast<LPARAM>(&g_region));
GetRgnBox(g_region, &g_bounds);
}
g_bpp = Win32::DisplayMode::getBpp(); g_bpp = Win32::DisplayMode::getBpp();
g_width = g_bounds.right - g_bounds.left; g_width = g_bounds.right - g_bounds.left;

View File

@ -21,6 +21,7 @@ namespace Gdi
DDSURFACEDESC2 getSurfaceDesc(const RECT& rect); DDSURFACEDESC2 getSurfaceDesc(const RECT& rect);
void init(); void init();
void setFullscreenMode(bool isFullscreen);
bool update(); bool update();
void updatePalette(PALETTEENTRY(&palette)[256]); void updatePalette(PALETTEENTRY(&palette)[256]);
} }

View File

@ -315,7 +315,7 @@ namespace
{ {
LOG_FUNC("SetLayeredWindowAttributes", hwnd, crKey, bAlpha, dwFlags); LOG_FUNC("SetLayeredWindowAttributes", hwnd, crKey, bAlpha, dwFlags);
BOOL result = CALL_ORIG_FUNC(SetLayeredWindowAttributes)(hwnd, crKey, bAlpha, dwFlags); BOOL result = CALL_ORIG_FUNC(SetLayeredWindowAttributes)(hwnd, crKey, bAlpha, dwFlags);
if (result && DDraw::RealPrimarySurface::isFullScreen()) if (result && DDraw::RealPrimarySurface::isFullscreen())
{ {
DDraw::RealPrimarySurface::scheduleUpdate(); DDraw::RealPrimarySurface::scheduleUpdate();
} }