ppy / osu-framework

A game framework written with osu! in mind.
MIT License
1.66k stars 416 forks source link

Raw input is not working correctly on touchscreen on Windows #2105

Open ekrctb opened 5 years ago

ekrctb commented 5 years ago

Device: Surface Pro (2017 model). I'm opening this issue to share my current investigation.

  1. In osuTK, GetRawInputData sometimes returns lastX, lastY both zeros while MOUSE_MOVE_ABSOLUTE. Ignoring such input seems fine.
  2. In osu!framework, I'm getting MouseStateFlags.VirtualDesktop true input and in this case a coordinate conversion currentPosition.X = (float)state.X / raw_input_resolution * screenRect.Width + screenRect.X; is applied. But this seems incorrect and Changing this to just currentPosition.X = (float)state.X seems correct. Not sure it is always the case. Can anyone test in different input devices?

By applying both fixes above, the raw input seems working.

peppy commented 5 years ago
  1. This is not the case in stable, but that is likely because of the different event flow used. I would say it's safe to ignore this, yes (any maybe check why opentk is returning it in the first place. if we can block there we should).

  2. For the VirtualDesktop case, this is how osu-stable handles it:

internal static Vector2 ToScreenCoords(RawMouse hardware)
{
    const int range = 65536;

    Rectangle screenRect = (hardware.Flags & RawMouseFlags.VirtualDesktop) > 0 ?
        VirtualScreenRect :
        new Rectangle(
            GameBase.InitialDesktopLocation.X, GameBase.InitialDesktopLocation.Y,
            GameBase.InitialDesktopResolution.Width, GameBase.InitialDesktopResolution.Height);

    return new Vector2(
        (float)hardware.LastX / range * screenRect.Width + screenRect.X,
        (float)hardware.LastY / range * screenRect.Height + screenRect.Y);
}

internal static Microsoft.Xna.Framework.Rectangle VirtualScreenRect
{
    get
    {
        return new Microsoft.Xna.Framework.Rectangle(
            GetSystemMetrics(SM_XVIRTUALSCREEN),
            GetSystemMetrics(SM_YVIRTUALSCREEN),
            GetSystemMetrics(SM_CXVIRTUALSCREEN),
            GetSystemMetrics(SM_CYVIRTUALSCREEN));
    }
}

[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int nIndex);