View Issue Details

IDProjectCategoryView StatusLast Update
0004768The Dark ModCodingpublic05.07.2018 17:42
Reporterstgatilov Assigned Tostgatilov  
Status resolvedResolutionfixed 
Product VersionTDM 2.06 
Target VersionTDM 2.07Fixed in VersionTDM 2.07 
Summary0004768: Support high-DPI mouse
DescriptionMake sure that the users of high-DPI mouse(s) can interact with TDM conveniently both in-game and in the main menu.
Additional InformationHistorically, TDM has only one value of "sensitivity", which can be controlled by user, and it only affects in-game sensitivity. The sensitivity of mouse in main menu (GUI) cannot be changed at all.
This causes problems when user has an exclusively high-DPI mouse, because the mouse is too sensitive in the main menu.

As an additional problem, one existing FM (Builder's blocks) has relied on the fact that sensitivity does not affect main menu (see related isue 0004663).
TagsNo tags attached.


related to 0004663 resolvedstgatilov Mouse Sensitivity Inconsistencies Between 2.05 and 2.06 
related to 0004769 assignedduzenko Remove DirectInput --- last dependency on Windows SDK 
related to 0004665 resolvedstgatilov Mouse Sensitivity Tied to Framerate 




01.04.2018 15:10

administrator   ~0010343

Please read the related issue 0004663, it contains a very lengthy discussion about the problem.
The ideas for solutions include: second sensitivity for GUI, auto-detect sensitivity from windows, fetch absolute cursor coordinates from OS, etc.


19.06.2018 01:29

administrator   ~0010537

The suggested solutions are:

1. Add separate cvar "sensitivityGui" without menu slider, and fetch its value from Windows (SystemParametersInfo with SPI_GETMOUSESPEED). Probably it should be non-archiving cvar, so that it is reevaluated on every run, unless player has explicitly overriden it manually in .cfg-file.

2. Somehow use absolute coordinates when GUI is active. This may be a proper solution, but it needs a bit of refactoring and has more breaking potential.


19.06.2018 01:43

administrator   ~0010538

How it is handled in dhewm3:

1. In events.cpp+574, mouse events are recorded from SDL:

  res.evType = SE_MOUSE;
  res.evValue = ev.motion.xrel;
  res.evValue2 = ev.motion.yrel;

  mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
  mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));

  return res;

2. In UserInterface.cpp+344, mouse movements are scaled for menus based on resolution:

