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?
Direct mouse input?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- Krunklehorn
- Prole
- Posts: 8
- Joined: Sat May 11, 2019 3:46 am
Direct mouse input?
Last edited by Krunklehorn on Mon Apr 13, 2020 10:55 pm, edited 2 times in total.
Re: Direct mouse input?
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
love.mouse.getX() gets the X value of cursor inside the window
love.mouse.getY() gets the Y value of cursor inside the window
- Krunklehorn
- Prole
- Posts: 8
- Joined: Sat May 11, 2019 3:46 am
Re: Direct mouse input?
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.
Re: Direct mouse input?
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.
- Krunklehorn
- Prole
- Posts: 8
- Joined: Sat May 11, 2019 3:46 am
Re: Direct mouse input?
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.
- slime
- Solid Snayke
- Posts: 3162
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Direct mouse input?
love doesn't use SDL_RenderSetLogicalSize - or any other part of SDL_Render for that matter, so that bug doesn't apply to love.
love.mouse.setRelativeMode will also make SDL use Raw Input, on Windows.
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.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.
love.mouse.setRelativeMode will also make SDL use Raw Input, on Windows.
Re: Direct mouse input?
Here's a POC of what I meant:
(edited to make zoom independent of frame rate)
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
- 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.
- Krunklehorn
- Prole
- Posts: 8
- Joined: Sat May 11, 2019 3:46 am
Re: Direct mouse input?
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)));
}
}
}
- slime
- Solid Snayke
- Posts: 3162
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Direct mouse input?
As I said, love doesn't use SDL_Render at all. That codepath is only executed when SDL_Render is used.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...
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.Code: Select all
[snip]
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 2 guests