inputor

Evdev remapping utility in lua
git clone https://git.neptards.moe/u3shit/inputor.git
Log | Files | Refs

accel_wheel.lua (2101B)


      1 local fn_fw, fn_acc = ...
      2 
      3 local input = require("lib.input")
      4 local uinput = require("lib.uinput")
      5 local poll = require("lib.helper.posix_io").poll_read
      6 
      7 local inp_fwd, inp_acc = input(fn_fw), input(fn_acc)
      8 local ui = uinput()
      9 
     10 local function to_float(axis)
     11   local info = inp_acc.absinfo[axis]
     12   local min, max = info.minimum, info.maximum
     13   if min < 0 and min == -max then
     14     local mul = 1/max
     15     return function(v) return v.value * mul end
     16   else
     17     local mul = 2 / (max - min)
     18     return function(v) return (v.value + min) * mul - 1 end
     19   end
     20 end
     21 
     22 local MAP = { X = to_float("X"), Z = to_float("Z") }
     23 local AXIS = "X"
     24 local MUL = 0xffff
     25 
     26 ui:copy_caps(inp_fwd)
     27 ui:abs_setup("Z", {minimum=0,maximum=256*2-1})
     28 ui:abs_setup("RZ", {minimum=0,maximum=256*2-1})
     29 
     30 if AXIS then ui:abs_setup(AXIS, {minimum = -MUL, maximum = MUL}) end
     31 ui:setup{
     32   -- id=inp.device_id,
     33   -- some apps (like wine) doesn't like if you have multiple devices with the
     34   -- same id, in that case fake something here:
     35   id={bustype="BLUETOOTH", vendor=1, product=2},
     36   name="Virtual gamepad",
     37   ff_effects_max=inp_fwd.ff_count
     38 }
     39 
     40 ui:create()
     41 print("created", ui.sysname)
     42 inp_fwd:grab() -- ! DANGER
     43 inp_acc:grab()
     44 
     45 local to_poll = { inp_fwd, inp_acc, ui }
     46 local ui_ff = ui:gen_ff_forwarder(inp_fwd)
     47 
     48 local vals = { X = 0, Z = 0 }
     49 local function recalc()
     50   local v = math.atan2(-vals.X, -vals.Z)
     51   if v < -1 then v = -1 elseif v > 1 then v = 1 end
     52   --print(v*MUL)
     53   ui:write{type="ABS", code=AXIS, value=v*MUL}
     54 end
     55 
     56 while true do
     57   local rdy = poll(to_poll)
     58   if rdy[inp_fwd] then
     59     local rd = inp_fwd:read()
     60     if rd.type ~= "ABS" or rd.code ~= AXIS then
     61       if rd.type == "ABS" and (rd.code == "Z" or rd.code == "RZ") then
     62         rd.value = rd.value + 256
     63       end
     64       ui:write(rd)
     65     end
     66   end
     67   if rdy[ui] then ui_ff() end
     68 
     69   if rdy[inp_acc] then
     70     local rd = inp_acc:read()
     71     if rd.type == "ABS" and MAP[rd.code] then
     72       local c = rd.code
     73       vals[c] = MAP[c](rd)
     74     elseif rd.type == "SYN" and rd.code == "REPORT" and AXIS then
     75       recalc()
     76       ui:write{type="SYN", code="REPORT"}
     77     end
     78   end
     79 end