Direct mouse input?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Krunklehorn
Prole
Posts: 8
Joined: Sat May 11, 2019 3:46 am

Direct mouse input?

Post by Krunklehorn »

I'd like to create a top-down player rig that uses WASD to move and the mouse to aim.

The dx and dy parameters returned by love.input.mousemoved() are integer values and as such, aren't the best for this.

How would I go about getting direct access to a mouse's response? Is a more direct input path not supported by Love because it is too system dependent?

Image
Last edited by Krunklehorn on Mon Apr 13, 2020 10:55 pm, edited 2 times in total.
Flamore
Prole
Posts: 11
Joined: Sat Mar 14, 2020 10:19 pm

Re: Direct mouse input?

Post by Flamore »

You should definetly try adding player position to mouse cursor position as it would make it relative to the world.
love.mouse.getX() gets the X value of cursor inside the window
love.mouse.getY() gets the Y value of cursor inside the window
User avatar
Krunklehorn
Prole
Posts: 8
Joined: Sat May 11, 2019 3:46 am

Re: Direct mouse input?

Post by Krunklehorn »

Flamore wrote: Mon Apr 13, 2020 5:32 pm You should definetly try adding player position to mouse cursor position as it would make it relative to the world.
love.mouse.getX() gets the X value of cursor inside the window
love.mouse.getY() gets the Y value of cursor inside the window
I think you've accidentally read my post wrong. When I talk about the dx and dy parameters being in screen space, I'm referring to the fact that they're locked to whole numbers ie. a pixel-by-pixel response. What I'm looking for is a way to access mouse hardware directly and get a smoother response.
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Direct mouse input?

Post by pgimeno »

There's no way to access mouse hardware with Löve. Nor should you need to. It should suffice to transform mouse coordinates to world coordinates. The Transform object is one you can use for that, but the details depend on how you handle your view.
User avatar
Krunklehorn
Prole
Posts: 8
Joined: Sat May 11, 2019 3:46 am

Re: Direct mouse input?

Post by Krunklehorn »

pgimeno wrote: Mon Apr 13, 2020 6:21 pm There's no way to access mouse hardware with Löve. Nor should you need to. It should suffice to transform mouse coordinates to world coordinates. The Transform object is one you can use for that, but the details depend on how you handle your view.
I've corrected my post to be more specific. What I originally meant by screen space was that they're locked to whole numbers ie. pixels. What I'm looking for is a mouse response relative to the system's logical viewport. Much better quality that way.

I did some digging through the Love & SDL sources as well as the Win32 API to figure out what's going on here. Turns out some aggressive truncating went unnoticed in SDL for quite some time.

https://bugzilla.libsdl.org/show_bug.cgi?id=4811

I'm going to recompile the SDL2.dll and get back to this thread soon for anyone interested.
User avatar
slime
Solid Snayke
Posts: 3162
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Direct mouse input?

Post by slime »

love doesn't use SDL_RenderSetLogicalSize - or any other part of SDL_Render for that matter, so that bug doesn't apply to love.
Krunklehorn wrote: Mon Apr 13, 2020 8:34 pm I've corrected my post to be more specific. What I originally meant by screen space was that they're locked to whole numbers ie. pixels. What I'm looking for is a mouse response relative to the system's logical viewport. Much better quality that way.
I'm not sure what you mean exactly by wanting mouse coordinates in the logical coordinate system. They are already in the logical coordinate system, and they might get more resolution in retina/high-dpi contexts if SDL were to expose non-integer mouse coordinate APIs because then they could be in fractions of a DPI-scaled unit (i.e. they could have pixel resolution when the coordinate system is scaled to larger than a pixel). It's also worth mentioning that love and SDL have no implementation of DPI scaling on Windows at the moment. Any DPI scaling of love games on Windows is done entirely by the OS, and love and SDL have no knowledge of it.

love.mouse.setRelativeMode will also make SDL use Raw Input, on Windows.
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Direct mouse input?

Post by pgimeno »

Here's a POC of what I meant:

Code: Select all

local tf = love.math.newTransform()

-- Apply our transformation
tf:scale(5)
tf:rotate(25)
tf:translate(10, 10)

-- Find the mouse position in transformed coordinates
local aimX, aimY = tf:inverseTransformPoint(love.mouse.getPosition())

function love.mousemoved(x, y)
  -- Keep aimX, aimY up-to-date with the cursor movement
  aimX, aimY = tf:inverseTransformPoint(x, y)
end

