Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[d3d9] Update software cursor position using SetCursorPosition #4670

Merged
merged 1 commit into from
Feb 8, 2025

Conversation

WinterSnowfall
Copy link
Contributor

@WinterSnowfall WinterSnowfall commented Feb 4, 2025

Fixes #3020 on Windows as well.

Games relying on software cursors apparently also call SetCursorPosition on each frame, and since we call ::SetCursorPos(X, Y) when that happens, on native Windows that tends to cause some strange movement feedback for some reason when we later retrieve the cursor position before present, using ::GetCursorPos(). And, you guessed it, this works just fine in Wine...

Regardless, what seems to work just as fine both on Windows and Wine is simply using the coordinates passed by the application with SetCursorPosition calls instead of us getting the position of the win32 cursor before present.

The downside is that if any game expects software cursors to work without it calling SetCursorPosition on each frame, it will be very very disappointed now.

Needs a bit more testing to confirm the above doesn't happen in practice. For now it has been confirmed to work on Windows and Linux with Dungeon Siege 2 at least.

@WinterSnowfall WinterSnowfall force-pushed the d3d9-swcursorwinfix branch 3 times, most recently from 52aec4f to a11894f Compare February 4, 2025 22:25
@WinterSnowfall
Copy link
Contributor Author

An operating system cursor is created and used under either of these conditions:

a) The hardware has set D3DCURSORCAPS_COLOR (see D3DCURSORCAPS), and the cursor size is 32x32 (which is the cursor size in the operating system).
b) The application is running in windowed mode.

Otherwise, DirectX uses an emulated cursor. An application uses IDirect3DDevice9::SetCursorPosition to move an emulated cursor to follow mouse movement.

D3D9 docs appear to suggest this is indeed the expected approach for emulated/software cursors, so I think we should be good here. All known games using the path still work in Wine, @Blisto91 will graciously confirm it's all fine on Windows as well (hopefully).

@Blisto91
Copy link
Contributor

Blisto91 commented Feb 7, 2025

Dungeon Siege 2, Act of War and Castle Strike seem fine on Windows with this.

@WinterSnowfall WinterSnowfall marked this pull request as ready for review February 7, 2025 19:49
@doitsujin doitsujin merged commit 13554f1 into doitsujin:master Feb 8, 2025
4 checks passed
@WinterSnowfall WinterSnowfall deleted the d3d9-swcursorwinfix branch February 8, 2025 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Dungeon Siege 2 invisible mouse cursor
3 participants