if ( event->evType == SE_MOUSE ) {
  if ( !desktop || (desktop->GetFlags() & WIN_MENUGUI) ) {
    // DG: this is a fullscreen GUI, scale the mousedelta added to cursorX/Y
    // by 640/w, because the GUI pretends that everything is 640x480
    // even if the actual resolution is higher => mouse moved too fast
    float w = renderSystem->GetScreenWidth();
    float h = renderSystem->GetScreenHeight();
    if( w <= 0.0f || h <= 0.0f ) {
      w = 640.0f;
      h = 480.0f;
    cursorX += event->evValue * (640.0f/w);
    cursorY += event->evValue2 * (480.0f/h);
  } else {
    // not a fullscreen GUI but some ingame thing - no scaling needed
    cursorX += event->evValue;
    cursorY += event->evValue2;


19.06.2018 06:24

administrator   ~0010539

Looking at SDL sources:

3. In video\windows\SDL_windowsevents.c + 478, SDL listens to WM_MOUSEMOVE event which returns absolute coordinates:

    case WM_MOUSEMOVE:
            SDL_Mouse *mouse = SDL_GetMouse();
            if (!mouse->relative_mode || mouse->relative_mode_warp) {
                SDL_MouseID mouseID = (((GetMessageExtraInfo() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) ? SDL_TOUCH_MOUSEID : 0);
                SDL_SendMouseMotion(data->window, mouseID, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
                if (isWin10FCUorNewer && mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) {
                    /* To work around 0003931, Win10 bug introduced in Fall Creators Update, where
                       SetCursorPos() (SDL_WarpMouseInWindow()) doesn't reliably generate mouse events anymore,
                       after each windows mouse event generate a fake event for the middle of the window
                       if relative_mode_warp is used */
                    int center_x = 0, center_y = 0;
                    SDL_GetWindowSize(data->window, &center_x, &center_y);
                    center_x /= 2;
                    center_y /= 2;
                    SDL_SendMouseMotion(data->window, mouseID, 0, center_x, center_y);

SDL seems to have some additional stuff like warping cursor (which breaks on newer Win10) and accumulation of subpixel movements when sensitibity is lower than 1.0. and yes, it is possible to change sensitivity as hint (separate for "normal" and "relative" modes).


19.06.2018 06:57

administrator   ~0010540

Committed the change from dhewm3 (point 2 above) in svn rev 7489.

In my opinion, this is a good change: before it horizontal mouse movement was noticeably faster than vertical movement, now they are almost equal.
The mouse speed seems the same if measured in screen pixels (but lower resolution allows you to cover the whole screen faster).
In fact, now mouse speed is a bit slow for me.

Duzenko, could you please check how is your high-DPI mouse?
I guess you also have very high resolution, so high DPI on mouse and screen are related.


20.06.2018 03:35

administrator   ~0010541

I tried also to take mouse settings from Windows control panel as described here:
It feels good with mouse acceleration: it is much easier to cover large distances with mouse.

On the other hand, it is necessary to create a cvar like sensitivityMenu to make sure that if player has problems with sensitivity, we can workaround it.

Now the question is: how to combine Control Panel settings with cvar?
Options are:
1. Apply cvar multiplier on top of adjustments made according to CP settings.
2. Cvar takes effect if it is positive. if it is -1, then Control Panels settings takes effect.


21.06.2018 04:36

administrator   ~0010545

Ok, made two more commits: svn rev 7490 and svn rev 7491.

Along with the Doom3-specific scaling fix from dhewm3 mentioned above, two more adjustments are done to mouse movement vector (in case of menu GUI):

1. OS-specific adjustments are applied using new function Sys_AdjustMouseMovement. These include: mouse sensitivity and mouse acceleration from Control Panel, and also DPI scaling in case of Windows 10.
These OS-specific adjustments can be disabled be setting cvar "sensitivityMenuOverride 1".

2. The movement is multiplied by "sensitivityMenu" cvar. I hope that it won't be necessary because point 1 should be enough. But if someone still meets big trouble with mouse in menu, he can at least tweak it manually with this cvar.

Note that among 3 commits (revs 7489-7451) the commit 7490 only adds new system function without affecting gameplay. So if the need arises to rollback these changes, rolling back 7451 and then 7489 is enough.


21.06.2018 15:11

administrator   ~0010546

The testing results for these changes are discussed here:

Issue History

Date Modified Username Field Change
01.04.2018 15:07 stgatilov New Issue
01.04.2018 15:07 stgatilov Status new => assigned
01.04.2018 15:07 stgatilov Assigned To => duzenko
01.04.2018 15:07 stgatilov Relationship added related to 0004663
01.04.2018 15:10 stgatilov Note Added: 0010343
01.04.2018 17:18 stgatilov Relationship added related to 0004769
19.06.2018 01:29 stgatilov Note Added: 0010537
19.06.2018 01:29 stgatilov Assigned To duzenko => stgatilov
19.06.2018 01:43 stgatilov Note Added: 0010538
19.06.2018 06:24 stgatilov Note Added: 0010539
19.06.2018 06:57 stgatilov Note Added: 0010540
20.06.2018 03:35 stgatilov Note Added: 0010541
21.06.2018 04:36 stgatilov Note Added: 0010545
21.06.2018 15:11 stgatilov Note Added: 0010546
21.06.2018 15:11 stgatilov Status assigned => resolved
21.06.2018 15:11 stgatilov Fixed in Version => TDM 2.07
21.06.2018 15:11 stgatilov Resolution open => fixed
05.07.2018 17:42 nbohr1more Relationship added related to 0004665