Skip to content

Instantly share code, notes, and snippets.

@creationix
Created January 29, 2012 00:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creationix/1696353 to your computer and use it in GitHub Desktop.
Save creationix/1696353 to your computer and use it in GitHub Desktop.
Basic Linux Joystick support
local Bit = require('bit')
local FS = require('fs')
local Emitter = require('emitter')
-- http://www.mjmwired.net/kernel/Documentation/input/joystick-api.txt
function parse(buffer)
local event = {
time = Bit.lshift(buffer:byte(4), 24) +
Bit.lshift(buffer:byte(3), 16) +
Bit.lshift(buffer:byte(2), 8) +
buffer:byte(1),
number = buffer:byte(8),
value = Bit.lshift(buffer:byte(6), 8) +
buffer:byte(5)
}
local type = buffer:byte(7)
if Bit.band(type, 0x80) > 0 then event.init = true end
if Bit.band(type, 0x01) > 0 then event.type = "button" end
if Bit.band(type, 0x02) > 0 then event.type = "axis" end
return event
end
-- Expose as a nice Lua API
local Joystick = Emitter:extend()
function Joystick.prototype:initialize(id)
self:wrap("on_open")
self:wrap("on_read")
self.id = id
FS.open("/dev/input/js" .. id, "r", "0644", self.on_open)
end
-- Register a bound version of a method and route errors
function Joystick.prototype:wrap(name)
local fn = self[name]
self[name] = function (err, ...)
if (err) then return self:emit("error", err) end
return fn(self, ...)
end
end
function Joystick.prototype:on_open(fd)
self.fd = fd
self:start_read()
end
function Joystick.prototype:start_read()
FS.read(self.fd, null, 8, self.on_read);
end
function Joystick.prototype:on_read(chunk)
local event = parse(chunk)
event.id = self.id
self:emit(event.type, event)
if self.fd then self:start_read() end
end
function Joystick.prototype:close(callback)
FS.close(self.fd, callback)
self.fd = nil
end
--------------------------------------------------------------------------------
-- Sample usage
local js = Joystick:new(1)
js:on('button', p);
js:on('axis', p);
-- Close after 5 seconds
--require('timer'):set_timeout(5000, function ()
-- js:close()
--end);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment