Absolute and relative mouse movement

Usually when dealing with mouse input you want the data from the mouse in two forms, one is absolute that you might use to draw a cursor or know which part of the window/screen a user has clicked on, and the other is relative where you are only interested in how much the mouse has moved.

Currently, the MouseState only seems to report the mouse movement in the absolute form. This means anyone using the mouse to control, for example, a first person camera would find their movement limited by the size of their window/screen. I have tried playing around with the Mouse.IsCaptured property but it doesn't seem to make much difference, quite possibly because I don't know how to use it.

Am I correct in thinking that getting relative mouse input data is not possible with the Mouse/MouseState classes This is not a big problem as mouse input is only supported on Windows and there are other methods for getting the mouse input data but I am curious to know.

Cheers,
Leaf.



Answer this question

Absolute and relative mouse movement

  • Bruce Baker

    Not tried it but how about

    public void GraphicsDevice.SetCursorPosition (
    int x,
    int y,
    bool updateImmediate
    )



  • Ultrawhack

    In full screen, SetCursorPosition seems to only affect where the cursor is drawn, but the MouseState parameters are unaffected. In windowed mode, SetCursorPosition does affect the MouseState parameters. I think this is a bug. SetCursorPosition should have the same side effects on the MouseState parameters no matter what the fullscreen state is.

    As a side note, I can't even get a cursor to draw in windowed mode, but that's probably my fault.

  • Crasch

    Yeah, it doesn't do much until you set the cursor properties too - using GraphicsDevice.SetCursorProperties(), then it has the effect we're looking for. Slightly messy though...

    Cheers,
    Leaf.


  • Mainiac007

    Promit wrote:
    You can grab your window handle and platform invoke out to the Win32 API and ask it (normally WinForms handles this, but of course we don't have WinForms anymore). Under Xbox you'll always be running fullscreen, so there's no need to do it there.

    I guess that might have to be the workaround here, but it would have been nice if it was available in the framework.



  • HopeDreamsComeTrue

    I wouldn't even call it hacky. I've seen plenty of games that do it this way.

  • Harrympower

    There's also no mouse support on the 360. Any kind of windows-specific hack would be ok.
  • vkrasner

    You can grab your window handle and platform invoke out to the Win32 API and ask it (normally WinForms handles this, but of course we don't have WinForms anymore). Under Xbox you'll always be running fullscreen, so there's no need to do it there.
  • John S S

  • Matrixchyah

    As we discussed on IRC, I cannot find a way to reset the cursor position. Anyone know how to do this

  • Bradley Reynolds

    You can try hiding the mouse pointer and after you read each absolute mouse position, reset the mouse pointer back to the middle of the screen. That way each read is effectily a relative one.Yes it seemed like a hacky workaround to me too, but I'm assured that a lot of games do it this way.

    (seems there is no way to set the mouse pointer position in XNA)

    Otherwise you are stuck going back to DirectInput or writing your own wrapper of windows raw messages.



  • John Portnov

    Come to think about it, isnt that for the cursor position in the console window

  • TCK

    Please submit a bug or feature request to be able to set the mouse cursor position. I'd also appreciate any feedback about the values returned from the mouse and are they useful or what you'd expect.

    Thanks!



  • Dietz

    Well, I got it to work using that, but at nasty price.

    Int32 middleX = this.graphics.Game.Window.ClientWidth / 2;
    Int32 middleY = this.graphics.Game.Window.ClientHeight / 2;

    mouseInfo = Mouse.GetState();

    if (mouseInfo.X != middleX || mouseInfo.Y != middleY)
    {
    if (mouseInfo.X < middleX || graphics.IsFullScreen == true)
    {
    mouseX = mouseInfo.X - middleX;
    }
    else
    {
    mouseX = middleX - mouseInfo.X;
    }
    if (mouseInfo.Y < middleY || graphics.IsFullScreen == true)
    {
    mouseY = mouseInfo.Y - middleY;
    }
    else
    {
    mouseY = middleY - mouseInfo.Y;
    }
    }

    if (graphics.IsFullScreen == false)
    {
    //this is because in windowed its doing absolute to screen!
    mouseX += 128; //this happens to be the offset of my window on screen
    mouseY += 141;

    }
    //reset the cursor back to the middle of the screen
    graphics.GraphicsDevice.SetCursorPosition(middleX, middleY, true);

    This works in both full screen and windowed, but in windowed I had a problem.

    I had to add in those constants as the offset from my screen to window. I cant find a poperty/method in XNA to get the window position, or the screen dimensions.

    Any ideas




  • Dallastower

    Leaf. wrote:
    Not tried it but how about

    public void GraphicsDevice.SetCursorPosition (
    int x,
    int y,
    bool updateImmediate
    )


    That doesnt seem to do anything at all.



  • Absolute and relative mouse movement