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

Fixed inaccurate cursor clipping in DPI unaware mode

This commit is contained in:
narzoul 2024-04-20 17:00:30 +02:00
parent c54c45a773
commit d5a44eb40c
4 changed files with 47 additions and 19 deletions

View File

@ -340,22 +340,8 @@ namespace
void setFullscreenPresentationMode(const Win32::DisplayMode::MonitorInfo& mi)
{
if (IsRectEmpty(&mi.rcDpiAware))
{
Gdi::Cursor::setEmulated(false);
Gdi::Cursor::setMonitorClipRect({});
}
else
{
auto clipRect = mi.rcEmulated;
if (!EqualRect(&mi.rcMonitor, &mi.rcReal))
{
InflateRect(&clipRect, -1, -1);
}
Gdi::Cursor::setMonitorClipRect(clipRect);
Gdi::Cursor::setEmulated(!Overlay::Steam::isOverlayOpen());
}
Gdi::Cursor::setEmulated(!IsRectEmpty(&mi.rcEmulated) && !Overlay::Steam::isOverlayOpen());
Gdi::Cursor::setMonitorClipRect(mi.rcEmulated);
}
void updateNow(CompatWeakPtr<IDirectDrawSurface7> src, bool isOverlayOnly)

View File

@ -62,9 +62,13 @@ namespace
LOG_FUNC("GetCursorInfo", pci);
Compat::ScopedCriticalSection lock(g_cs);
BOOL result = CALL_ORIG_FUNC(GetCursorInfo)(pci);
if (result && pci->hCursor == g_nullCursor)
if (result)
{
pci->hCursor = g_cursor;
if (pci->hCursor == g_nullCursor)
{
pci->hCursor = g_cursor;
}
Gdi::Cursor::clip(pci->ptScreenPos);
}
return LOG_RESULT(result);
}
@ -121,6 +125,33 @@ namespace Gdi
{
namespace Cursor
{
void clip()
{
Compat::ScopedCriticalSection lock(g_cs);
if (!IsRectEmpty(&g_monitorClipRect))
{
POINT cp = {};
CALL_ORIG_FUNC(GetCursorPos)(&cp);
if (!PtInRect(&g_monitorClipRect, cp))
{
clip(cp);
CALL_ORIG_FUNC(SetCursorPos)(cp.x, cp.y);
}
}
}
void clip(POINT& pt)
{
Compat::ScopedCriticalSection lock(g_cs);
if (!IsRectEmpty(&g_monitorClipRect))
{
pt.x = std::max(pt.x, g_monitorClipRect.left);
pt.x = std::min(pt.x, g_monitorClipRect.right);
pt.y = std::max(pt.y, g_monitorClipRect.top);
pt.y = std::min(pt.y, g_monitorClipRect.bottom);
}
}
CURSORINFO getEmulatedCursorInfo()
{
CURSORINFO ci = {};
@ -139,6 +170,7 @@ namespace Gdi
ci.hCursor = nullptr;
ci.flags = 0;
}
clip(ci.ptScreenPos);
}
return ci;

View File

@ -6,6 +6,8 @@ namespace Gdi
{
namespace Cursor
{
void clip();
void clip(POINT& pt);
CURSORINFO getEmulatedCursorInfo();
void installHooks();
bool isEmulated();

View File

@ -337,13 +337,20 @@ namespace
*lpPoint = *g_cursorPos;
return TRUE;
}
return CALL_ORIG_FUNC(GetCursorPos)(lpPoint);
BOOL result = CALL_ORIG_FUNC(GetCursorPos)(lpPoint);
if (result)
{
Gdi::Cursor::clip(*lpPoint);
}
return result;
}
BOOL WINAPI getMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax,
decltype(&GetMessageA) origGetMessage)
{
DDraw::RealPrimarySurface::setUpdateReady();
Gdi::Cursor::clip();
return origGetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
}
@ -564,6 +571,7 @@ namespace
decltype(&PeekMessageA) origPeekMessage)
{
DDraw::RealPrimarySurface::setUpdateReady();
Gdi::Cursor::clip();
BOOL result = origPeekMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
if (!g_isFrameStarted || Config::Settings::FpsLimiter::MSGLOOP != Config::fpsLimiter.get())
{