Skip to content

Commit

Permalink
Improved handling of mouse cursor when background render is enabled a…
Browse files Browse the repository at this point in the history
…nd the game window is in the background
  • Loading branch information
Kaldaien committed Jan 5, 2025
1 parent c743411 commit c121641
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 50 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
25.1.3.1
25.1.5
======
+ Improved handling of mouse cursor when background render is enabled and
the game window is in the background (for games that use GetCursorPos ()).

25.1.3.1
========
+ Revert 24.12.29.1's optimizations that could cause incorrect game rendering.

Expand Down
6 changes: 3 additions & 3 deletions include/SpecialK/DLL_VERSION.H
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

#define SK_YEAR 25
#define SK_MONTH 1
#define SK_DATE 3
#define SK_REV_N 1
#define SK_REV 1
#define SK_DATE 5
#define SK_REV_N 0
#define SK_REV 0

#ifndef _A2
#define _A2(a) #a
Expand Down
11 changes: 9 additions & 2 deletions include/imgui/imgui_user.inl
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,13 @@ MessageProc ( const HWND& hWnd,
return false;
};

extern
LONG_PTR
WINAPI
SK_SetClassLongPtrW (_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG_PTR dwNewLong);

LRESULT
WINAPI
ImGui_WndProcHandler ( HWND hWnd, UINT msg,
Expand Down Expand Up @@ -1132,7 +1139,7 @@ ImGui_WndProcHandler ( HWND hWnd, UINT msg,
// We have to manually call SetCursor (...), because the game
// is not using class cursors.
if (! using_class_cursor)
SetCursor (desired_cursor);
SK_SetCursor (desired_cursor);
}

return TRUE;
Expand All @@ -1146,7 +1153,7 @@ ImGui_WndProcHandler ( HWND hWnd, UINT msg,
{
game_window.real_cursor = game_window.game_cursor;

SetClassLongPtrW ( game_window.hWnd, GCLP_HCURSOR,
SK_SetClassLongPtrW ( game_window.hWnd, GCLP_HCURSOR,
(LONG_PTR)game_window.real_cursor );
}

Expand Down
47 changes: 3 additions & 44 deletions src/input/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1113,41 +1113,27 @@ GetCursorPos_Detour (LPPOINT lpPoint)
//
if (SK_WantBackgroundRender () && (! SK_IsGameWindowActive ()))
{
#if 0
POINT ptCursor = {};
SK_GetCursorPos (&ptCursor);

static POINT lastCursorPt = ptCursor;
static HWND lastFgWindow = SK_GetForegroundWindow ();
HWND FgWindow = SK_GetForegroundWindow ();

if ((lastFgWindow != FgWindow || (ptCursor.x != lastCursorPt.x ||
ptCursor.y != lastCursorPt.y)) && (WindowFromPoint (ptCursor) != game_window.hWnd))
// Also prevent mouse look from spinning like mad while the cursor is outisde the game window :)
if (!SK_ImGui_CursorWarpingCooledDown () || WindowFromPoint (ptCursor) != game_window.hWnd)
{
lastFgWindow = FgWindow;
lastCursorPt = ptCursor;
#endif

SK_Win32_Backend->markHidden (sk_win32_func::GetCursorPos);

*lpPoint = SK_ImGui_Cursor.orig_pos;
SK_ImGui_Cursor.LocalToScreen (lpPoint);

return TRUE;
#if 0
}

lastFgWindow = FgWindow;
lastCursorPt = ptCursor;
#endif
}

if (!game_window.isCursorHovering () || SK_ImGui_IsMouseRelevant())
{
//
// Compute delta mouse coordinates for games that use cursor warping (i.e. mouselook)
//
if (SK_ImGui_WantMouseCapture () || (SK_ImGui_Active () && s_GameSetCursorPosTime >= SK_timeGetTime () - kCursorWarpCooldown))
if (SK_ImGui_WantMouseCapture () || (SK_ImGui_Active () && !SK_ImGui_CursorWarpingCooledDown ()))
{
SK_Win32_Backend->markHidden (sk_win32_func::GetCursorPos);
#if 0
Expand Down Expand Up @@ -1346,8 +1332,6 @@ struct SK_MouseTimer {

int init = FALSE;
UINT timer_id = 0x68993;
HCURSOR
class_cursor = 0;
} static last_mouse;

bool
Expand All @@ -1369,23 +1353,10 @@ SK_Window_ActivateCursor (bool changed)
if (SK_ImGui_WantHWCursor ())
{
SK_SendMsgShowCursor (TRUE);

// Deliberately call SetCursor's _hooked_ function, so we can determine whether to
// activate the window using the game's cursor or our override
SetClassLongPtrW (game_window.hWnd, GCLP_HCURSOR, (LONG_PTR)last_mouse.class_cursor);
SK_SetCursor (last_mouse.class_cursor);

SK_SendMsgSetCursor (last_mouse.class_cursor);
}

else
{
// Deliberately call SetCursor's _hooked_ function, so we can determine whether to
// activate the window using the game's cursor or our override
SetClassLongPtrW (game_window.hWnd, GCLP_HCURSOR, (LONG_PTR)0);
SK_SetCursor (0);

SK_SendMsgSetCursor ((HCURSOR)0);
SK_SendMsgShowCursor (FALSE);
}

Expand Down Expand Up @@ -1419,18 +1390,6 @@ SK_Window_DeactivateCursor (bool ignore_imgui)
{
if ((! SK_IsSteamOverlayActive ()))
{
if (was_active)
{
HCURSOR cursor = //SK_GetCursor ();
(HCURSOR)GetClassLongPtrW (game_window.hWnd, GCLP_HCURSOR);

if (cursor != 0)
last_mouse.class_cursor = cursor;
}

SetClassLongPtrW (game_window.hWnd, GCLP_HCURSOR, 0);

SK_SendMsgSetCursor (0);
SK_SendMsgShowCursor (FALSE);

last_mouse.cursor = false;
Expand Down
12 changes: 12 additions & 0 deletions src/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3201,6 +3201,18 @@ GetWindowLongPtr_Marshall (
return -1;
}

LONG_PTR
WINAPI
SK_SetClassLongPtrW (_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG_PTR dwNewLong)
{
return
SetClassLongPtrW_Original != nullptr ?
SetClassLongPtrW_Original (hWnd, nIndex, dwNewLong) :
SetClassLongPtrW (hWnd, nIndex, dwNewLong);
}

DWORD
WINAPI
SetClassLongA_Detour (_In_ HWND hWnd,
Expand Down

0 comments on commit c121641

Please sign in to comment.