UNPKG

dualshock-controller

Version:

Eventing API layer over HID for the Sony DualShock 3 and DualShock 4 controllers

105 lines (85 loc) 3.39 kB
'use strict'; // Module dependencies. var config = require('./config'), dsutilities = require('./utilities'); //Proccess button events. var Buttons = function(controller) { var buttons = config.getControllerConfig().buttons; // convert strings to numbers, e.g. "0x01" to 0x01 // must be converted because JSON doesn't allow numbers with leading zeros buttons.forEach(function(button) { if (typeof button.buttonValue == "string") { button.buttonValue = parseInt(button.buttonValue); } if (typeof button.mask == "string") { button.mask = parseInt(button.mask); } else if (!(button.mask instanceof Number)) { button.mask = 0xFF; } //generate event name aliases: button.eventPrefixes = dsutilities.generateEventPrefixAliases(button.name); }); var buffer = {}; //Private methods var emitEvent = function(button, eventText, data) { button.eventPrefixes.forEach(function(eventPrefix) { controller.emit(eventPrefix + eventText, data); }); }; var processButton = function(button, data) { //make sure the data contains a value for the specified block //and bitwise operation for the button value var block = data[button.buttonBlock] & button.mask; var hit = (block & button.buttonValue) == button.buttonValue; var value = 0; var state = 0; // 0: up, 1: down, 2: hold // special case for the dualshock 4's dpadUp button as it causes the // lower 8 bits of it's block to be zeroed if (!button.buttonValue) { hit = !block; } // special case for dualshock 4's dpad - they are not bitmasked values as // they cannot be pressed together - ie. up, left and upleft are three // different values - upleft is not equal to up & left if (button.buttonBlock == 5 && block < 0x08) { hit = block == button.buttonValue; } if (hit) { value = 1; //if the button is in the released state. if (!buffer[button.name]) { state = 1; buffer[button.name] = true; emitEvent(button, ':press', button.name); } else { state = 2; emitEvent(button, ':hold', button.name); } //send the analog data if (button.analogPin && data[button.analogPin]) { emitEvent(button, ':analog', data[button.analogPin]); } } else if (buffer[button.name]) { //button was pressed and is not released buffer[button.name] = false; //button is no longer pressed, emit a analog 0 event. if (button.analogPin) { emitEvent(button, ':analog', 0); } //emit the released event. emitEvent(button, ':release', button.name); } if (controller[button.name]) { controller[button.name].value = value; controller[button.name].state = state; } }; // Public methods //process all the analog events. this.process = function(data) { for (var i = 0; i < buttons.length; i++) { processButton(buttons[i], data); } }; }; module.exports = Buttons;