function love.draw()
  -- Set the transform before drawing
  love.graphics.replaceTransform(tf)

  -- Drawn circle parameters
  local posX, posY = 30, 30
  local R = 20

  -- Find the vector pointing to the mouse
  local vx = aimX - posX
  local vy = aimY - posY

  love.graphics.setLineWidth(0.5)

  -- Draw grid
  for i = -199, 199, 20 do
    love.graphics.line(i, -199, i, love.graphics.getHeight())
  end
  for i = -199, 199, 20 do
    love.graphics.line(-199, i, love.graphics.getWidth(), i)
  end

  love.graphics.circle("line", posX, posY, R)

  -- Set the length of the vector to the radius of the circle
  local len = math.sqrt(vx*vx + vy*vy)
  if len > 0 then
    -- Adjust vector
    vx = vx * R / len
    vy = vy * R / len
    -- Draw the line unless the mouse is at the centre of the circle
    love.graphics.line(posX, posY,  -- from centre of circle...
      posX + vx, posY + vy)         -- in the direction of the vector
  end
end

function love.update(dt)
  -- Allow key movement: cursor keys to displace, keypad +/- to zoom
  local pressed = love.keyboard.isScancodeDown
  if pressed("escape") then return love.event.quit() end
  if pressed("left") then tf:translate(dt*10, 0) end
  if pressed("right") then tf:translate(dt*-10, 0) end
  if pressed("up") then tf:translate(0, dt*-10) end
  if pressed("down") then tf:translate(0, dt*10) end
  if pressed("kp+") then tf:scale(1.5^dt) end
  if pressed("kp-") then tf:scale(1.5^-dt) end
end
(edited to make zoom independent of frame rate)
Attachments
pointToCursor.love
(906 Bytes) Downloaded 165 times
Last edited by pgimeno on Tue Apr 14, 2020 9:53 am, edited 1 time in total.
User avatar
Krunklehorn
Prole
Posts: 8
Joined: Sat May 11, 2019 3:46 am

Re: Direct mouse input?

Post by Krunklehorn »

slime wrote: Mon Apr 13, 2020 9:46 pm love doesn't use SDL_RenderSetLogicalSize - or any other part of SDL_Render for that matter, so that bug doesn't apply to love.
Not SDL_RenderSetLogicalSize specifcally, but love.mousemoved is down the event line from SDL_RendererEventWatch. Search for SDL_MOUSEMOTION in SDL_Render.c and you'll find this from current SDL build...note the conversion to integer on every line...

Code: Select all

if (logical_w) {
                event->motion.x -= (int)(viewport.x * renderer->dpi_scale.x);
                event->motion.y -= (int)(viewport.y * renderer->dpi_scale.y);
                event->motion.x = (int)(event->motion.x / (scale.x * renderer->dpi_scale.x));
                event->motion.y = (int)(event->motion.y / (scale.y * renderer->dpi_scale.y));
                if (event->motion.xrel > 0) {
                    event->motion.xrel = SDL_max(1, (int)(event->motion.xrel / (scale.x * renderer->dpi_scale.x)));
                } else if (event->motion.xrel < 0) {
                    event->motion.xrel = SDL_min(-1, (int)(event->motion.xrel / (scale.x * renderer->dpi_scale.x)));
                }
                if (event->motion.yrel > 0) {
                    event->motion.yrel = SDL_max(1, (int)(event->motion.yrel / (scale.y * renderer->dpi_scale.y)));
                } else if (event->motion.yrel < 0) {
                    event->motion.yrel = SDL_min(-1, (int)(event->motion.yrel / (scale.y * renderer->dpi_scale.y)));
                }
            }
        }
These are the same xrel/yrel variables that love's Event.cpp reads from and are supposed to be used as floats. That's what hmk was talking about in that bugzilla post about aggressive truncation. His patch suggests a fix but I'm having issues getting it compiled. More on that soon.
User avatar
slime
Solid Snayke
Posts: 3162
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Direct mouse input?

Post by slime »

Krunklehorn wrote: Mon Apr 13, 2020 10:53 pm Not SDL_RenderSetLogicalSize specifcally, but love.mousemoved is down the event line from SDL_RendererEventWatch. Search for SDL_MOUSEMOTION in SDL_Render.c and you'll find this from current SDL build...note the conversion to integer on every line...

Code: Select all

[snip]
These are the same xrel/yrel variables that love's Event.cpp reads from and are supposed to be used as floats. That's what hmk was talking about in that bugzilla post about aggressive truncation. His patch suggests a fix but I'm having issues getting it compiled. More on that soon.
As I said, love doesn't use SDL_Render at all. That codepath is only executed when SDL_Render is used.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 4 guests