1
0
Fork 0
mirror of https://github.com/Reuh/ubiquitousse.git synced 2025-10-27 17:19:31 +00:00

Added uqt.input for ctrulua and other stuff

This commit is contained in:
Reuh 2016-12-25 21:05:10 +01:00
parent 42738cc7c9
commit c0db856b82
7 changed files with 430 additions and 81 deletions

View file

@ -10,6 +10,7 @@ local version = "0.0.1"
local uqt = require((...):match("^(.-ubiquitousse)%."))
local ctr = require("ctr")
local gfx = require("ctr.gfx")
local hid = require("ctr.hid")
-- Version compatibility warning
do
@ -31,12 +32,17 @@ do
end
-- Redefine all functions in tbl which also are in toAdd, so when used they call the old function (in tbl) and then the new (in toAdd).
-- Functions with names prefixed by a exclamation mark will overwrite the old function.
local function add(tbl, toAdd)
for k,v in pairs(toAdd) do
local old = tbl[k]
tbl[k] = function(...)
old(...)
return v(...)
if k:sub(1,1) == "!" then
tbl[k] = v
else
tbl[k] = function(...)
old(...)
return v(...)
end
end
end
end
@ -57,4 +63,263 @@ add(uqt.time, {
})
end
-- uqt.input: TODO
-- uqt.input
if uqt.input then
local keys = {}
local touchX, touchY, dTouchX, dTouchY
add(uqt.input, {
update = function()
hid.read()
keys = hid.keys()
local nTouchX, nTouchY = hid.touch()
dTouchX, dTouchY = nTouchX - touchX, nTouchY - touchY
touchX, touchY = nTouchX, nTouchY
end,
buttonDetector = function(...)
local ret = {}
for _,id in ipairs({...}) do
-- Keys
if id:match("^key%.") then
local key = id:match("^key%.(.+)$")
table.insert(ret, function()
return keys.held[key]
end)
else
error("Unknown button identifier: "..id)
end
end
return unpack(ret)
end,
axisDetector = function(...)
local ret = {}
for _,id in ipairs({...}) do
-- Binary axis
if id:match(".+%,.+") then
local d1, d2 = uqt.input.buttonDetector(id:match("^(.+)%,(.+)$"))
table.insert(ret, function()
local b1, b2 = d1(), d2()
if b1 and b2 then return 0
elseif b1 then return -1
elseif b2 then return 1
else return 0 end
end)
-- Touch movement
elseif id:match("^touch%.move%.") then
local axis, threshold = id:match("^touch%.move%.(.+)%%(.+)$")
if not axis then axis = id:match("^touch%.move%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, function()
local val, raw, max
if axis == "x" then
raw, max = dTouchX, gfx.BOTTOM_WIDTH
elseif axis == "y" then
raw, max = dTouchY, gfx.BOTTOM_HEIGHT
end
val = raw / max
return math.abs(val) > math.abs(threshold) and val or 0, raw, max
end)
-- Touch position
elseif id:match("^touch%.position%.") then
local axis, threshold = id:match("^touch%.position%.(.+)%%(.+)$")
if not axis then axis = id:match("^touch%.position%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, function()
local val, raw, max
if axis == "x" then
max = gfx.BOTTOM_WIDTH / 2 -- /2 because x=0,y=0 is the center of the screen (an axis value is in [-1,1])
raw = touchX - max
elseif axis == "y" then
max = gfx.BOTTOM_HEIGHT / 2
raw = touchY - max
end
val = raw / max
return math.abs(val) > math.abs(threshold) and val or 0, raw, max
end)
-- Circle pad axis
elseif id:match("^circle%.") then
local axis, threshold = id:match("^circle%.(.+)%%(.+)$")
if not axis then axis = id:match("^circle%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, function()
local x, y = hid.circle()
local val, raw, max = 0, 0, 156
if axis == "x" then raw = x
elseif axis == "y" then raw = y end
val = raw / max
return math.abs(val) > math.abs(threshold) and val or 0, raw, max
end)
-- C-Stick axis
elseif id:match("^cstick%.") then
local axis, threshold = id:match("^cstick%.(.+)%%(.+)$")
if not axis then axis = id:match("^cstick%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, function()
local x, y = hid.cstick()
local val, raw, max = 0, 0, 146
if axis == "x" then raw = x
elseif axis == "y" then raw = y end
val = raw / max
return math.abs(val) > math.abs(threshold) and val or 0, raw, max
end)
-- Accelerometer axis
elseif id:match("^accel%.") then
local axis, threshold = id:match("^accel%.(.+)%%(.+)$")
if not axis then axis = id:match("^accel%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, function()
local x, y, z = hid.accel()
local val, raw, max = 0, 0, 32768 -- no idea actually, but it's a s16
if axis == "x" then raw = x
elseif axis == "y" then raw = y
elseif axis == "z" then raw = z end
val = raw / max
return math.abs(val) > math.abs(threshold) and val or 0, raw, max
end)
-- Gyroscope axis
elseif id:match("^gyro%.") then
local axis, threshold = id:match("^gyro%.(.+)%%(.+)$")
if not axis then axis = id:match("^gyro%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, function()
local roll, pitch, yaw = hid.gyro()
local val, raw, max = 0, 0, 32768 -- no idea actually, but it's a s16
if axis == "roll" then raw = roll
elseif axis == "pitch" then raw = pitch
elseif axis == "yaw" then raw = yaw end
val = raw / max
return math.abs(val) > math.abs(threshold) and val or 0, raw, max
end)
else
error("Unknown axis identifier: "..id)
end
end
return unpack(ret)
end,
buttonsInUse = function(threshold)
local r = {}
for key, held in pairs(keys.held) do
if held then table.insert(r, "key."..key) end
end
return r
end,
axesInUse = function(threshold)
local r = {}
threshold = threshold or 0.5
if math.abs(touchX) / gfx.BOTTOM_WIDTH > threshold then table.insert(r, "touch.position.x%"..threshold) end
if math.abs(touchY) / gfx.BOTTOM_HEIGHT > threshold then table.insert(r, "touch.position.y%"..threshold) end
if math.abs(dTouchX) / gfx.BOTTOM_WIDTH > threshold then table.insert(r, "touch.move.x%"..threshold) end
if math.abs(dTouchY) / gfx.BOTTOM_HEIGHT > threshold then table.insert(r, "touch.move.y%"..threshold) end
local circleX, circleY = hid.circle()
if math.abs(circleX) / 156 > threshold then table.insert(r, "circle.x%"..threshold) end
if math.abs(circleY) / 156 > threshold then table.insert(r, "circle.y%"..threshold) end
if ctr.apt.isNew3DS() then
local cstickX, cstickY = hid.cstick()
if math.abs(cstickY) / 146 > threshold then table.insert(r, "cstick.y%"..threshold) end
if math.abs(cstickX) / 146 > threshold then table.insert(r, "cstick.x%"..threshold) end
end
local accelX, accelY, accelZ = hid.accel()
if math.abs(accelX) / 32768 > threshold then table.insert(r, "accel.x%"..threshold) end
if math.abs(accelY) / 32768 > threshold then table.insert(r, "accel.y%"..threshold) end
if math.abs(accelZ) / 32768 > threshold then table.insert(r, "accel.z%"..threshold) end
-- no gyro, because it is always in use
return r
end,
buttonName = function(...)
local ret = {}
for _,id in ipairs({...}) do
-- Key
if id:match("^key%.") then
local key = id:match("^key%.(.+)$")
table.insert(ret, key:sub(1,1):upper()..key:sub(2).." key")
else
table.insert(ret, id)
end
end
return unpack(ret)
end,
axisName = function(...)
local ret = {}
for _,id in ipairs({...}) do
-- Binary axis
if id:match(".+%,.+") then
local b1, b2 = uqt.input.buttonName(id:match("^(.+)%,(.+)$"))
table.insert(ret, b1.." / "..b2)
-- Touch movement
elseif id:match("^touch%.move%.") then
local axis, threshold = id:match("^touch%.move%.(.+)%%(.+)$")
if not axis then axis = id:match("^touch%.move%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, ("Touch %s movement (threshold %s%%)"):format(axis, math.abs(threshold*100)))
-- Touch position
elseif id:match("^touch%.position%.") then
local axis, threshold = id:match("^touch%.position%.(.+)%%(.+)$")
if not axis then axis = id:match("^touch%.position%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, ("Touch %s position (threshold %s%%)"):format(axis, math.abs(threshold*100)))
-- Circle pad axis
elseif id:match("^circle%.") then
local axis, threshold = id:match("^circle%.(.+)%%(.+)$")
if not axis then axis = id:match("^circle%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
if axis == "x" then
table.insert(ret, ("Circle pad horizontal axis (deadzone %s%%)"):format(math.abs(threshold*100)))
elseif axis == "y" then
table.insert(ret, ("Circle pad vertical axis (deadzone %s%%)"):format(math.abs(threshold*100)))
else
table.insert(ret, ("Circle pad %s axis (deadzone %s%%)"):format(axis, math.abs(threshold*100)))
end
-- C-Stick axis
elseif id:match("^cstick%.") then
local axis, threshold = id:match("^cstick%.(.+)%%(.+)$")
if not axis then axis = id:match("^cstick%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
if axis == "x" then
table.insert(ret, ("C-Stick horizontal axis (deadzone %s%%)"):format(math.abs(threshold*100)))
elseif axis == "y" then
table.insert(ret, ("C-Stick vertical axis (deadzone %s%%)"):format(math.abs(threshold*100)))
else
table.insert(ret, ("C-Stick %s axis (deadzone %s%%)"):format(axis, math.abs(threshold*100)))
end
-- Accelerometer axis
elseif id:match("^accel%.") then
local axis, threshold = id:match("^accel%.(.+)%%(.+)$")
if not axis then axis = id:match("^accel%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, ("Accelerometer %s axis (deadzone %s%%)"):format(axis, math.abs(threshold*100)))
-- Gyroscope axis
elseif id:match("^gyro%.") then
local axis, threshold = id:match("^gyro%.(.+)%%(.+)$")
if not axis then axis = id:match("^gyro%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, ("Gyroscope %s axis (deadzone %s%%)"):format(axis, math.abs(threshold*100)))
else
table.insert(ret, id)
end
end
return unpack(ret)
end
})
-- Defaults
uqt.input.default.pointer:bind(
{ "absolute", "key.left,key.right", "key.up,key.down" },
{ "absolute", "circle.x", "circle.y" }
)
uqt.input.default.confirm:bind("key.a")
uqt.input.default.cancel:bind("key.b")
end

View file

@ -30,12 +30,17 @@ do
end
-- Redefine all functions in tbl which also are in toAdd, so when used they call the old function (in tbl) and then the new (in toAdd).
-- Functions with names prefixed by a exclamation mark will overwrite the old function.
local function add(tbl, toAdd)
for k,v in pairs(toAdd) do
local old = tbl[k]
tbl[k] = function(...)
old(...)
return v(...)
if k:sub(1,1) == "!" then
tbl[k] = v
else
tbl[k] = function(...)
old(...)
return v(...)
end
end
end
end
@ -48,9 +53,6 @@ if uqt.event then
local updateDefault = uqt.event.update
uqt.event.update = function() end
function love.update(dt)
-- Value update
uqt.draw.fps = love.timer.getFPS()
-- Stuff defined in ubiquitousse.lua
updateDefault(dt*1000)
@ -93,6 +95,9 @@ add(uqt.draw, {
resizable = p.resizable
})
end,
fps = function()
return love.timer.getFPS()
end,
color = function(r, g, b, a)
love.graphics.setColor(r, g, b, a)
end,
@ -100,16 +105,34 @@ add(uqt.draw, {
love.graphics.setFont(defaultFont)
love.graphics.print(text, x, y)
end,
line = function(x1, y1, x2, y2)
love.graphics.line(x1, y1, x2, y2)
lineWidth = function(width)
love.graphics.setLineWidth(width)
end,
rectangle = function(x, y, width, height)
line = function(x1, y1, x2, y2, ...)
love.graphics.line(x1, y1, x2, y2, ...)
end,
polygon = function(...)
love.graphics.polygon("fill", ...)
end,
linedPolygon = function(...)
love.graphics.polygon("line", ...)
end,
["!rectangle"] = function(x, y, width, height)
love.graphics.rectangle("fill", x, y, width, height)
end,
["!linedRectangle"] = function(x, y, width, height)
love.graphics.rectangle("line", x, y, width, height)
end,
circle = function(x, y, radius)
love.graphics.circle("fill", x, y, radius)
end,
linedCircle = function(x, y, radius)
love.graphics.circle("line", x, y, radius)
end,
scissor = function(x, y, width, height)
love.graphics.setScissor(x, y, width, height)
end,
-- TODO: doc
-- TODO: cf draw.lua
image = function(filename)
local img = love.graphics.newImage(filename)
return {
@ -144,7 +167,7 @@ end
-- uqt.audio
if uqt.audio then
add(uqt.audio, {
-- TODO: doc
-- TODO: cf audio.lua
load = function(filepath)
local audio = love.audio.newSource(filepath)
return {
@ -199,18 +222,6 @@ function love.mousemoved(x, y, dx, dy)
if dx ~= 0 then axesInUse["mouse.move.x"] = dx/love.graphics.getWidth() end
if dy ~= 0 then axesInUse["mouse.move.y"] = dy/love.graphics.getHeight() end
end
-- love.wheelmoved doesn't trigger when the wheel stop moving, so we need to clear up our stuff after love.update (so in love.draw)
add(love, {
draw = function()
buttonsInUse["mouse.wheel.up"] = nil
buttonsInUse["mouse.wheel.down"] = nil
buttonsInUse["mouse.wheel.right"] = nil
buttonsInUse["mouse.wheel.left"] = nil
-- Same for mouse axis
axesInUse["mouse.move.x"] = nil
axesInUse["mouse.move.y"] = nil
end
})
function love.gamepadpressed(joystick, button)
buttonsInUse["gamepad.button."..joystick:getID().."."..button] = true
end
@ -228,6 +239,17 @@ end
love.mouse.setVisible(false)
add(uqt.input, {
-- love.wheelmoved doesn't trigger when the wheel stop moving, so we need to clear up our stuff at each update
update = function()
buttonsInUse["mouse.wheel.up"] = nil
buttonsInUse["mouse.wheel.down"] = nil
buttonsInUse["mouse.wheel.right"] = nil
buttonsInUse["mouse.wheel.left"] = nil
-- Same for mouse axis
axesInUse["mouse.move.x"] = nil
axesInUse["mouse.move.y"] = nil
end,
buttonDetector = function(...)
local ret = {}
for _,id in ipairs({...}) do
@ -356,7 +378,7 @@ add(uqt.input, {
buttonsInUse = function(threshold)
local r = {}
local threshold = threshold or 0.5
threshold = threshold or 0.5
for b in pairs(buttonsInUse) do
table.insert(r, b)
end
@ -370,7 +392,7 @@ add(uqt.input, {
axesInUse = function(threshold)
local r = {}
local threshold = threshold or 0.5
threshold = threshold or 0.5
for b,v in pairs(axesInUse) do
if math.abs(v) > threshold then
table.insert(r, b.."%"..threshold)
@ -416,7 +438,7 @@ add(uqt.input, {
table.insert(ret, ("Gamepad %s axis %s (deadzone %s%%)"):format(gid, axis, math.abs(threshold*100)))
end
else
table.insert(r, id)
table.insert(ret, id)
end
end
return unpack(ret)
@ -429,13 +451,13 @@ add(uqt.input, {
if id:match(".+%,.+") then
local b1, b2 = uqt.input.buttonName(id:match("^(.+)%,(.+)$"))
table.insert(ret, b1.." / "..b2)
-- Mouse move
-- Mouse movement
elseif id:match("^mouse%.move%.") then
local axis, threshold = id:match("^mouse%.move%.(.+)%%(.+)$")
if not axis then axis = id:match("^mouse%.move%.(.+)$") end -- no threshold (=0)
threshold = tonumber(threshold) or 0
table.insert(ret, ("Mouse %s movement (threshold %s%%)"):format(axis, math.abs(threshold*100)))
-- Mouse move
-- Mouse position
elseif id:match("^mouse%.position%.") then
local axis, threshold = id:match("^mouse%.position%.(.+)%%(.+)$")
if not axis then axis = id:match("^mouse%.position%.(.+)$") end -- no threshold (=0)
@ -458,7 +480,7 @@ add(uqt.input, {
table.insert(ret, ("Gamepad %s axis %s (deadzone %s%%)"):format(gid, axis, math.abs(threshold*100)))
end
else
table.insert(r, id)
table.insert(ret, id)
end
end
return unpack(ret)