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

m_rawinput mouse trapped inside a rectangle. #1546

Open
L453rh4wk opened this issue Sep 11, 2014 · 22 comments · May be fixed by #1900
Open

m_rawinput mouse trapped inside a rectangle. #1546

L453rh4wk opened this issue Sep 11, 2014 · 22 comments · May be fixed by #1900

Comments

@L453rh4wk
Copy link

This bug only happens with the github code, not in the hl release. I've compiled the client.dll and the hl.dll and I've tested it over the beta half-life.
Every time I set m_rawinput to 1, the mouse pointer gets trapped inside a rectangle and it's impossible to aim outside that screen area.
If I set m_rawinput to 0 again, it works fine.
Here we have a video demonstration:
http://youtu.be/GmvvPiVan-A

And my system details are:
Processor Information:
Vendor: GenuineIntel
CPU Family: 0x6
CPU Model: 0x3a
CPU Stepping: 0x9
CPU Type: 0x0
Speed: 3503 Mhz
8 logical processors
4 physical processors
HyperThreading: Supported
FCMOV: Supported
SSE2: Supported
SSE3: Supported
SSSE3: Supported
SSE4a: Unsupported
SSE41: Supported
SSE42: Supported
Network Information:
Network Speed:
Operating System Version:
Windows 7 (64 bit)
NTFS: Supported
Crypto Provider Codes: Supported 311 0x0 0x0 0x0
Video Card:
Driver: NVIDIA GeForce GTX 660
DirectX Driver Name: nvd3dum.dll
Driver Version: 9.18.13.4052
DirectX Driver Version: 9.18.13.4052
Driver Date: 2 July 2014
OpenGL Version: 4.4
Desktop Color Depth: 32 bits per pixel
Monitor Refresh Rate: 60 Hz
DirectX Card: NVIDIA GeForce GTX 660
VendorID: 0x10de
DeviceID: 0x11c0
Number of Monitors: 1
Number of Logical Video Cards: 1
No SLI or Crossfire Detected
Primary Display Resolution: 1600 x 900
Desktop Resolution: 1600 x 900
Primary Display Size: 22.20" x 12.52" (25.47" diag)
56.4cm x 31.8cm (64.7cm diag)
Primary Bus: PCI Express 16x
Primary VRAM: 2047 MB
Supported MSAA Modes: 2x 4x 8x
Sound card:
Audio device: Altavoces (VIA HD Audio)
Memory:
RAM: 16341 Mb
Miscellaneous:
UI Language: English
Microphone: Not set
Media Type: Undetermined
Total Hard Disk Space Available: 433052 Mb
Largest Free Hard Disk Block: 142966 Mb
OS Install Date: dic 31 1969
Game Controller: None detected

@dtugend
Copy link
Contributor

dtugend commented Sep 11, 2014

This is a known issue, see #1377

@L453rh4wk
Copy link
Author

Thanks for your fast answer. I've applied that workaround and m_rawinput 1 worked great, but with 0, the mouse only moves to one quadrant, (x < 0, y > 0) just up, and left.

@dtugend
Copy link
Contributor

dtugend commented Sep 12, 2014

That's probably because the workaround by @Matherunner does not bother whether m_rawinput is 0 or 1. I removed the link to avoid confusion for other people.
I think you should be able to figure out a proper workaround by what is posted in the issue.

Also as you can read in that issue it's just a workaround, since according to @alfred-valve the point to fix it is inside the engine. However Valve seems to be busy with other things atm, so I don't expect it to be fixed anytime soon.

@L453rh4wk
Copy link
Author

I've solved it adding a cvar check:

if (CVAR_GET_FLOAT( "m_rawinput" ))
    SDL_SetRelativeMouseMode(SDL_TRUE);

@dtugend
Copy link
Contributor

dtugend commented Sep 12, 2014

@L453rh4wk :
Does this also work when you change m_rawinput while the game is running?

I cannot check atm if IN_ActivateMouse and IN_DeactivateMouse get called when you change m_rawinput (I think they might get called, but I don't know for sure),
because they updated Steam and it needs SSE2 now for some reason :-(

@L453rh4wk
Copy link
Author

It works only if you put the command manually in the game console, because every time you return to the game the IN_ActivateMouse event is fired :P Now I'm going to try to find an smarter way to solve the issue.

@dtugend
Copy link
Contributor

dtugend commented Sep 12, 2014

Don't forget that this issue affects Linux as well it seems, however the m_rawinput cvar probably doesn't exist on Linux, it's always handled raw (1) there I think.
So you might need to use those #ifdef _WIN32 preprocessor directives and so on :-(

@L453rh4wk
Copy link
Author

I've tested the linux version of the released hl and the m_rawinput cvar exists and seems to do it's job as in windows... but in the code it's bypassed (as you said) with the preprocessor's tags... Maybe in Linux, the engine handles the game using the SDL layer in both cases (0 / 1) but using the mouse acceleration of the OS when m_rawinput is 0.

@L453rh4wk
Copy link
Author

In the code, there's a function called:

void IN_MouseMove ( float frametime, usercmd_t *cmd)

That function is executed every frame, so, at the top of the function i've added this:

#ifdef _WIN32
if (!m_bRawInput)
    SDL_SetRelativeMouseMode(SDL_FALSE);
else
#endif
    SDL_SetRelativeMouseMode(SDL_TRUE);

And now works like a charm over windows, I will try to compile it over linux and test it.

@dtugend
Copy link
Contributor

dtugend commented Sep 12, 2014

I am not sure if it's a good idea too call that function that often:

http://wiki.libsdl.org/SDL_SetRelativeMouseMode says:
This function will flush any pending mouse motion.

However according to the SDL 2.0.0 version in the hg repository nothing will happen if there is no change in the mousemode:
http://hg.libsdl.org/SDL/file/d6a8fa507a45/src/events/SDL_mouse.c#l438

     if (enabled == mouse->relative_mode) {
         return 0;
     }

So meaning I guess you can do what you do and it will work, though from my point of view it's not a good idea semantically.
However my opinion doesn't matter that much, since I could suggest a fix myself if I wanted it a specific way :D

Btw.: You should consider a pull-request with the fix in case it works. Otherwise if someone doesn't fix it that issue will pop up again and again in the tracker.

@dtugend
Copy link
Contributor

dtugend commented Sep 12, 2014

I just noticed s.th. awkward that might take that whole mouse problems to a new level:
Search the repository for iMouseInUse

@dtugend
Copy link
Contributor

dtugend commented Sep 12, 2014

Hm, I am still not sure if it's a good idea the way it is now with your suggested fix. Because the VGUI mouse might be affected by that :S What I mean is for the VGUI it needs to be in absolute mouse mode, meaning it should have to react to IN_ActivateMouse and IN_DeactivateMouse somehow.

The other problem I see, which I meant above, is code in the client DLL that works with absolute mouse coordinates, which maybe might cause trouble when SDL_SetRelativeMouseMode is on SDL_TRUE.
(Example would be SDL_GetCursorPos in in_camera.cpp, which additionally is different for ricochet and dmc from the Half-Life client DLL).
Surprisingly thirdperson somewhat works with m_rawinput 1 in the original Half-Life (at least in Wine), not sure what the engine does in the background.

Maybe we should focus on fixing m_rawinput 1 without breaking the VGUI and care about the thirdperson code in in_camera.cpp later.

Btw another question, which you might be able to answer since you are smarter than me:
The ricochet code in this repository does not match the ricochet that is in Steam, does it? For example the ricochet in the repository would allow thirdperson, the one in Steam seems not to allow it.

@dtugend
Copy link
Contributor

dtugend commented Sep 12, 2014

I am sorry about the confusion with the VGUI.
You should be fine because IN_MouseMove is only called when mouseactive is 1

@L453rh4wk
Copy link
Author

I've studied the code more deeply and SDL does the same work over linux as in windows. When raw input is 1 it blocks the mouse pointer and sends the mouse movement direction to the opengl world (mouse is "active"). If you set the raw input to 0, SDL will use the pointer's direction from the OS that does the same job, it blocks the pointer and sends the movement's direction to SDL applying the default acceleration curve generating that strange feeling when you aim. When you switch to the vgui, mouse is "not active" and SDL sends real x,y coordinates because you are in a 2D plane using the window's coordinates.
The problem begins when you turn on the raw input and you forget to tell to SDL that he needs to block the mouse position. In this case, it will use the windows coordinates and the player's view get stucked inside the window's limit (a rectangle). In the same way, if you block the mouse pointer, and put the cvar in 0, SDL will send the direction of a blocked mouse.

The ifdef tags in the code, i suppose that appear due the pointer handling is different in windows than in linux.

Now I've tried with this code and works fine over windows, tomorrow I going to test in linux.
Near the top of the file i've defined a variable to block the SDL_SetRelativeMouseMode spam

#ifdef _WIN32
    SDL_bool mouseRelative = SDL_TRUE;
#endif

then in IN_ActivateMouse

#ifdef _WIN32
    if (!m_bRawInput)
    {
        SDL_SetRelativeMouseMode(SDL_FALSE);
        mouseRelative = SDL_FALSE;
    }
    else
    {
        mouseRelative = SDL_TRUE;
                SDL_SetRelativeMouseMode(SDL_TRUE);
    }
#else
               SDL_SetRelativeMouseMode(SDL_TRUE);
#endif

then in IN_DeactivateMouse

#ifdef _WIN32
    if (m_bRawInput)
    {
        mouseRelative = SDL_FALSE;
    }

#endif
        SDL_SetRelativeMouseMode(SDL_FALSE);

finally inside IN_MouseMove

#ifdef _WIN32
    if (!m_bRawInput && mouseRelative)
    {
        SDL_SetRelativeMouseMode(SDL_FALSE);
        mouseRelative = SDL_FALSE;
    }
    else if (m_bRawInput && !mouseRelative)
    {
        SDL_SetRelativeMouseMode(SDL_TRUE);
        mouseRelative = SDL_TRUE;
    }
#endif

@L453rh4wk
Copy link
Author

Confirmed, it seems to work on linux too.

@dtugend
Copy link
Contributor

dtugend commented Sep 13, 2014

This fix looks very good.

The only thing I am worried about is calls to the Half-Life / dmc / ricochet client.dll functions SDL_GetCursorPos and SDL_SetCursorPos (in_camera.cpp).
While the Half-Life client.dll SDL_GetCursorPos uses gEngfuncs.GetMousePosition, dmc and ricochet use SDL_GetMouseState. SDL_SetCursorPos does nothing in all 3 implementations.
For some reason thirdperson seems to work in Half-Life though, both with m_rawinput 0 and 1.
I am assuming at some point the engine resets the mouse position to the center. Not sure if thirdperson would work properly in dmc and ricochet though (but it doesn't seem to be enabled in Valve's release builds of dmc and ricochet anyway).

Can you try if thirdperson works for you (be sure to compile with _DEBUG, otherwise thirdperson will only work in single player) with the modified Half-Life client.dll?

If it does please consider making a pull request with your changes.

@dtugend
Copy link
Contributor

dtugend commented Sep 13, 2014

There is a small logical oddity though in your fix:
In IN_ActivateMouse you are checking for m_bRawInput, which cannot change when the mouse is not active. A possible solution is to put a check for the cvar before that like this:

#ifdef _WIN32
    m_bRawInput = CVAR_GET_FLOAT( "m_rawinput" ) != 0;
    if (!m_bRawInput)
    {
        SDL_SetRelativeMouseMode(SDL_FALSE);
        mouseRelative = SDL_FALSE;
    }
    else
    {
        mouseRelative = SDL_TRUE;
                SDL_SetRelativeMouseMode(SDL_TRUE);
    }
#else
               SDL_SetRelativeMouseMode(SDL_TRUE);
#endif

@dtugend
Copy link
Contributor

dtugend commented Sep 13, 2014

Actually +cammousemove and +camdistance seem to be broken in the official build too anyway. So don't worry about that now, needs to be fixed separately.

@L453rh4wk
Copy link
Author

I've compiled the dmc source, disabling the debug check for thirdperson and it doesn't work well. Thirdperson seems to have a different code than in hl, and it's code was never updated because is an mp-only game and it's not used at all.
Also, I've replaced the hl's inputw32.cpp by the dmc's one and it works fine, without any fix. I think that the mouse handling code in hl's client.dll is not necessary. The m_rawinput cvar works well with the 2 values.
As Alfred said, the best way it's doing the mouse handling on the engine side. So I suppose that removing this code from the client side it's the best alternative.

@dtugend
Copy link
Contributor

dtugend commented Sep 14, 2014

Um, okay, he didn't say that actually. What he said is this:

The not seeing SDL relative mode is a bug in HL1, I'll need to add a hinting API so that mods can tell the engine they support SDL2 (rather than the older OS specific methods).

Or did I overlook s.th.?
I think if we don't fix it - Valve is not gonna fix it for a while.
I also would like to see some engine func like GetMouseDelta or s.th. like that, but I think it's not going to happen any time soon.

Did you try +cammousemove or +camdistance with the Half-Life client.dll? Those seem to be broken as I said. If you use +cammousemove or +camdistance in thirdperson the (broken) mouse handling will be in in_camera.cpp, if you use thirdperson only without these commands the mouse handling will still be inside inputw32.cpp. I am pretty sure those commands don't work the way they should.

@dtugend
Copy link
Contributor

dtugend commented Sep 14, 2014

I can understand if you don't want to submit a pull request with the changes for some reason.

In case Valve fixes the Steam client to run on CPUs without SSE2 again (which I don't see yet), I might give it a shot and use your ideas - if that is okay?

dtugend added a commit to advancedfx/halflife that referenced this issue Oct 13, 2014
Fixes ValveSoftware#1546
- fixed m_rawinput 1 mouse trapped inside a rectangle
- fixed thirdperson camera not working as it should

Fixes ValveSoftware#1558
- recoded mousethread and made it somewhat useful for very fast mouse
  movements (will reset CursorPos now) and thus also fixed some thread
  synchronization issues (hopefully)

Further fixes:
- Fixed IN_JoyMove doing nothing on Linux for ricochet client
- Limited mouse thread sleep to sane values between 0 and 1000
@fmoraw
Copy link

fmoraw commented Nov 27, 2015

Thank you. Works like charm on Linux. Haven't tested it on windows. I changed abs() to fabs() because the parameter is of the type float.

YaLTeR pushed a commit to YaLTeR/halflife that referenced this issue Jun 11, 2016
Fixes ValveSoftware#1546
- fixed m_rawinput 1 mouse trapped inside a rectangle
- fixed thirdperson camera not working as it should

Fixes ValveSoftware#1558
- recoded mousethread and made it somewhat useful for very fast mouse
  movements (will reset CursorPos now) and thus also fixed some thread
  synchronization issues (hopefully)

Further fixes:
- Fixed IN_JoyMove doing nothing on Linux for ricochet client
- Limited mouse thread sleep to sane values between 0 and 1000
@dtugend dtugend linked a pull request Aug 25, 2018 that will close this issue
MegaBrutal pushed a commit to MegaBrutal/SevenKewp that referenced this issue Mar 11, 2022
Apparently, the problem is caused by this issue:
ValveSoftware/halflife#1377

Which Solokiller has a fix for:
twhl-community/halflife-updated@92ffa23

But seems to be originated from L453rh4wk:
ValveSoftware/halflife#1546 (comment)
wootguy pushed a commit to wootguy/SevenKewp that referenced this issue Mar 12, 2022
* Make project compile on Linux

- Updated CMake files to support build on Linux
- Deleted original Linux makefiles as they are not needed since CMake is introduced
- Fixed minor problems in the code which prevented the project from compiling

It likely breaks the Windows build, but hopefully it only causes minor problems
those are easy to fix in a way that allows the project to compile on both platforms.

The Linux CMake files don't try to deploy the built libraries to the game mod
directory (people likely build in a separate environment, not where they have the
game installed).

* Explicitly link SDL2 to client library

- Added SDL2 to the list of linked libraries to client.so
Not sure if it helps anything, the library loaded without it successfully,
but it doesn't hurt either.

- Fixed symlinks to Linux and MacOS builds of SDL2
They were supposed to be symlinks and they are in Valve's repo, but in
Solokiller's fork they lost their symlink flag with this commit:
twhl-community/halflife-updated@6509102

* Port fix for getting mouse stuck in box

Apparently, the problem is caused by this issue:
ValveSoftware/halflife#1377

Which Solokiller has a fix for:
twhl-community/halflife-updated@92ffa23

But seems to be originated from L453rh4wk:
ValveSoftware/halflife#1546 (comment)

Co-authored-by: MegaBrutal <megabrutal@devcentre>
wootguy pushed a commit to wootguy/SevenKewp that referenced this issue Mar 12, 2022
* Make project compile on Linux

- Updated CMake files to support build on Linux
- Deleted original Linux makefiles as they are not needed since CMake is introduced
- Fixed minor problems in the code which prevented the project from compiling

It likely breaks the Windows build, but hopefully it only causes minor problems
those are easy to fix in a way that allows the project to compile on both platforms.

The Linux CMake files don't try to deploy the built libraries to the game mod
directory (people likely build in a separate environment, not where they have the
game installed).

* Explicitly link SDL2 to client library

- Added SDL2 to the list of linked libraries to client.so
Not sure if it helps anything, the library loaded without it successfully,
but it doesn't hurt either.

- Fixed symlinks to Linux and MacOS builds of SDL2
They were supposed to be symlinks and they are in Valve's repo, but in
Solokiller's fork they lost their symlink flag with this commit:
twhl-community/halflife-updated@6509102

* Port fix for getting mouse stuck in box

Apparently, the problem is caused by this issue:
ValveSoftware/halflife#1377

Which Solokiller has a fix for:
twhl-community/halflife-updated@92ffa23

But seems to be originated from L453rh4wk:
ValveSoftware/halflife#1546 (comment)

* Add CTriggerOnce.cpp to server library

Co-authored-by: MegaBrutal <megabrutal@devcentre>
chinese-soup pushed a commit to chinese-soup/halflife that referenced this issue Jun 28, 2022
Fixes ValveSoftware#1546
- fixed m_rawinput 1 mouse trapped inside a rectangle
- fixed thirdperson camera not working as it should

Fixes ValveSoftware#1558
- recoded mousethread and made it somewhat useful for very fast mouse
  movements (will reset CursorPos now) and thus also fixed some thread
  synchronization issues (hopefully)

Further fixes:
- Fixed IN_JoyMove doing nothing on Linux for ricochet client
- Limited mouse thread sleep to sane values between 0 and 1000
chinese-soup pushed a commit to chinese-soup/halflife that referenced this issue Jun 28, 2022
Fixes ValveSoftware#1546
- fixed m_rawinput 1 mouse trapped inside a rectangle
- fixed thirdperson camera not working as it should

Fixes ValveSoftware#1558
- recoded mousethread and made it somewhat useful for very fast mouse
  movements (will reset CursorPos now) and thus also fixed some thread
  synchronization issues (hopefully)

Further fixes:
- Fixed IN_JoyMove doing nothing on Linux for ricochet client
- Limited mouse thread sleep to sane values between 0 and 1000
YaLTeR pushed a commit to YaLTeR/halflife that referenced this issue Jun 28, 2022
Fixes ValveSoftware#1546
- fixed m_rawinput 1 mouse trapped inside a rectangle
- fixed thirdperson camera not working as it should

Fixes ValveSoftware#1558
- recoded mousethread and made it somewhat useful for very fast mouse
  movements (will reset CursorPos now) and thus also fixed some thread
  synchronization issues (hopefully)

Further fixes:
- Fixed IN_JoyMove doing nothing on Linux for ricochet client
- Limited mouse thread sleep to sane values between 0 and 1000
SmileyAG pushed a commit to SmileyAG/OpenAG that referenced this issue Dec 14, 2023
Fixes ValveSoftware/halflife#1546
- fixed m_rawinput 1 mouse trapped inside a rectangle
- fixed thirdperson camera not working as it should

Fixes ValveSoftware/halflife#1558
- recoded mousethread and made it somewhat useful for very fast mouse
  movements (will reset CursorPos now) and thus also fixed some thread
  synchronization issues (hopefully)

Further fixes:
- Fixed IN_JoyMove doing nothing on Linux for ricochet client
- Limited mouse thread sleep to sane values between 0 and 1000
SmileyAG pushed a commit to SmileyAG/OpenAG that referenced this issue Dec 14, 2023
Fixes ValveSoftware/halflife#1546
- fixed m_rawinput 1 mouse trapped inside a rectangle
- fixed thirdperson camera not working as it should

Fixes ValveSoftware/halflife#1558
- recoded mousethread and made it somewhat useful for very fast mouse
  movements (will reset CursorPos now) and thus also fixed some thread
  synchronization issues (hopefully)

Further fixes:
- Fixed IN_JoyMove doing nothing on Linux for ricochet client
- Limited mouse thread sleep to sane values between 0 and 1000
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 a pull request may close this issue.

3 participants