var FS = require('fs'); var EventEmitter = require('events').EventEmitter; // http://www.mjmwired.net/kernel/Documentation/input/joystick-api.txt function parse(buffer) { var event = { time: buffer.readUInt32LE(0), number: buffer[7], value: buffer.readInt16LE(4) } if (buffer[6] & 0x80) event.init = true; if (buffer[6] & 0x01) event.type = "button"; if (buffer[6] & 0x02) event.type = "axis"; return event; } // Expose as a nice JavaScript API function Joystick(id) { this.onOpen = this.onOpen.bind(this); this.onRead = this.onRead.bind(this); this.buffer = new Buffer(8); FS.open("/dev/input/js" + id, "r", this.onOpen); } Joystick.prototype = Object.create(EventEmitter.prototype, { constructor: {value: Joystick} }); Joystick.prototype.onOpen = function (err, fd) { if (err) return this.emit("error", err); this.fd = fd; this.startRead(); }; Joystick.prototype.startRead = function () { FS.read(this.fd, this.buffer, 0, 8, null, this.onRead); }; Joystick.prototype.onRead = function (err, bytesRead) { if (err) return this.emit("error", err); var event = parse(this.buffer); this.emit(event.type, event); if (this.fd) this.startRead(); }; Joystick.prototype.close = function (callback) { FS.close(this.fd, callback); this.fd = undefined; }; //////////////////////////////////////////////////////////////////////////////// // Sample usage var js = new Joystick(1); js.on('button', console.log); js.on('axis', console.log); // Close after 5 seconds setTimeout(function () { js.close(); }, 5000);