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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -315,7 +315,7 @@ namespace
{
LOG_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();
}