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

Add a way to display the mouse #36

Open
etra0 opened this issue Oct 27, 2022 · 26 comments
Open

Add a way to display the mouse #36

etra0 opened this issue Oct 27, 2022 · 26 comments
Labels
enhancement New feature or request

Comments

@etra0
Copy link
Contributor

etra0 commented Oct 27, 2022

I'm still not totally sure about this but it would be worth the discussion.

Currently, although this captures mouse input, it doesn't have any mechanism to 'force' the cursor to be displayed.
I'd like to be something like Reshade, when the Menu is open, show and capture mouse input (and blocks mouse input
from the game).

Right now I'm doing some very nasty hack for the tool I've been building for The Witcher and it kinda works,
it shows the mouse even if the game doesn't want to:

etra0/hudhook@master...temp_patches

This could work as a proof of concept I guess if we test it in more games.

@etra0 etra0 changed the title Add a way to display the mouse and lock keyboard input. Add a way to display the mouse Oct 27, 2022
@veeenu
Copy link
Owner

veeenu commented Oct 27, 2022

I used to have something similar way back when and I think it would be a good idea, because some games will definitely need it.

I don't think your solution is particularly hacky, it's definitely the "intended" way of showing a cursor. The main thing I'd change is that the decision to show the cursor should be delegated to the clients via some API. I'm not sure what that could look like yet.

@etra0
Copy link
Contributor Author

etra0 commented Oct 27, 2022

The solution is actually using ImguiRenderLoop::should_block_messages so it's up to the client to re-implement that trait in order to show the cursor. Maybe could be renamed or actually add a method for that.

@etra0
Copy link
Contributor Author

etra0 commented Oct 27, 2022

I'd also like a way for the mouse input to be totally blocked, that would require a bit of investigation, because sometimes when you click you also interact with the game and it's a bit messy. Right now my hack only displays the cursor

@veeenu
Copy link
Owner

veeenu commented Oct 27, 2022

I've kind of given up on that. Been trying to block input for DS3 and ER for years now, to absolutely no avail. Still haven't understood how to block their input flow, I've no idea where they even get the data from.

@etra0
Copy link
Contributor Author

etra0 commented Oct 27, 2022

Good thing is reshade is also open source :D I'll try some stuff when I have the time and see if a PR is possible

@Godnoken
Copy link
Contributor

I'm also very interested in finding a way to block game input completely, in all games. I'm going to investigate it over the next month if time allows.

Good thing is reshade is also open source :D I'll try some stuff when I have the time and see if a PR is possible

Are you saying that Reshade implements this behaviour?

@etra0
Copy link
Contributor Author

etra0 commented Jan 13, 2023

iirc yes it does, but I may be wrong. It's been a while since I had time to look this up.

@Godnoken
Copy link
Contributor

Interesting. I'm going to give it a download and see if it works for a wide variety of games.

@Godnoken
Copy link
Contributor

It seems to work almost flawlessly, amazing.

The only game I had a problem with so far is Stardew Valley. While game input is definitely blocked, the game 'drops' the current mouse position/inactivates when the menu comes up. Meaning - hovering elements stop showing.
All other games I tried did just fine on that part.

One other issue that isn't huge is that the in-game cursor (only the visuals) follow the hardware cursor in the Reshade menu in some games. However, game input is still blocked.

Now the question is how this magic works.. I'll update if I manage to get something working.

Could you possible try Reshade for DS3 or ER and confirm that mouse input gets blocked @veeenu?

@veeenu
Copy link
Owner

veeenu commented Jan 17, 2023

I can confirm the input gets blocked for Elden Ring! Haven't tried for DS3 but I'm ready to bet it is the same there. Now to understand how it works... 😅

@veeenu veeenu added the enhancement New feature or request label Jan 17, 2023
@Godnoken
Copy link
Contributor

Awesome. Yeah, there's a lot of interesting stuff in Reshade. The installation process is one.

Anyways - I've never done C++ so I haven't got very far with trying to understand the game input block nor how it manages to display the second cursor..

Have you had any time to look at it?

@veeenu
Copy link
Owner

veeenu commented Jan 20, 2023

Unfortunately not. Been pretty busy lately, had to cut back a bit on working on these things 😞

@etra0
Copy link
Contributor Author

etra0 commented Jan 20, 2023

FWIW I have some (a bit dirty) patches to force to show the cursor, but I haven't blocked the input yet, you can check them in https://github.com/etra0/hudhook/commits/temp_patches

@Godnoken
Copy link
Contributor

Unfortunately not. Been pretty busy lately, had to cut back a bit on working on these things 😞

No worries, I'll keep jabbing at it when I get the time too.

FWIW I have some (a bit dirty) patches to force to show the cursor, but I haven't blocked the input yet, you can check them in https://github.com/etra0/hudhook/commits/temp_patches

I actually tried your solution but I couldn't stop the mouse from flickering constantly, if I remember correctly.. Any ideas?
May have another go at it now.

@etra0
Copy link
Contributor Author

etra0 commented Jan 20, 2023

hmm, could it be because at every iteration I'm doing ShowCursor. I don't remember if I just do it once it'll show... I can check that during the weekend.

@Godnoken
Copy link
Contributor

Well, I tried it yesterday and while the cursor indeed did show up, it did not do so consistently - at the very least not on my end.
So the cursor would show up when constructed to do so (initially), but whenever it is constructed to not show up, it doesn't seem to obey. The cursor disappears but after a while it pops back up without the ShowCursor being triggered. It may be an issue from game to game, not sure.

@Godnoken
Copy link
Contributor

Godnoken commented Apr 23, 2023

Got an update on this. I've managed to block game input completely similarly to how Reshade has done it. It doesn't work fully in all games (just like Reshade).

  • As far as I have tested, all clicks or keypresses will be ignored by the game. - Won't work if the game uses its own input sys or dinput (We could fix dinput by hooking in there too..)
  • In some games, hovering elements are still not ignored - Reshade seems to manage this flawlessly, not sure how
  • In some games, the in-game cursor's movement gets ignored now (ideal) - However, Reshade hasn't figured out how to do this globally either, and per my estimations, it seems impossible to find a global solution..

hudhook_blocked_input

The issue we seem to have with the current WndProc solution is that it only gets hooked into one of the game's threads (probably always the main thread..?), which in some cases makes us miss out on messages that are handled in different threads.

I've fixed this by utilizing SetWindowsHookEx with WH_GETMESSAGE and GetMsgProc to hook into all threads inside of the game.

However, I may be wrong and that is entirely unnecessary. As far as I can tell, Reshade only hooks GetMessage and PeekMessage once and it still manages to block input like I have done. Either Reshade finds the correct thread inside the game or it is indeed hooked onto all threads as I have done.

Excuse my horribly chaotic code, but here's a working branch.
You can ignore all hooks apart from get_msg_proc as the others are currently not a part of the solution.

Let me know if you test it, intrigued to see if it works in Elden Ring or DS3 too.

@Godnoken
Copy link
Contributor

Godnoken commented Apr 23, 2023

Forgot to mention, the game input issues I have mentioned earlier in disccussions and issue are completely gone now, so that's another positive side-effect of this.

@veeenu
Copy link
Owner

veeenu commented Apr 23, 2023

That is absolutely awesome, nice find!

I'm a bit skeptical of adding a hook kind as a solution, it seems complicated and disruptive to the API. But if we manage to use SetWindowsHookEx in the initialization/deinitialization of a renderer object so that it can manage the resulting state, that should be ideal, provided it doesn't add a lot of overhead.

@Godnoken
Copy link
Contributor

Cheers! :D

Hmm, with "hook kind", do you mean the hooks in CommonHooks or SetWindowsHookEx? And the "resulting state" is referring to what exactly?

It's definitely implemented in a really ugly way right now. I'm still too inexperienced and I've been too lazy to learn what's idiomatic and generally just go with whatever seems to work, hehe.

Shall I create a pull request where we could work on this?

@veeenu
Copy link
Owner

veeenu commented Apr 24, 2023

Hmm, with "hook kind", do you mean the hooks in CommonHooks or SetWindowsHookEx? And the "resulting state" is referring to what exactly?

Yep, that one. I wouldn't add that, I'd rather have the setup/teardown of SetWindowsHookEx be done by the renderers themselves. Much like in the same spots the setting/unsetting of the wnd proc is done now.

By "resulting state" I mean the state of the message hook being active/inactive and the consequent change of flow in the application.

It's definitely implemented in a really ugly way right now. I'm still too inexperienced and I've been too lazy to learn what's idiomatic and generally just go with whatever seems to work, hehe.

Shall I create a pull request where we could work on this?

Oh sure, feel free to open one! I'd start from a fresh slate off of main though, so that we can end up with a small enough PR diff.

@Godnoken
Copy link
Contributor

Yep, that one. I wouldn't add that, I'd rather have the setup/teardown of SetWindowsHookEx be done by the renderers themselves. Much like in the same spots the setting/unsetting of the wnd proc is done now.
By "resulting state" I mean the state of the message hook being active/inactive and the consequent change of flow in the application.

Rightio, I'll look into it!

Oh sure, feel free to open one! I'd start from a fresh slate off of main though, so that we can end up with a small enough PR diff.

Cool, I'll most likely get on it first thing in the morning.

@etra0
Copy link
Contributor Author

etra0 commented Apr 24, 2023

This sound like some exciting progress! I'll check your branch in more depth as soon as I have time, as my tool could also benefit from this!

@Godnoken
Copy link
Contributor

Lovely! I've just noticed some sort of deadlock happening with the input after a while, it's most likely some fkup with the keys or the hooks. I'll look into it.

@Godnoken
Copy link
Contributor

There is most definitely a major fuck up somewhere with the input. At some point during should_block_messages, the input freezes completely in Fallout 3 and in other games I've had the in-game mouse just locking up. ALT + TAB sometimes fixes it.

I'm an übernoob when it comes to threads, pointers, mutexes etc.. I'll get the PR up tomorrow so if anyone wants to dabble with it, it'll be much appreciated :)

@etra0
Copy link
Contributor Author

etra0 commented Dec 23, 2024

hey, any reason we can dig back at this? maybe just first focus on getting the cursor stuff. I'm interested to know if such feature is valuable to see if I can take what's been done and 'formalize' it.

I'm trying to avoid to use my own personal hudhook fork to be more 'standard' haha.

EDIT: Hm, I did miss the implementation of the MessageFilter and on_wnd_proc, I think I can now implement these things on the client side. Will see how it goes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants