mirror of
https://github.com/danbulant/console-hub
synced 2026-06-18 14:01:19 +00:00
working on DS4 controller
This commit is contained in:
parent
a19487d016
commit
99d943a41a
40 changed files with 3161 additions and 41 deletions
74
controller.js
Normal file
74
controller.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
var dualShock = require('./dist/dualshock-controller/src/dualshock');
|
||||
|
||||
|
||||
var controller = dualShock({
|
||||
config: "dualshock4-generic-driver"
|
||||
});
|
||||
controller.on('error', err => console.log(err));
|
||||
|
||||
function setExtras(obj){
|
||||
controller.setExtras(obj);
|
||||
}
|
||||
var connected = false;
|
||||
controller.on('connected', () => {
|
||||
connected = true;
|
||||
});
|
||||
controller.on("disconnected", ()=>{
|
||||
connected = false;
|
||||
})
|
||||
|
||||
function isConnected(){
|
||||
return connected;
|
||||
}
|
||||
//add event handlers:
|
||||
// controller.on('left:move', data => console.log('left Moved: ' + data.x + ' | ' + data.y));
|
||||
|
||||
// controller.on('right:move', data => console.log('right Moved: ' + data.x + ' | ' + data.y));
|
||||
|
||||
// controller.on('square:press', () => console.log('square press'));
|
||||
|
||||
// controller.on('square:release', () => console.log('square release'));
|
||||
|
||||
//sixasis motion events:
|
||||
//the object returned from each of the movement events is as follows:
|
||||
//{
|
||||
// direction : values can be: 1 for right, forward and up. 2 for left, backwards and down.
|
||||
// value : values will be from 0 to 120 for directions right, forward and up and from 0 to -120 for left, backwards and down.
|
||||
//}
|
||||
|
||||
function on(event, handler){
|
||||
controller.on(event, handler);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
on,
|
||||
isConnected,
|
||||
setExtras
|
||||
}
|
||||
// controller.on('touchpad:x1:active', () => console.log('touchpad one finger active'));
|
||||
|
||||
// controller.on('touchpad:x2:active', () => console.log('touchpad two fingers active'));
|
||||
|
||||
// controller.on('touchpad:x2:inactive', () => console.log('touchpad back to single finger'));
|
||||
|
||||
// controller.on('touchpad:x1', data => console.log('touchpad x1:', data.x, data.y));
|
||||
|
||||
// controller.on('touchpad:x2', data => console.log('touchpad x2:', data.x, data.y));
|
||||
|
||||
|
||||
// //right-left movement
|
||||
// controller.on('rightLeft:motion', data => console.log(data));
|
||||
|
||||
// //forward-back movement
|
||||
// controller.on('forwardBackward:motion', data => console.log(data));
|
||||
|
||||
// //up-down movement
|
||||
// controller.on('upDown:motion', data => console.log(data));
|
||||
|
||||
// //controller status
|
||||
// //as of version 0.6.2 you can get the battery %, if the controller is connected and if the controller is charging
|
||||
// controller.on('battery:change', data => console.log(data));
|
||||
|
||||
// controller.on('connection:change', data => console.log(data));
|
||||
|
||||
// controller.on('charging:change', data => console.log(data));
|
||||
9
dist/dualshock-controller/.editorconfig
vendored
Normal file
9
dist/dualshock-controller/.editorconfig
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
6
dist/dualshock-controller/.gitignore
vendored
Normal file
6
dist/dualshock-controller/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
node_modules
|
||||
*.log
|
||||
coverage
|
||||
*.iml
|
||||
*.idea
|
||||
.DS_Store
|
||||
6
dist/dualshock-controller/.travis.yml
vendored
Normal file
6
dist/dualshock-controller/.travis.yml
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- "6.9.2"
|
||||
before_script:
|
||||
install: echo "node-hid installation will fail in travis. Overiding `npm install`"
|
||||
compiler: clang
|
||||
194
dist/dualshock-controller/README.md
vendored
Normal file
194
dist/dualshock-controller/README.md
vendored
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
node-dualshock-controller
|
||||
=========================
|
||||
[](https://travis-ci.org/rdepena/node-dualshock-controller) [](https://codeclimate.com/github/rdepena/node-dualshock-controller)
|
||||
|
||||
`dualshock-controller` Eventing API layer over HID for the Sony DualShock 3 and DualShock 4 controllers
|
||||
|
||||
## Installation:
|
||||
|
||||
#### OSX/Windows:
|
||||
|
||||
```bash
|
||||
npm install dualshock-controller
|
||||
```
|
||||
#### Linux:
|
||||
|
||||
Review the [Linux support](#linux-support) section.
|
||||
|
||||
## Using the DualShock library
|
||||
|
||||
`Important: THE CONTROLLER WILL NOT SEND ANY DATA IF YOU DO NOT PRESS THE PS BUTTON.`
|
||||
|
||||
Also, to use the touchpad, rumble and LED capabilities of the controller you
|
||||
must connect the controller to your computer using a micro-USB cable.
|
||||
|
||||
~~~~ javascript
|
||||
var dualShock = require('dualshock-controller');
|
||||
|
||||
//pass options to init the controller.
|
||||
var controller = dualShock(
|
||||
{
|
||||
//you can use a ds4 by uncommenting this line.
|
||||
//config: "dualshock4-generic-driver",
|
||||
//if the above configuration doesn't work for you,
|
||||
//try uncommenting the following line instead.
|
||||
//config: "dualshock4-alternate-driver"
|
||||
//if using ds4 comment this line.
|
||||
config: "dualShock3",
|
||||
//smooths the output from the acelerometers (moving averages) defaults to true
|
||||
accelerometerSmoothing: true,
|
||||
//smooths the output from the analog sticks (moving averages) defaults to false
|
||||
analogStickSmoothing: false
|
||||
});
|
||||
|
||||
//make sure you add an error event handler
|
||||
controller.on('error', err => console.log(err));
|
||||
|
||||
//DualShock 4 control rumble and light settings for the controller
|
||||
controller.setExtras({
|
||||
rumbleLeft: 0, // 0-255 (Rumble left intensity)
|
||||
rumbleRight: 0, // 0-255 (Rumble right intensity)
|
||||
red: 0, // 0-255 (Red intensity)
|
||||
green: 75, // 0-255 (Blue intensity)
|
||||
blue: 225, // 0-255 (Green intensity)
|
||||
flashOn: 40, // 0-255 (Flash on time)
|
||||
flashOff: 10 // 0-255 (Flash off time)
|
||||
});
|
||||
|
||||
//DualShock 3 control rumble and light settings for the controller
|
||||
controller.setExtras({
|
||||
rumbleLeft: 0, // 0-1 (Rumble left on/off)
|
||||
rumbleRight: 0, // 0-255 (Rumble right intensity)
|
||||
led: 2 // 2 | 4 | 8 | 16 (Leds 1-4 on/off, bitmasked)
|
||||
});
|
||||
|
||||
//add event handlers:
|
||||
controller.on('left:move', data => console.log('left Moved: ' + data.x + ' | ' + data.y));
|
||||
|
||||
controller.on('right:move', data => console.log('right Moved: ' + data.x + ' | ' + data.y));
|
||||
|
||||
controller.on('connected', () => console.log('connected'));
|
||||
|
||||
controller.on('square:press', ()=> console.log('square press'));
|
||||
|
||||
controller.on('square:release', () => console.log('square release'));
|
||||
|
||||
//sixasis motion events:
|
||||
//the object returned from each of the movement events is as follows:
|
||||
//{
|
||||
// direction : values can be: 1 for right, forward and up. 2 for left, backwards and down.
|
||||
// value : values will be from 0 to 120 for directions right, forward and up and from 0 to -120 for left, backwards and down.
|
||||
//}
|
||||
|
||||
//DualShock 4 TouchPad
|
||||
//finger 1 is x1 finger 2 is x2
|
||||
controller.on('touchpad:x1:active', () => console.log('touchpad one finger active'));
|
||||
|
||||
controller.on('touchpad:x2:active', () => console.log('touchpad two fingers active'));
|
||||
|
||||
controller.on('touchpad:x2:inactive', () => console.log('touchpad back to single finger'));
|
||||
|
||||
controller.on('touchpad:x1', data => console.log('touchpad x1:', data.x, data.y));
|
||||
|
||||
controller.on('touchpad:x2', data => console.log('touchpad x2:', data.x, data.y));
|
||||
|
||||
|
||||
//right-left movement
|
||||
controller.on('rightLeft:motion', data => console.log(data));
|
||||
|
||||
//forward-back movement
|
||||
controller.on('forwardBackward:motion', data => console.log(data));
|
||||
|
||||
//up-down movement
|
||||
controller.on('upDown:motion', data => console.log(data));
|
||||
|
||||
//controller status
|
||||
//as of version 0.6.2 you can get the battery %, if the controller is connected and if the controller is charging
|
||||
controller.on('battery:change', data => console.log(data));
|
||||
|
||||
controller.on('connection:change', data => console.log(data));
|
||||
|
||||
controller.on('charging:change', data => console.log(data));
|
||||
|
||||
~~~~
|
||||
|
||||
## <a name="linux-support"></a> Linux support:
|
||||
|
||||
In order to provide Rumble/Gyro and LED support for all platforms the linux specific joystick implementation has been removed. This means you will need to:
|
||||
|
||||
* [Install node-hid build requirements](#node-hid-build)
|
||||
* [Install node-hid with hidraw support](#node-hid-hidraw)
|
||||
* [create udev rules](#create-udev-rules)
|
||||
|
||||
#### <a name="node-hid-build"></a> Install node-hid build requirements
|
||||
|
||||
To build node-hid you will need to install:
|
||||
|
||||
* libudev-dev
|
||||
* libusb-1.0-0
|
||||
* libusb-1.0-0-dev
|
||||
* build-essential
|
||||
* git
|
||||
* node-gyp
|
||||
* node-pre-gyp
|
||||
|
||||
Using apt-get:
|
||||
|
||||
```bash
|
||||
sudo apt-get install libudev-dev libusb-1.0-0 libusb-1.0-0-dev build-essential git
|
||||
```
|
||||
|
||||
```bash
|
||||
npm install -g node-gyp node-pre-gyp
|
||||
```
|
||||
|
||||
#### <a name="node-hid-hidraw"></a> Install node-hid with hidraw support
|
||||
|
||||
Once you have run the installation scripts above you can install the node-dualshock module, then replace the installed node-hid with hidraw support enabled node-hid:
|
||||
|
||||
```bash
|
||||
npm install dualshock-controller
|
||||
```
|
||||
|
||||
```bash
|
||||
npm install node-hid --driver=hidraw --build-from-source
|
||||
```
|
||||
|
||||
#### <a name="create-udev-rules"></a> Create udev rules
|
||||
|
||||
You will need to create a udev rule to be able to access the hid stream as a non root user.
|
||||
|
||||
Write the following file in `/etc/udev/rules.d/61-dualshock.rules`
|
||||
|
||||
```
|
||||
SUBSYSTEM=="input", GROUP="input", MODE="0666"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0268", MODE:="666", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev"
|
||||
|
||||
SUBSYSTEM=="input", GROUP="input", MODE="0666"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="05c4", MODE:="666", GROUP="plugdev"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev"
|
||||
```
|
||||
|
||||
Reload the rules `sudo udevadm control --reload-rules`, then disconnect/connect the controller.
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Ricardo de Pena
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
35
dist/dualshock-controller/controllerConfigurations/README.md
vendored
Normal file
35
dist/dualshock-controller/controllerConfigurations/README.md
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
These json files are used to map the controller:
|
||||
=========================
|
||||
|
||||
## To add a new controller:
|
||||
Use DeviceDiscoveryHelp.js in the examples folder, using node-hid you can obtain the values you need to create a controller.json file and leverage the library to wire it up.
|
||||
|
||||
### To connect the right controller
|
||||
the vendorId and the productId need to be set to the right values, you can use node-hid to determine what these are.
|
||||
|
||||
### Analogs are mapped as:
|
||||
~~~~ js
|
||||
"analogSticks" : [
|
||||
{
|
||||
"name" : "left",
|
||||
"x" : 7,
|
||||
"y" : 6
|
||||
},
|
||||
{
|
||||
"name" : "right",
|
||||
"x" : 9,
|
||||
"y" : 8
|
||||
}
|
||||
]
|
||||
|
||||
### Buttons are usually grouped by a block but should be added as:
|
||||
|
||||
~~~~ js
|
||||
"buttons" : [
|
||||
{
|
||||
"name": name of the button used for events,
|
||||
"buttonBlock": int representing the button block,
|
||||
"buttonValue": bit value,
|
||||
"analogPin" : int representing the pin used for analog.
|
||||
},
|
||||
]
|
||||
244
dist/dualshock-controller/controllerConfigurations/dualShock3.json
vendored
Normal file
244
dist/dualshock-controller/controllerConfigurations/dualShock3.json
vendored
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
{
|
||||
"vendorId" : 1356,
|
||||
"productId" : 616,
|
||||
"analogSticks" : [
|
||||
{
|
||||
"name" : "left",
|
||||
"x" : 6,
|
||||
"y" : 7,
|
||||
"joystickXNumber" : 0,
|
||||
"joystickYNumber" : 1
|
||||
},
|
||||
{
|
||||
"name" : "right",
|
||||
"x" : 8,
|
||||
"y" : 9,
|
||||
"joystickXNumber" : 2,
|
||||
"joystickYNumber" : 3
|
||||
}
|
||||
],
|
||||
"buttons" : [
|
||||
{
|
||||
"name": "l2",
|
||||
"buttonBlock": 3,
|
||||
"buttonValue": "0x01",
|
||||
"analogPin" : 18,
|
||||
"joystickNumber": 8
|
||||
},
|
||||
{
|
||||
"name": "r2",
|
||||
"buttonBlock": 3,
|
||||
"buttonValue": "0x02",
|
||||
"analogPin" : 19,
|
||||
"joystickNumber" : 9
|
||||
},
|
||||
{
|
||||
"name": "l1",
|
||||
"buttonBlock": 3,
|
||||
"buttonValue": "0x04",
|
||||
"analogPin" : 20,
|
||||
"joystickNumber" : 10
|
||||
},
|
||||
{
|
||||
"name":"r1",
|
||||
"buttonBlock": 3,
|
||||
"buttonValue": "0x08",
|
||||
"analogPin" : 21,
|
||||
"joystickNumber" : 11
|
||||
},
|
||||
{
|
||||
"name": "triangle",
|
||||
"buttonBlock": 3,
|
||||
"buttonValue": "0x10",
|
||||
"analogPin" : 22,
|
||||
"joystickNumber" : 12
|
||||
},
|
||||
{
|
||||
"name": "circle",
|
||||
"buttonBlock": 3,
|
||||
"buttonValue": "0x20",
|
||||
"analogPin" : 23,
|
||||
"joystickNumber" : 13
|
||||
},
|
||||
{
|
||||
"name": "x",
|
||||
"buttonBlock": 3,
|
||||
"buttonValue": "0x40",
|
||||
"analogPin" : 24,
|
||||
"joystickNumber" : 14
|
||||
},
|
||||
{
|
||||
"name": "square",
|
||||
"buttonBlock": 3,
|
||||
"buttonValue": "0x80",
|
||||
"analogPin": 25,
|
||||
"joystickNumber" : 15
|
||||
},
|
||||
{
|
||||
"name": "select",
|
||||
"buttonBlock": 2,
|
||||
"buttonValue": "0x1",
|
||||
"joystickNumber" : 0
|
||||
},
|
||||
{
|
||||
"name": "leftAnalogBump",
|
||||
"buttonBlock": 2,
|
||||
"buttonValue": "0x2",
|
||||
"joystickNumber" : 1
|
||||
},
|
||||
{
|
||||
"name": "rightAnalogBump",
|
||||
"buttonBlock": 2,
|
||||
"buttonValue": "0x4",
|
||||
"joystickNumber" : 2
|
||||
},
|
||||
{
|
||||
"name": "start",
|
||||
"buttonBlock": 2,
|
||||
"buttonValue": "0x08",
|
||||
"joystickNumber" : 3
|
||||
},
|
||||
{
|
||||
"name": "dpadUp",
|
||||
"buttonBlock": 2,
|
||||
"buttonValue": "0x10",
|
||||
"analogPin": 14,
|
||||
"joystickNumber" : 4
|
||||
},
|
||||
{
|
||||
"name": "dpadRight",
|
||||
"buttonBlock": 2,
|
||||
"buttonValue": "0x20",
|
||||
"analogPin": 15,
|
||||
"joystickNumber" : 5
|
||||
},
|
||||
{
|
||||
"name": "dpadDown",
|
||||
"buttonBlock": 2,
|
||||
"buttonValue" : "0x40",
|
||||
"analogPin" : 16,
|
||||
"joystickNumber" : 6
|
||||
},
|
||||
{
|
||||
"name": "dpadLeft",
|
||||
"buttonBlock": 2,
|
||||
"buttonValue": "0x80",
|
||||
"analogPin": 17,
|
||||
"joystickNumber" : 7
|
||||
},
|
||||
{
|
||||
"name": "psxButton",
|
||||
"buttonBlock":4,
|
||||
"buttonValue": "0x01",
|
||||
"joystickNumber" : 16
|
||||
}
|
||||
],
|
||||
"motionInputs": [
|
||||
{
|
||||
"name" : "rightLeft",
|
||||
"directionPin" : 41,
|
||||
"valuePin" : 42
|
||||
},
|
||||
{
|
||||
"name" : "forwardBackward",
|
||||
"directionPin" : 43,
|
||||
"valuePin" : 44
|
||||
},
|
||||
{
|
||||
"name" : "upDown",
|
||||
"directionPin" : 45,
|
||||
"valuePin" : 46
|
||||
},
|
||||
{
|
||||
"name" : "yaw",
|
||||
"directionPin" : 47,
|
||||
"valuePin" : 48
|
||||
}
|
||||
],
|
||||
"status": [
|
||||
{
|
||||
"name" : "charging",
|
||||
"pin" : 29,
|
||||
"states" : [
|
||||
{
|
||||
"value" : 0,
|
||||
"state" : "Charging"
|
||||
},
|
||||
{
|
||||
"value" : 2,
|
||||
"state" : "Charging"
|
||||
},
|
||||
{
|
||||
"value" : 3,
|
||||
"state" : "Not Charging"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "battery",
|
||||
"pin" : 30,
|
||||
"states" : [
|
||||
{
|
||||
"value" : 238,
|
||||
"state" : "Charging"
|
||||
},
|
||||
{
|
||||
"value" : 0,
|
||||
"state" : "No charge"
|
||||
},
|
||||
{
|
||||
"value" : 1,
|
||||
"state" : "20%"
|
||||
},
|
||||
{
|
||||
"value" : 2,
|
||||
"state" : "40%"
|
||||
},
|
||||
{
|
||||
"value" : 3,
|
||||
"state" : "60%"
|
||||
},
|
||||
{
|
||||
"value" : 4,
|
||||
"state" : "80%"
|
||||
},
|
||||
{
|
||||
"value" : 5,
|
||||
"state" : "100%"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "connection",
|
||||
"pin" : 31,
|
||||
"states" : [
|
||||
{
|
||||
"value" : 18,
|
||||
"state" : "Usb"
|
||||
},
|
||||
{
|
||||
"value" : 22,
|
||||
"state" : "Bluetooth"
|
||||
},
|
||||
{
|
||||
"value" : 20,
|
||||
"state" : "Rumbling"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"output": {
|
||||
"defaultBuffer":[
|
||||
1, 0, 254, 0, 254, 0, 0, 0, 0, 0, 0,
|
||||
255, 39, 16, 0, 50, 255, 39, 16, 0, 50, 255,
|
||||
39, 16, 0, 50, 255, 39, 16, 0, 50, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0
|
||||
],
|
||||
"indexes": {
|
||||
"rumbleLeft": 3,
|
||||
"rumbleRight": 5,
|
||||
"led": 10
|
||||
}
|
||||
}
|
||||
}
|
||||
177
dist/dualshock-controller/controllerConfigurations/dualShock4-alternate-driver.json
vendored
Normal file
177
dist/dualshock-controller/controllerConfigurations/dualShock4-alternate-driver.json
vendored
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
{
|
||||
"vendorId" : 1356,
|
||||
"productId" : 2508,
|
||||
"analogSticks" : [
|
||||
{
|
||||
"name" : "left",
|
||||
"x" : 1,
|
||||
"y" : 2
|
||||
},
|
||||
{
|
||||
"name" : "right",
|
||||
"x" : 3,
|
||||
"y" : 4
|
||||
}
|
||||
],
|
||||
"buttons" : [
|
||||
{
|
||||
"name": "l2",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x04",
|
||||
"analogPin" : 8
|
||||
},
|
||||
{
|
||||
"name": "r2",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x08",
|
||||
"analogPin" : 9
|
||||
},
|
||||
{
|
||||
"name": "l1",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x01"
|
||||
},
|
||||
{
|
||||
"name": "r1",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x02"
|
||||
},
|
||||
{
|
||||
"name": "leftAnalogBump",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x04"
|
||||
},
|
||||
{
|
||||
"name": "rightAnalogBump",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x08"
|
||||
},
|
||||
{
|
||||
"name": "psxButton",
|
||||
"buttonBlock": 7,
|
||||
"buttonValue": "0x01"
|
||||
},
|
||||
{
|
||||
"name": "touchPad",
|
||||
"buttonBlock": 7,
|
||||
"buttonValue": "0x02"
|
||||
},
|
||||
{
|
||||
"name": "square",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x10"
|
||||
},
|
||||
{
|
||||
"name": "triangle",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x80"
|
||||
},
|
||||
{
|
||||
"name": "circle",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x40"
|
||||
},
|
||||
{
|
||||
"name": "x",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x20"
|
||||
},
|
||||
{
|
||||
"name": "dpadUp",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x00",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadUpRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x01",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x02",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDownRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x03",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDown",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue" : "0x04",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDownLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue" : "0x05",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x06",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadUpLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x07",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "share",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x10"
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x20"
|
||||
},
|
||||
{
|
||||
"name": "leftStick",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x40"
|
||||
},
|
||||
{
|
||||
"name": "rightStick",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x80"
|
||||
}
|
||||
],
|
||||
"motionInputs" : [],
|
||||
"status" : [],
|
||||
"output": {
|
||||
"defaultBuffer":[
|
||||
5,255,4,0,0,0,0,0,0,0,0
|
||||
],
|
||||
"indexes": {
|
||||
"rumbleLeft": 4,
|
||||
"rumbleRight": 5,
|
||||
"red": 6,
|
||||
"green": 7,
|
||||
"blue": 8,
|
||||
"flashOn": 9,
|
||||
"flashOff": 10
|
||||
}
|
||||
},
|
||||
"touchPad": [{
|
||||
"name":"x1",
|
||||
"activePin": 35,
|
||||
"dataPinA": 37,
|
||||
"dataPinB": 36,
|
||||
"dataPinC": 38
|
||||
},{
|
||||
"name": "x2",
|
||||
"activePin": 39,
|
||||
"dataPinA": 41,
|
||||
"dataPinB": 40,
|
||||
"dataPinC": 42
|
||||
}]
|
||||
}
|
||||
177
dist/dualshock-controller/controllerConfigurations/dualShock4-generic-driver.json
vendored
Normal file
177
dist/dualshock-controller/controllerConfigurations/dualShock4-generic-driver.json
vendored
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
{
|
||||
"vendorId" : 1356,
|
||||
"productId" : 1476,
|
||||
"analogSticks" : [
|
||||
{
|
||||
"name" : "left",
|
||||
"x" : 1,
|
||||
"y" : 2
|
||||
},
|
||||
{
|
||||
"name" : "right",
|
||||
"x" : 3,
|
||||
"y" : 4
|
||||
}
|
||||
],
|
||||
"buttons" : [
|
||||
{
|
||||
"name": "l2",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x04",
|
||||
"analogPin" : 8
|
||||
},
|
||||
{
|
||||
"name": "r2",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x08",
|
||||
"analogPin" : 9
|
||||
},
|
||||
{
|
||||
"name": "l1",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x01"
|
||||
},
|
||||
{
|
||||
"name": "r1",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x02"
|
||||
},
|
||||
{
|
||||
"name": "leftAnalogBump",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x04"
|
||||
},
|
||||
{
|
||||
"name": "rightAnalogBump",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x08"
|
||||
},
|
||||
{
|
||||
"name": "psxButton",
|
||||
"buttonBlock": 7,
|
||||
"buttonValue": "0x01"
|
||||
},
|
||||
{
|
||||
"name": "touchPad",
|
||||
"buttonBlock": 7,
|
||||
"buttonValue": "0x02"
|
||||
},
|
||||
{
|
||||
"name": "square",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x10"
|
||||
},
|
||||
{
|
||||
"name": "triangle",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x80"
|
||||
},
|
||||
{
|
||||
"name": "circle",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x40"
|
||||
},
|
||||
{
|
||||
"name": "x",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x20"
|
||||
},
|
||||
{
|
||||
"name": "dpadUp",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x00",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadUpRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x01",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x02",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDownRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x03",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDown",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue" : "0x04",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDownLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue" : "0x05",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x06",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadUpLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x07",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "share",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x10"
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x20"
|
||||
},
|
||||
{
|
||||
"name": "leftStick",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x40"
|
||||
},
|
||||
{
|
||||
"name": "rightStick",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x80"
|
||||
}
|
||||
],
|
||||
"motionInputs" : [],
|
||||
"status" : [],
|
||||
"output": {
|
||||
"defaultBuffer":[
|
||||
5,255,4,0,0,0,0,0,0,0,0
|
||||
],
|
||||
"indexes": {
|
||||
"rumbleLeft": 4,
|
||||
"rumbleRight": 5,
|
||||
"red": 6,
|
||||
"green": 7,
|
||||
"blue": 8,
|
||||
"flashOn": 9,
|
||||
"flashOff": 10
|
||||
}
|
||||
},
|
||||
"touchPad": [{
|
||||
"name":"x1",
|
||||
"activePin": 35,
|
||||
"dataPinA": 37,
|
||||
"dataPinB": 36,
|
||||
"dataPinC": 38
|
||||
},{
|
||||
"name": "x2",
|
||||
"activePin": 39,
|
||||
"dataPinA": 41,
|
||||
"dataPinB": 40,
|
||||
"dataPinC": 42
|
||||
}]
|
||||
}
|
||||
195
dist/dualshock-controller/controllerConfigurations/dualShock4.json
vendored
Normal file
195
dist/dualshock-controller/controllerConfigurations/dualShock4.json
vendored
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
{
|
||||
"vendorId" : 1356,
|
||||
"productId" : 1476,
|
||||
"analogSticks" : [
|
||||
{
|
||||
"name" : "left",
|
||||
"x" : 1,
|
||||
"y" : 2,
|
||||
"joystickXNumber" : 0,
|
||||
"joystickYNumber" : 1
|
||||
},
|
||||
{
|
||||
"name" : "right",
|
||||
"x" : 3,
|
||||
"y" : 4,
|
||||
"joystickXNumber" : 2,
|
||||
"joystickYNumber" : 5
|
||||
},
|
||||
{
|
||||
"name" : "l2Analog",
|
||||
"x" : 100,
|
||||
"joystickXNumber" : 3
|
||||
},
|
||||
{
|
||||
"name" : "r2Analog",
|
||||
"x" : 101,
|
||||
"joystickXNumber" : 4
|
||||
}
|
||||
],
|
||||
"buttons" : [
|
||||
{
|
||||
"name": "l2",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x04",
|
||||
"analogPin" : 8,
|
||||
"joystickNumber": 6
|
||||
},
|
||||
{
|
||||
"name": "r2",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x08",
|
||||
"analogPin" : 9,
|
||||
"joystickNumber": 7
|
||||
},
|
||||
{
|
||||
"name": "l1",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x01",
|
||||
"joystickNumber": 4
|
||||
},
|
||||
{
|
||||
"name": "r1",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x02",
|
||||
"joystickNumber": 5
|
||||
},
|
||||
{
|
||||
"name": "psxButton",
|
||||
"buttonBlock": 7,
|
||||
"buttonValue": "0x01",
|
||||
"joystickNumber": 12
|
||||
},
|
||||
{
|
||||
"name": "touchPad",
|
||||
"buttonBlock": 7,
|
||||
"buttonValue": "0x02",
|
||||
"joystickNumber": 13
|
||||
},
|
||||
{
|
||||
"name": "square",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x10",
|
||||
"joystickNumber": 0
|
||||
},
|
||||
{
|
||||
"name": "triangle",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x80",
|
||||
"joystickNumber": 3
|
||||
},
|
||||
{
|
||||
"name": "circle",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x40",
|
||||
"joystickNumber": 2
|
||||
},
|
||||
{
|
||||
"name": "x",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x20",
|
||||
"joystickNumber": 1
|
||||
},
|
||||
{
|
||||
"name": "dpadUp",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x00",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadUpRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x01",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x02",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDownRight",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x03",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDown",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue" : "0x04",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadDownLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue" : "0x05",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x06",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "dpadUpLeft",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x07",
|
||||
"mask": "0xF"
|
||||
},
|
||||
{
|
||||
"name": "share",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x10",
|
||||
"joystickNumber": 8
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x20",
|
||||
"joystickNumber": 9
|
||||
},
|
||||
{
|
||||
"name": "leftStick",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x40",
|
||||
"joystickNumber": 10
|
||||
},
|
||||
{
|
||||
"name": "rightStick",
|
||||
"buttonBlock": 6,
|
||||
"buttonValue": "0x80",
|
||||
"joystickNumber": 11
|
||||
}
|
||||
],
|
||||
"motionInputs" : [],
|
||||
"status" : [],
|
||||
"output": {
|
||||
"defaultBuffer":[
|
||||
5,255,4,0,0,0,0,0,0,0,0
|
||||
],
|
||||
"indexes": {
|
||||
"rumbleLeft": 4,
|
||||
"rumbleRight": 5,
|
||||
"red": 6,
|
||||
"green": 7,
|
||||
"blue": 8,
|
||||
"flashOn": 9,
|
||||
"flashOff": 10
|
||||
}
|
||||
},
|
||||
"touchPad": [{
|
||||
"name":"x1",
|
||||
"activePin": 35,
|
||||
"dataPinA": 37,
|
||||
"dataPinB": 36,
|
||||
"dataPinC": 38
|
||||
},{
|
||||
"name": "x2",
|
||||
"activePin": 39,
|
||||
"dataPinA": 41,
|
||||
"dataPinB": 40,
|
||||
"dataPinC": 42
|
||||
}]
|
||||
}
|
||||
8
dist/dualshock-controller/examples/README.md
vendored
Normal file
8
dist/dualshock-controller/examples/README.md
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
Examples:
|
||||
=========================
|
||||
|
||||
## Don't use this code as a starting point.
|
||||
I do things here that are not neccesary, you are better off looking at the readme in root as it has a cleaner implementation, this is here just so you can test it right away.
|
||||
|
||||
If you'd like to see more examples for the DualShock 4, feel free to check out
|
||||
[ds-examples](https://github.com/itaisteinherz/ds-examples).
|
||||
61
dist/dualshock-controller/examples/consolePrintControllerEvents.js
vendored
Normal file
61
dist/dualshock-controller/examples/consolePrintControllerEvents.js
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
var printcontrollerEvents = function(controller, controllerConfiguration) {
|
||||
'use strict';
|
||||
controller.on('left:move', function(data) {
|
||||
console.log('left Moved');
|
||||
console.log(data);
|
||||
});
|
||||
controller.on('right:move', function(data) {
|
||||
console.log('right Moved');
|
||||
console.log(data);
|
||||
});
|
||||
controller.on('connected', function() {
|
||||
console.log('connected');
|
||||
});
|
||||
|
||||
controller.on('error', function(data) {
|
||||
console.log(data);
|
||||
});
|
||||
|
||||
var pressed = function(data) {
|
||||
console.log(data + ": press");
|
||||
};
|
||||
var released = function(data) {
|
||||
console.log(data + ": release");
|
||||
};
|
||||
var analog = function(data) {
|
||||
console.log(data + ": analog");
|
||||
};
|
||||
var hold = function(data) {
|
||||
console.log(data + ": hold");
|
||||
};
|
||||
var motion = function(motionInput, data) {
|
||||
console.log(motionInput);
|
||||
console.log(data);
|
||||
};
|
||||
//subscribe to all the buttons:
|
||||
for (var i = 0; i < controllerConfiguration.buttons.length; i++) {
|
||||
controller.on(controllerConfiguration.buttons[i].name + ":press", pressed);
|
||||
controller.on(controllerConfiguration.buttons[i].name + ":release", released);
|
||||
controller.on(controllerConfiguration.buttons[i].name + ":analog", analog);
|
||||
controller.on(controllerConfiguration.buttons[i].name + ":hold", hold);
|
||||
|
||||
}
|
||||
//subscribe to all the status events:
|
||||
if (controllerConfiguration.status && controllerConfiguration.status.length) {
|
||||
for (i = 0; i < controllerConfiguration.status.length; i++) {
|
||||
controller.on(controllerConfiguration.status[i].name + ":change", console.log);
|
||||
}
|
||||
}
|
||||
//subscribe to the motion events.
|
||||
controller.on('rightLeft' + ':motion', function(data) {
|
||||
motion('rightLeft', data);
|
||||
});
|
||||
controller.on('forwardBackward' + ':motion', function(data) {
|
||||
motion('forwardBackward', data);
|
||||
});
|
||||
controller.on('upDown' + ':motion', function(data) {
|
||||
motion('upDown', data);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = printcontrollerEvents;
|
||||
52
dist/dualshock-controller/examples/consolePrintDualShock3.js
vendored
Normal file
52
dist/dualshock-controller/examples/consolePrintDualShock3.js
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
'use strict';
|
||||
var dualShock = require('./../src/dualshock.js');
|
||||
var dualShock3;
|
||||
|
||||
//init the controller
|
||||
dualShock3 = dualShock({
|
||||
analogStickSmoothing: false,
|
||||
config: "dualShock3",
|
||||
logging: true
|
||||
});
|
||||
|
||||
// //for a client implementation we do not need this, this is only to test the inputs.
|
||||
var controllerConfiguration = require('./../controllerConfigurations/dualShock3');
|
||||
|
||||
// //init the print events
|
||||
var consolePrintEvents = require('./consolePrintControllerEvents')(dualShock3, controllerConfiguration);
|
||||
|
||||
dualShock3.on("dpadup:press", () => {
|
||||
dualShock3.setExtras({
|
||||
led: 2
|
||||
});
|
||||
});
|
||||
|
||||
dualShock3.on("dpadright:press", () => {
|
||||
dualShock3.setExtras({
|
||||
led: 4
|
||||
});
|
||||
});
|
||||
|
||||
dualShock3.on("dpaddown:press", () => {
|
||||
dualShock3.setExtras({
|
||||
led: 8
|
||||
});
|
||||
});
|
||||
|
||||
dualShock3.on("dpadleft:press", () => {
|
||||
dualShock3.setExtras({
|
||||
led: 16
|
||||
});
|
||||
});
|
||||
|
||||
dualShock3.on("r2:analog", (d) => {
|
||||
dualShock3.setExtras({
|
||||
rumbleRight: d
|
||||
});
|
||||
});
|
||||
|
||||
dualShock3.on("l2:press", (d) => {
|
||||
dualShock3.setExtras({
|
||||
rumbleLeft: 1
|
||||
});
|
||||
});
|
||||
59
dist/dualshock-controller/examples/consolePrintDualShock4.js
vendored
Normal file
59
dist/dualshock-controller/examples/consolePrintDualShock4.js
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
'use strict';
|
||||
var dualShock = require('./../src/dualshock.js');
|
||||
|
||||
var dualShock4 = dualShock({
|
||||
config: "dualShock4",
|
||||
logging: true
|
||||
});
|
||||
|
||||
//for a client implementation we do not need this, this is only to test the inputs.
|
||||
var controllerConfiguration = require('./../controllerConfigurations/dualShock4');
|
||||
|
||||
//init the print events
|
||||
var consolePrintEvents = require('./consolePrintControllerEvents')(dualShock4, controllerConfiguration);
|
||||
|
||||
dualShock4.on("dpadup:press", () => {
|
||||
dualShock4.setExtras({
|
||||
red: 255
|
||||
});
|
||||
});
|
||||
|
||||
dualShock4.on("dpadright:press", () => {
|
||||
dualShock4.setExtras({
|
||||
green: 255
|
||||
});
|
||||
});
|
||||
|
||||
dualShock4.on("dpaddown:press", () => {
|
||||
dualShock4.setExtras({
|
||||
blue: 255
|
||||
});
|
||||
});
|
||||
|
||||
dualShock4.on("dpadleft:press", () => {
|
||||
dualShock4.setExtras({
|
||||
red: 255,
|
||||
green: 255,
|
||||
blue: 255
|
||||
});
|
||||
});
|
||||
|
||||
dualShock4.on("x:press", (d) => {
|
||||
dualShock4.setExtras({
|
||||
red: 255,
|
||||
flashOn: 50,
|
||||
flashOff: 10
|
||||
});
|
||||
});
|
||||
|
||||
dualShock4.on("r2:analog", (d) => {
|
||||
dualShock4.setExtras({
|
||||
rumbleRight: d
|
||||
});
|
||||
});
|
||||
|
||||
dualShock4.on("l2:analog", (d) => {
|
||||
dualShock4.setExtras({
|
||||
rumbleLeft: d
|
||||
});
|
||||
});
|
||||
12
dist/dualshock-controller/examples/deviceDiscoveryHelp.js
vendored
Normal file
12
dist/dualshock-controller/examples/deviceDiscoveryHelp.js
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
var HID = require('node-hid');
|
||||
console.log(HID.devices());
|
||||
|
||||
var controller = new HID.HID(1356, 616);
|
||||
|
||||
controller.on('data', function(data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (i === 30) {
|
||||
console.log(i + " " + data[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
6
dist/dualshock-controller/examples/deviceDiscoveryHelpLinux.js
vendored
Normal file
6
dist/dualshock-controller/examples/deviceDiscoveryHelpLinux.js
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
var joystick = require('joystick'),
|
||||
controller = new joystick(0, 256, 500);
|
||||
|
||||
controller.on('button', console.log);
|
||||
|
||||
controller.on('axis', console.log);
|
||||
67
dist/dualshock-controller/gruntfile.js
vendored
Normal file
67
dist/dualshock-controller/gruntfile.js
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
const files = ['gruntfile.js',
|
||||
'src/*.js',
|
||||
'src/inputProcessors/*.js',
|
||||
'test/*.js',
|
||||
'examples/*.js'
|
||||
];
|
||||
module.exports = function(grunt) {
|
||||
grunt.initConfig({
|
||||
watch: {
|
||||
files: files,
|
||||
tasks: ['default']
|
||||
},
|
||||
jshint: {
|
||||
files: files,
|
||||
options: {
|
||||
reporterOutput: "",
|
||||
esnext: true,
|
||||
node: true,
|
||||
globals: {
|
||||
describe: true,
|
||||
it: true,
|
||||
beforeEach: true
|
||||
}
|
||||
}
|
||||
},
|
||||
mochaTest: {
|
||||
test: {
|
||||
options: {
|
||||
reporter: 'spec'
|
||||
},
|
||||
src: ['test/*.js']
|
||||
}
|
||||
},
|
||||
jsbeautifier: {
|
||||
files: files,
|
||||
options: {
|
||||
js: {
|
||||
braceStyle: "collapse",
|
||||
breakChainedMethods: false,
|
||||
e4x: false,
|
||||
evalCode: false,
|
||||
indentChar: " ",
|
||||
indentLevel: 0,
|
||||
indentSize: 4,
|
||||
indentWithTabs: false,
|
||||
jslintHappy: false,
|
||||
keepArrayIndentation: false,
|
||||
keepFunctionIndentation: false,
|
||||
maxPreserveNewlines: 10,
|
||||
preserveNewlines: true,
|
||||
spaceBeforeConditional: true,
|
||||
spaceInParen: false,
|
||||
unescapeStrings: false,
|
||||
wrapLineLength: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-mocha-test');
|
||||
grunt.loadNpmTasks('grunt-jsbeautifier');
|
||||
|
||||
grunt.registerTask('test', ['jshint', 'mochaTest']);
|
||||
grunt.registerTask('default', ['jshint', 'mochaTest', 'jsbeautifier']);
|
||||
};
|
||||
47
dist/dualshock-controller/package.json
vendored
Normal file
47
dist/dualshock-controller/package.json
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"name": "dualshock-controller",
|
||||
"version": "1.1.1",
|
||||
"description": "Eventing API layer over HID for the Sony DualShock 3 and DualShock 4 controllers ",
|
||||
"main": "./src/dualshock.js",
|
||||
"dependencies": {
|
||||
"node-hid": "^0.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-cli": "^1.2.0",
|
||||
"grunt-contrib-jshint": "^1.1.0",
|
||||
"grunt-contrib-watch": "^1.0.0",
|
||||
"grunt-mocha-test": "^0.13.2",
|
||||
"mocha": "^3.2.0",
|
||||
"sinon": "^1.8",
|
||||
"nyc": "^10.0.0",
|
||||
"grunt-jsbeautifier": "^0.2.7",
|
||||
"jshint": "^2.5.0",
|
||||
"mockery": "^2.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "grunt test",
|
||||
"coverage": "nyc npm test"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.2"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/rdepena/node-dualshock-controller.git"
|
||||
},
|
||||
"author": "ricardo de pena",
|
||||
"license": "MIT",
|
||||
"readmeFilename": "README.md",
|
||||
"keywords": [
|
||||
"ps3",
|
||||
"controller",
|
||||
"gamepad",
|
||||
"dualshock",
|
||||
"dualshock3",
|
||||
"dualshock4",
|
||||
"dual shock 3",
|
||||
"dual shock 4",
|
||||
"node-hid"
|
||||
]
|
||||
}
|
||||
BIN
dist/dualshock-controller/src/HID.node
vendored
Normal file
BIN
dist/dualshock-controller/src/HID.node
vendored
Normal file
Binary file not shown.
51
dist/dualshock-controller/src/analogs.js
vendored
Normal file
51
dist/dualshock-controller/src/analogs.js
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
'use strict';
|
||||
// Module dependencies.
|
||||
var dsutilities = require('./utilities'),
|
||||
Smoothing = require('./smoothing'),
|
||||
config = require('./config');
|
||||
|
||||
//Proccess Analog stick events.
|
||||
var Analogs = function(controller) {
|
||||
|
||||
var varianceThreshhold = 1,
|
||||
smoothInput = config.getOptions().analogStickSmoothing,
|
||||
outputSmoothing = new Smoothing(smoothInput),
|
||||
analogSticks = config.getControllerConfig().analogSticks;
|
||||
|
||||
//Private methods
|
||||
var processStick = function(analogStick, data) {
|
||||
var currentValue = {
|
||||
x: data[analogStick.x],
|
||||
y: data[analogStick.y]
|
||||
},
|
||||
previousValue = {
|
||||
x: outputSmoothing.readLastPosition(analogStick.name + 'x'),
|
||||
y: outputSmoothing.readLastPosition(analogStick.name + 'y')
|
||||
};
|
||||
|
||||
//we only raise an event if both
|
||||
if (dsutilities.isWithinVariance(previousValue.x, currentValue.x, varianceThreshhold) ||
|
||||
dsutilities.isWithinVariance(previousValue.y, currentValue.y, varianceThreshhold)) {
|
||||
|
||||
currentValue.x = outputSmoothing.smooth(analogStick.name + 'x', currentValue.x);
|
||||
currentValue.y = outputSmoothing.smooth(analogStick.name + 'y', currentValue.y);
|
||||
|
||||
// Update and emit
|
||||
if (controller[analogStick.name]) {
|
||||
controller[analogStick.name].x = currentValue.x;
|
||||
controller[analogStick.name].y = currentValue.y;
|
||||
}
|
||||
controller.emit(analogStick.name + ':move', currentValue);
|
||||
}
|
||||
};
|
||||
|
||||
// Public methods
|
||||
//process all the analog events.
|
||||
this.process = function(data) {
|
||||
for (var i = 0; i < analogSticks.length; i++) {
|
||||
processStick(analogSticks[i], data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Analogs;
|
||||
104
dist/dualshock-controller/src/buttons.js
vendored
Normal file
104
dist/dualshock-controller/src/buttons.js
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
'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;
|
||||
56
dist/dualshock-controller/src/config.js
vendored
Normal file
56
dist/dualshock-controller/src/config.js
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
'use strict';
|
||||
// Module dependencies.
|
||||
// we will expose these objects via the manager.
|
||||
var options,
|
||||
controllerConfig;
|
||||
|
||||
//provides access to the current options and configs.
|
||||
var config = {
|
||||
setOptions: function(opts) {
|
||||
//no options were passed
|
||||
options = opts || {};
|
||||
|
||||
// Defaults:
|
||||
var defaultValues = {
|
||||
config: "dualShock3",
|
||||
accelerometerSmoothing: true,
|
||||
analogStickSmoothing: false,
|
||||
logging: false,
|
||||
forceNodeHid: false,
|
||||
linuxJoystickId: 0
|
||||
};
|
||||
|
||||
for (var name in defaultValues) {
|
||||
if (defaultValues.hasOwnProperty(name)) {
|
||||
var target = options[name];
|
||||
var orig = defaultValues[name];
|
||||
|
||||
if (!target) {
|
||||
options[name] = orig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var controllerConfiguration;
|
||||
//use passed config or load from built-in configs
|
||||
if (typeof options.config === "object") {
|
||||
controllerConfiguration = options.config;
|
||||
} else {
|
||||
controllerConfiguration = require('./../controllerConfigurations/' + options.config);
|
||||
}
|
||||
|
||||
//set the current controllerConfiguration
|
||||
config.setControllerConfig(controllerConfiguration);
|
||||
},
|
||||
getOptions: function() {
|
||||
return options;
|
||||
},
|
||||
setControllerConfig: function(config) {
|
||||
controllerConfig = config;
|
||||
},
|
||||
getControllerConfig: function() {
|
||||
return controllerConfig;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
167
dist/dualshock-controller/src/controller.js
vendored
Normal file
167
dist/dualshock-controller/src/controller.js
vendored
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
// Module dependencies.
|
||||
const util = require('util'),
|
||||
dsutilities = require('./utilities'),
|
||||
Emitter = require('events').EventEmitter,
|
||||
Gyro = require('./gyro'),
|
||||
Analogs = require('./analogs'),
|
||||
Buttons = require('./buttons'),
|
||||
Status = require('./status'),
|
||||
HID = require('./HID'),
|
||||
config = require('./config'),
|
||||
TouchPad = require('./touchpad');
|
||||
|
||||
//generic controller object, it will need a controller Configuration with a buttons array passed into its connect function.
|
||||
const Controller = function() {
|
||||
'use strict';
|
||||
Emitter.call(this);
|
||||
|
||||
const controllerConfig = config.getControllerConfig(),
|
||||
options = config.getOptions(),
|
||||
indexes = controllerConfig.output.indexes,
|
||||
analogs = new Analogs(this),
|
||||
buttons = new Buttons(this),
|
||||
gyro = new Gyro(this),
|
||||
status = new Status(this),
|
||||
touchPad = new TouchPad(this);
|
||||
|
||||
let device = null;
|
||||
|
||||
[{
|
||||
type: 'analogSticks',
|
||||
properties: [{
|
||||
name: 'x',
|
||||
initialValue: 0
|
||||
}, {
|
||||
name: 'y',
|
||||
initialValue: 0
|
||||
}]
|
||||
}, {
|
||||
type: 'buttons',
|
||||
properties: [{
|
||||
name: 'state',
|
||||
initialValue: 0
|
||||
}, {
|
||||
name: 'value',
|
||||
initialValue: 0
|
||||
}]
|
||||
}, {
|
||||
type: 'motionInputs',
|
||||
properties: [{
|
||||
name: 'value',
|
||||
initialValue: 0
|
||||
}, {
|
||||
name: 'direction',
|
||||
initialValue: 0
|
||||
}]
|
||||
}, {
|
||||
type: 'status',
|
||||
properties: [{
|
||||
name: 'state',
|
||||
initialValue: ''
|
||||
}]
|
||||
}].forEach(function(setup) {
|
||||
const entities = controllerConfig[setup.type],
|
||||
properties = setup.properties;
|
||||
|
||||
if (entities.length) {
|
||||
entities.forEach(function(entity) {
|
||||
this[entity.name] = properties.reduce(function(accum, property) {
|
||||
return (accum[property.name] = property.initialValue, accum);
|
||||
}, {});
|
||||
}, this);
|
||||
}
|
||||
}, this);
|
||||
|
||||
//Private methods
|
||||
//emit an error event or log it to the console.
|
||||
const handleException = function(ex) {
|
||||
//if exception was generated within our stream
|
||||
if (this && this.emit) {
|
||||
this.emit('error', ex);
|
||||
} else {
|
||||
dsutilities.warn(ex);
|
||||
throw (ex);
|
||||
}
|
||||
};
|
||||
|
||||
//process data from HID connected device.
|
||||
const processFrame = function(data) {
|
||||
if (controllerConfig.motionInputs) {
|
||||
gyro.process(data);
|
||||
}
|
||||
if (controllerConfig.analogSticks) {
|
||||
analogs.process(data);
|
||||
}
|
||||
if (controllerConfig.buttons) {
|
||||
buttons.process(data);
|
||||
}
|
||||
if (controllerConfig.status) {
|
||||
status.process(data);
|
||||
}
|
||||
if (controllerConfig.touchPad) {
|
||||
touchPad.process(data);
|
||||
}
|
||||
};
|
||||
|
||||
const isController = function(device) {
|
||||
var vendor = (device.vendorId == controllerConfig.vendorId);
|
||||
var product = (device.productId == controllerConfig.productId || device.productId == 2508);
|
||||
return vendor && product;
|
||||
};
|
||||
|
||||
// Public methods
|
||||
this.connect = function() {
|
||||
dsutilities.warn('connect method is deprecated, controller now connects upon declaration.');
|
||||
};
|
||||
|
||||
this.disconnect = function() {
|
||||
if (device && device.close) {
|
||||
device.close();
|
||||
}
|
||||
this.emit('disconnecting');
|
||||
dsutilities.warn('node dualshock disconnecting');
|
||||
};
|
||||
|
||||
// Used to set controller rumble and light
|
||||
this.setExtras = function(data) {
|
||||
|
||||
let buff = controllerConfig.output.defaultBuffer.slice();
|
||||
|
||||
Object.keys(data).forEach(k => {
|
||||
buff[indexes[k]] = data[k];
|
||||
});
|
||||
device.write(buff);
|
||||
};
|
||||
|
||||
//connect to the controller.
|
||||
if (typeof options.device === 'undefined') {
|
||||
dsutilities.warn('node dualshock connecting');
|
||||
var devices = HID.devices();
|
||||
|
||||
const deviceMeta = devices
|
||||
.filter(isController)[0];
|
||||
if (deviceMeta) {
|
||||
device = new HID.HID(deviceMeta.path);
|
||||
console.log(device);
|
||||
device.on('data', processFrame.bind(this));
|
||||
device.on('error', handleException.bind(this));
|
||||
} else {
|
||||
handleException(new Error(`device with Vendor ID:${controllerConfig.vendorId} Product ID:${controllerConfig.productId} not found`));
|
||||
}
|
||||
|
||||
} else {
|
||||
// Allow user-specified device
|
||||
device = options.device;
|
||||
console.log("Custom device: ", device);
|
||||
device.on('data', processFrame.bind(this));
|
||||
device.on('error', handleException.bind(this));
|
||||
}
|
||||
|
||||
//subscribe to the exit event:
|
||||
process.on('exit', this.disconnect.bind(this));
|
||||
};
|
||||
|
||||
//need to inherit from event emiter.
|
||||
util.inherits(Controller, Emitter);
|
||||
|
||||
module.exports = Controller;
|
||||
22
dist/dualshock-controller/src/dualshock.js
vendored
Normal file
22
dist/dualshock-controller/src/dualshock.js
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Module dependencies.
|
||||
var Controller = require('./controller'),
|
||||
config = require('./config');
|
||||
|
||||
// This is the app entry point.
|
||||
// options you can pass:
|
||||
// {
|
||||
// config : "File from controllerConfigurations" or a JS object containing configuration,
|
||||
// accelerometerSmoothing : true/false, this will activate motion/acelerometer output smoothing. true by default.
|
||||
// analogStickSmoothing : true/false, this will activate analog thumb stick smoothing
|
||||
// }
|
||||
var dualShock = function(options) {
|
||||
'use strict';
|
||||
|
||||
//set the current options
|
||||
config.setOptions(options);
|
||||
|
||||
//returns the controller.
|
||||
return new Controller();
|
||||
};
|
||||
|
||||
module.exports = dualShock;
|
||||
72
dist/dualshock-controller/src/gyro.js
vendored
Normal file
72
dist/dualshock-controller/src/gyro.js
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
'use strict';
|
||||
// Module dependencies.
|
||||
var dsutilities = require('./utilities'),
|
||||
Smoothing = require('./smoothing'),
|
||||
config = require('./config');
|
||||
|
||||
//Proccess button events.
|
||||
var motionProcessor = function(controller) {
|
||||
|
||||
var varianceThreshhold = 1,
|
||||
smoothInput = config.getOptions().accelerometerSmoothing,
|
||||
outputSmoothing = new Smoothing(smoothInput),
|
||||
motionInputs = config.getControllerConfig().motionInputs;
|
||||
|
||||
//generate event name aliases:
|
||||
motionInputs.forEach(function(motionAxis) {
|
||||
motionAxis.eventPrefixes = dsutilities.generateEventPrefixAliases(motionAxis.name);
|
||||
});
|
||||
|
||||
//Private methods
|
||||
//data corrections so that each dirrection has a 0 throug x value
|
||||
var correctData = function(motionAxis, data) {
|
||||
var value;
|
||||
//ensuring that both directions start from 0 and move to -x or x;
|
||||
if (data[motionAxis.directionPin] === 1) {
|
||||
//we need the values to be from 0 to x.
|
||||
value = 255 - data[motionAxis.valuePin];
|
||||
} else if (data[motionAxis.directionPin] === 2) {
|
||||
//going in the oposite direction, we need to values to be from 0 to -x;
|
||||
value = data[motionAxis.valuePin] * -1;
|
||||
}
|
||||
|
||||
//return an object with both value and dirrection.
|
||||
return {
|
||||
direction: data[motionAxis.directionPin],
|
||||
value: value
|
||||
};
|
||||
};
|
||||
|
||||
//process the axis movement.
|
||||
var processAxis = function(motionAxis, data) {
|
||||
//every motion will have a dirrection and a value
|
||||
var motionValue = correctData(motionAxis, data),
|
||||
lastPosition = outputSmoothing.readLastPosition(motionAxis.name);
|
||||
|
||||
//check if the values are within variance
|
||||
if (dsutilities.isWithinVariance(lastPosition, motionValue.value, varianceThreshhold)) {
|
||||
motionValue.value = outputSmoothing.smooth(motionAxis.name, motionValue.value);
|
||||
|
||||
// Don't assign motionValue directly to controller[motionAxis.name],
|
||||
// this will break the reference.
|
||||
if (controller[motionAxis.name]) {
|
||||
controller[motionAxis.name].value = motionValue.value;
|
||||
controller[motionAxis.name].direction = motionValue.direction;
|
||||
}
|
||||
|
||||
motionAxis.eventPrefixes.forEach(function(eventPrefix) {
|
||||
controller.emit(eventPrefix + ':motion', motionValue);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Public methods
|
||||
//process all configured motion inputs.
|
||||
this.process = function(data) {
|
||||
for (var i = 0; i < motionInputs.length; i++) {
|
||||
processAxis(motionInputs[i], data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = motionProcessor;
|
||||
50
dist/dualshock-controller/src/smoothing.js
vendored
Normal file
50
dist/dualshock-controller/src/smoothing.js
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// Module dependencies.
|
||||
|
||||
//smooths data with moving average
|
||||
var outputSmoothing = function(smoothInput) {
|
||||
'use strict';
|
||||
|
||||
var buffer = {},
|
||||
maxFrames = 5;
|
||||
|
||||
// Public methods
|
||||
this.readLastPosition = function(motionAxisName) {
|
||||
var axisBuffer = buffer[motionAxisName];
|
||||
return axisBuffer ? axisBuffer[axisBuffer.length - 1] : null;
|
||||
};
|
||||
|
||||
this.addToBuffer = function(motionAxisName, value) {
|
||||
if (buffer[motionAxisName]) {
|
||||
//add the current value to the buffer
|
||||
buffer[motionAxisName].push(value);
|
||||
|
||||
//remove the head of the buffer
|
||||
if (buffer[motionAxisName].length > maxFrames) {
|
||||
buffer[motionAxisName].shift();
|
||||
}
|
||||
} else {
|
||||
//create an array with the value.
|
||||
buffer[motionAxisName] = [value];
|
||||
}
|
||||
};
|
||||
|
||||
//smooth using a moving average.
|
||||
this.smooth = function(motionAxisName, value) {
|
||||
this.addToBuffer(motionAxisName, value);
|
||||
var axisBuffer = buffer[motionAxisName],
|
||||
sum = 0,
|
||||
smoothedVal = value;
|
||||
|
||||
if (smoothInput) {
|
||||
for (var i = 0; i < axisBuffer.length; i++) {
|
||||
sum += axisBuffer[i];
|
||||
}
|
||||
smoothedVal = Math.floor(sum / axisBuffer.length);
|
||||
}
|
||||
|
||||
return smoothedVal;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = outputSmoothing;
|
||||
36
dist/dualshock-controller/src/status.js
vendored
Normal file
36
dist/dualshock-controller/src/status.js
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
'use strict';
|
||||
// Module dependencies.
|
||||
|
||||
var config = require('./config');
|
||||
|
||||
//Proccess button events.
|
||||
var Status = function(controller) {
|
||||
|
||||
var buffer = {},
|
||||
status = config.getControllerConfig().status;
|
||||
|
||||
var processControllerStatus = function(category, data) {
|
||||
var state;
|
||||
for (var i = 0; i < category.states.length; i++) {
|
||||
if (data[category.pin] === category.states[i].value) {
|
||||
state = category.states[i].state;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer[category.name] !== state) {
|
||||
if (controller[category.name]) {
|
||||
controller[category.name].state = state;
|
||||
}
|
||||
controller.emit(category.name + ':change', state);
|
||||
}
|
||||
buffer[category.name] = state;
|
||||
};
|
||||
|
||||
this.process = function(data) {
|
||||
for (var i = 0; i < status.length; i++) {
|
||||
processControllerStatus(status[i], data);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = Status;
|
||||
52
dist/dualshock-controller/src/touchpad.js
vendored
Normal file
52
dist/dualshock-controller/src/touchpad.js
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
const config = require('./config');
|
||||
|
||||
function genpBufferFromConf(tpAxis) {
|
||||
return {
|
||||
name: tpAxis.name,
|
||||
active: false,
|
||||
data: {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function TouchPad(controller) {
|
||||
const touchPad = config.getControllerConfig().touchPad;
|
||||
let pBuffer = {};
|
||||
|
||||
function processIsActive(buffer, tpAxis) {
|
||||
const active = buffer[tpAxis.activePin] < 128;
|
||||
const axisBuffer = pBuffer[tpAxis.name];
|
||||
const evt = active ? 'active' : 'inactive';
|
||||
|
||||
if (active !== axisBuffer.active) {
|
||||
controller.emit(`touchpad:${tpAxis.name}:${evt}`);
|
||||
}
|
||||
|
||||
axisBuffer.active = active;
|
||||
}
|
||||
|
||||
function processData(buffer, tpAxis) {
|
||||
const axisBuffer = pBuffer[tpAxis.name];
|
||||
|
||||
if (axisBuffer.active) {
|
||||
axisBuffer.data.x = ((buffer[tpAxis.dataPinA] & 15) << 8 | buffer[tpAxis.dataPinB]);
|
||||
axisBuffer.data.y = buffer[tpAxis.dataPinC] << 4 | ((buffer[tpAxis.dataPinA] & 240) >> 4);
|
||||
controller.emit(`touchpad:${tpAxis.name}`, axisBuffer.data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.process = function process(buffer) {
|
||||
for (let i = 0; i < touchPad.length; i++) {
|
||||
//if we have not built a pBuffer profile for this axis lets build it.
|
||||
if (!pBuffer[touchPad[i].name]) {
|
||||
pBuffer[touchPad[i].name] = genpBufferFromConf(touchPad[i]);
|
||||
}
|
||||
|
||||
processIsActive(buffer, touchPad[i]);
|
||||
processData(buffer, touchPad[i]);
|
||||
}
|
||||
};
|
||||
};
|
||||
34
dist/dualshock-controller/src/utilities.js
vendored
Normal file
34
dist/dualshock-controller/src/utilities.js
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
'use strict';
|
||||
// Module dependencies.
|
||||
|
||||
var config = require('./config');
|
||||
|
||||
var unique = function unique(x) {
|
||||
var result = [];
|
||||
for (var i = 0; i < x.length; i++) {
|
||||
if ((result.indexOf(x[i]) < 0)) {
|
||||
result.push(x[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
//provide a few utility functions.
|
||||
module.exports = {
|
||||
|
||||
//reduces noise from the controller
|
||||
isWithinVariance: function(x, y, varianceThreshhold) {
|
||||
return Math.abs(x - y) > varianceThreshhold;
|
||||
},
|
||||
warn: function(message) {
|
||||
if (config.getOptions().logging) {
|
||||
console.log(message);
|
||||
}
|
||||
},
|
||||
generateEventPrefixAliases: function(eventPrefix) {
|
||||
return unique([
|
||||
eventPrefix,
|
||||
eventPrefix.toLowerCase()
|
||||
]);
|
||||
}
|
||||
};
|
||||
84
dist/dualshock-controller/test/analog.tests.js
vendored
Normal file
84
dist/dualshock-controller/test/analog.tests.js
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// Module dependencies.
|
||||
var Analogs = require('../src/analogs'),
|
||||
assert = require('assert'),
|
||||
sinon = require('sinon'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
config = require('../src/config');
|
||||
|
||||
describe('the Analogs component', function() {
|
||||
'use strict';
|
||||
|
||||
var mockConfig = [{
|
||||
"name": "analog",
|
||||
"x": 0,
|
||||
"y": 1
|
||||
}],
|
||||
instance = [{
|
||||
name: 'process'
|
||||
}],
|
||||
dataA = [50, 65],
|
||||
dataB = [0, 0],
|
||||
analogs,
|
||||
emitter,
|
||||
spy;
|
||||
|
||||
beforeEach(function() {
|
||||
emitter = new EventEmitter();
|
||||
config.setOptions({
|
||||
analogStickSmoothing: false
|
||||
});
|
||||
config.setControllerConfig({
|
||||
analogSticks: mockConfig
|
||||
});
|
||||
analogs = new Analogs(emitter);
|
||||
spy = new sinon.spy();
|
||||
});
|
||||
|
||||
describe('object instance', function() {
|
||||
it('should have the following shape', function() {
|
||||
//make sure we find these functions.
|
||||
instance.forEach(function(method) {
|
||||
assert.equal(typeof analogs[method.name], 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('move events', function() {
|
||||
it('should invoke the move event', function() {
|
||||
emitter.on('analog:move', spy);
|
||||
analogs.process(dataA);
|
||||
|
||||
assert.equal(spy.called, true);
|
||||
});
|
||||
it('should not invoke the move event', function() {
|
||||
emitter.on('analog:move', spy);
|
||||
analogs.process(dataB);
|
||||
|
||||
assert.equal(spy.called, false);
|
||||
});
|
||||
it('should invoke the move event with zero', function() {
|
||||
analogs.process(dataA);
|
||||
emitter.on('analog:move', spy);
|
||||
analogs.process(dataB);
|
||||
|
||||
assert.equal(spy.called, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('return values', function() {
|
||||
it('should return the analog values', function() {
|
||||
emitter.on('analog:move', spy);
|
||||
analogs.process(dataA);
|
||||
var expectedValue = {
|
||||
x: 50,
|
||||
y: 65
|
||||
},
|
||||
spyArgument = spy.args[0][0];
|
||||
|
||||
assert.equal(expectedValue.x, spyArgument.x);
|
||||
assert.equal(expectedValue.y, spyArgument.y);
|
||||
assert.equal(spy.called, true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
178
dist/dualshock-controller/test/buttons.tests.js
vendored
Normal file
178
dist/dualshock-controller/test/buttons.tests.js
vendored
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
// Module dependencies.
|
||||
var Buttons = require('../src/buttons'),
|
||||
assert = require('assert'),
|
||||
sinon = require('sinon'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
config = require('../src/config');
|
||||
|
||||
describe('the Buttons component', function() {
|
||||
'use strict';
|
||||
|
||||
var mockConfig = [{
|
||||
"name": "buttonName",
|
||||
"buttonBlock": 0,
|
||||
"buttonValue": "0x08",
|
||||
"analogPin": 1
|
||||
}, {
|
||||
"name": "dpadUp",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x00",
|
||||
"mask": "0xF"
|
||||
}, {
|
||||
"name": "dpadDown",
|
||||
"buttonBlock": 5,
|
||||
"buttonValue": "0x01",
|
||||
"mask": "0xF"
|
||||
}],
|
||||
instance = [{
|
||||
name: 'process'
|
||||
}],
|
||||
dataA = [8, 170],
|
||||
dataB = [0, 0],
|
||||
buttons,
|
||||
emitter,
|
||||
spy,
|
||||
spyLowerCaseEvents;
|
||||
|
||||
beforeEach(function() {
|
||||
emitter = new EventEmitter();
|
||||
config.setControllerConfig({
|
||||
buttons: mockConfig
|
||||
});
|
||||
buttons = new Buttons(emitter);
|
||||
spy = new sinon.spy();
|
||||
spyLowerCaseEvents = new sinon.spy();
|
||||
|
||||
});
|
||||
|
||||
describe('object instance', function() {
|
||||
it('should have the following shape', function() {
|
||||
//make sure we find these functions.
|
||||
instance.forEach(function(method) {
|
||||
assert.equal(typeof buttons[method.name], 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('press events', function() {
|
||||
it('should envoke the buttonName:press', function() {
|
||||
emitter.on('buttonName:press', spy);
|
||||
emitter.on('buttonname:press', spyLowerCaseEvents);
|
||||
buttons.process(dataA);
|
||||
|
||||
assert.equal(spy.called, true);
|
||||
assert.equal(spyLowerCaseEvents.called, true);
|
||||
});
|
||||
it('should not envoke the buttonName:press', function() {
|
||||
emitter.on('buttonName:release', spy);
|
||||
emitter.on('buttonname:release', spyLowerCaseEvents);
|
||||
buttons.process(dataB);
|
||||
|
||||
assert.equal(spy.called, false);
|
||||
assert.equal(spyLowerCaseEvents.called, false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('release events', function() {
|
||||
it('should envoke the buttonName:release', function() {
|
||||
emitter.on('buttonName:release', spy);
|
||||
emitter.on('buttonname:release', spyLowerCaseEvents);
|
||||
buttons.process(dataA);
|
||||
buttons.process(dataB);
|
||||
|
||||
assert.equal(spy.called, true);
|
||||
assert.equal(spyLowerCaseEvents.called, true);
|
||||
});
|
||||
it('should not envoke the buttonName:release', function() {
|
||||
emitter.on('buttonName:release', spy);
|
||||
emitter.on('buttonname:release', spyLowerCaseEvents);
|
||||
buttons.process(dataA);
|
||||
|
||||
assert.equal(spy.called, false);
|
||||
assert.equal(spyLowerCaseEvents.called, false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('button hold', function() {
|
||||
it('should raise the hold event', function() {
|
||||
emitter.on('buttonName:hold', spy);
|
||||
emitter.on('buttonname:hold', spyLowerCaseEvents);
|
||||
buttons.process(dataA);
|
||||
buttons.process(dataA);
|
||||
assert.equal(spy.args[0][0], 'buttonName');
|
||||
assert.equal(spy.called, true);
|
||||
assert.equal(spyLowerCaseEvents.called, true);
|
||||
});
|
||||
|
||||
it('should not raise the hold event', function() {
|
||||
emitter.on('buttonName:hold', spy);
|
||||
emitter.on('buttonname:hold', spyLowerCaseEvents);
|
||||
buttons.process(dataB);
|
||||
buttons.process(dataB);
|
||||
assert.equal(spy.called, false);
|
||||
assert.equal(spyLowerCaseEvents.called, false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('button analog', function() {
|
||||
it('should raise the analog event', function() {
|
||||
emitter.on('buttonName:analog', spy);
|
||||
emitter.on('buttonname:analog', spyLowerCaseEvents);
|
||||
buttons.process(dataA);
|
||||
|
||||
assert.equal(spy.args[0][0], dataA[1]);
|
||||
assert.equal(spy.called, true);
|
||||
assert.equal(spyLowerCaseEvents.called, true);
|
||||
});
|
||||
|
||||
it('should not raise the analog event', function() {
|
||||
emitter.on('buttonName:analog', spy);
|
||||
emitter.on('buttonname:analog', spyLowerCaseEvents);
|
||||
buttons.process(dataB);
|
||||
|
||||
assert.equal(spy.called, false);
|
||||
assert.equal(spyLowerCaseEvents.called, false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ps4 dpad up button', function() {
|
||||
it('should emit the dpadUp:press event', function() {
|
||||
emitter.on('dpadUp:press', spy);
|
||||
emitter.on('dpadup:press', spyLowerCaseEvents);
|
||||
buttons.process([0, 0, 0, 0, 0, 0]);
|
||||
|
||||
assert.equal(spy.called, true);
|
||||
assert.equal(spyLowerCaseEvents.called, true);
|
||||
});
|
||||
|
||||
it('should not emit the dpadDown:press event', function() {
|
||||
emitter.on('dpadDown:press', spy);
|
||||
emitter.on('dpaddown:press', spyLowerCaseEvents);
|
||||
buttons.process([0, 0, 0, 0, 0, 0]);
|
||||
|
||||
assert.equal(spy.called, false);
|
||||
assert.equal(spyLowerCaseEvents.called, false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ps4 dpad down button', function() {
|
||||
it('should emit the dpadDown:press event', function() {
|
||||
emitter.on('dpadDown:press', spy);
|
||||
emitter.on('dpaddown:press', spyLowerCaseEvents);
|
||||
buttons.process([0, 0, 0, 0, 0, parseInt("00001001", 2)]);
|
||||
|
||||
assert.equal(spy.called, true);
|
||||
assert.equal(spyLowerCaseEvents.called, true);
|
||||
});
|
||||
|
||||
it('should not emit the dpadUp:press event', function() {
|
||||
emitter.on('dpadUp:press', spy);
|
||||
emitter.on('dpadup:press', spyLowerCaseEvents);
|
||||
buttons.process([0, 0, 0, 0, 0, parseInt("00001001", 2)]);
|
||||
|
||||
assert.equal(spy.called, false);
|
||||
assert.equal(spyLowerCaseEvents.called, false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
91
dist/dualshock-controller/test/config.tests.js
vendored
Normal file
91
dist/dualshock-controller/test/config.tests.js
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
|
||||
describe('The Config component', function() {
|
||||
var mockConfig = {
|
||||
vendorId: 1556,
|
||||
productId: 616,
|
||||
output: []
|
||||
},
|
||||
mockOptions = {
|
||||
config: 'dualShock3',
|
||||
accelerometerSmoothing: true,
|
||||
logging: false
|
||||
},
|
||||
instance = [{
|
||||
name: 'setOptions'
|
||||
}, {
|
||||
name: 'getOptions'
|
||||
}, {
|
||||
name: 'setControllerConfig'
|
||||
}, {
|
||||
name: 'getControllerConfig'
|
||||
}],
|
||||
defaultOptionsInstance = [{
|
||||
name: 'config'
|
||||
}, {
|
||||
name: 'accelerometerSmoothing'
|
||||
}, {
|
||||
name: 'analogStickSmoothing'
|
||||
}],
|
||||
configA,
|
||||
configB;
|
||||
|
||||
beforeEach(function() {
|
||||
configA = require('../src/config');
|
||||
configB = require('../src/config');
|
||||
});
|
||||
|
||||
|
||||
describe('object instance', function() {
|
||||
it('should have the following shape', function() {
|
||||
instance.forEach(function(method) {
|
||||
assert.equal(typeof configA[method.name], 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('option methods', function() {
|
||||
it('should be able to save options', function() {
|
||||
configA.setOptions(mockOptions);
|
||||
assert.equal(configA.getOptions(), mockOptions);
|
||||
});
|
||||
|
||||
it('should provide a single object accross instances', function() {
|
||||
configA.setOptions(mockOptions);
|
||||
assert.equal(configA.getOptions(), configB.getOptions());
|
||||
});
|
||||
});
|
||||
|
||||
describe('controllerConfig methods', function() {
|
||||
it('should be able to save controllerConfig settings', function() {
|
||||
configA.setControllerConfig(mockConfig);
|
||||
//change the object
|
||||
mockConfig.vendorId = 22;
|
||||
assert.equal(configA.getControllerConfig(), mockConfig);
|
||||
});
|
||||
|
||||
it('should provide a single object accross instances', function() {
|
||||
configA.setControllerConfig(mockConfig);
|
||||
assert.equal(configA.getControllerConfig(), configB.getControllerConfig());
|
||||
});
|
||||
});
|
||||
|
||||
describe('default values', function() {
|
||||
beforeEach(function() {
|
||||
configA.setOptions();
|
||||
});
|
||||
it('should apply default values', function() {
|
||||
var ops = configA.getOptions();
|
||||
defaultOptionsInstance.forEach(function(property) {
|
||||
assert.notEqual(ops[property.name], void 0);
|
||||
});
|
||||
});
|
||||
it('should load default config', function() {
|
||||
var controllerConfig = configA.getControllerConfig();
|
||||
assert.notEqual(controllerConfig, null);
|
||||
assert.notEqual(controllerConfig, void 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
158
dist/dualshock-controller/test/dualshock.tests.js
vendored
Normal file
158
dist/dualshock-controller/test/dualshock.tests.js
vendored
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
var assert = require('assert'),
|
||||
Emitter = require('events').EventEmitter,
|
||||
config = require('../src/config'),
|
||||
mockery = require('mockery');
|
||||
|
||||
function Device() {
|
||||
Emitter.call(this);
|
||||
}
|
||||
|
||||
Device.prototype = Object.create(Emitter.prototype, {
|
||||
constructor: {
|
||||
value: Device
|
||||
},
|
||||
close: {
|
||||
value: function() {}
|
||||
}
|
||||
});
|
||||
|
||||
var config = {
|
||||
analogSticks: [{
|
||||
name: 'foo',
|
||||
x: 0,
|
||||
y: 1
|
||||
}],
|
||||
buttons: [{
|
||||
name: 'bar',
|
||||
buttonBlock: 0,
|
||||
buttonValue: 0x08,
|
||||
analogPin: 1
|
||||
}],
|
||||
motionInputs: [{
|
||||
name: 'baz',
|
||||
directionPin: 0,
|
||||
valuePin: 1
|
||||
}],
|
||||
status: [{
|
||||
name: 'quz',
|
||||
pin: 5,
|
||||
states: [{
|
||||
value: 0,
|
||||
state: 'Charging'
|
||||
}, {
|
||||
value: 2,
|
||||
state: 'Charging'
|
||||
}, {
|
||||
value: 3,
|
||||
state: '40%'
|
||||
}]
|
||||
}],
|
||||
output: []
|
||||
};
|
||||
|
||||
var analogs = config.analogSticks;
|
||||
var buttons = config.buttons;
|
||||
var motions = config.motionInputs;
|
||||
var status = config.status;
|
||||
|
||||
describe('the DualShock component', function() {
|
||||
//enable mockery and mock node-hid:
|
||||
mockery.enable();
|
||||
var nodeHidMock = {
|
||||
HID: function(vendor, productId) {
|
||||
return {
|
||||
on: function() {
|
||||
//could use this at some point. nothing atm.
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
//register mock node-hid.
|
||||
mockery.registerMock('node-hid', nodeHidMock);
|
||||
|
||||
//once mockery is up we can require the dualshock module.
|
||||
var DualShock = require('./../src/dualshock.js'),
|
||||
controller, device;
|
||||
|
||||
before(function() {
|
||||
device = new Device();
|
||||
controller = DualShock({
|
||||
config: config,
|
||||
device: device
|
||||
});
|
||||
});
|
||||
|
||||
//disable mockery so it does not interfere with other tests.
|
||||
after(function() {
|
||||
mockery.deregisterMock('node-hid');
|
||||
mockery.disable();
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
controller.removeAllListeners(Object.keys(controller._events));
|
||||
});
|
||||
|
||||
describe('analog properties', function() {
|
||||
analogs.forEach(function(analog) {
|
||||
it(analog.name, function() {
|
||||
assert.equal(controller[analog.name].x, 0);
|
||||
assert.equal(controller[analog.name].y, 0);
|
||||
|
||||
device.emit('data', [100, 100]);
|
||||
|
||||
assert.equal(controller[analog.name].x, 100);
|
||||
assert.equal(controller[analog.name].y, 100);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('button properties', function() {
|
||||
buttons.forEach(function(button) {
|
||||
it(button.name, function() {
|
||||
assert.equal(controller[button.name].value, 0);
|
||||
assert.equal(controller[button.name].state, 0);
|
||||
|
||||
device.emit('data', [8, 170]);
|
||||
|
||||
assert.equal(controller[button.name].value, 1);
|
||||
assert.equal(controller[button.name].state, 1);
|
||||
|
||||
device.emit('data', [8, 170]);
|
||||
|
||||
assert.equal(controller[button.name].value, 1);
|
||||
assert.equal(controller[button.name].state, 2);
|
||||
|
||||
device.emit('data', [0, 0]);
|
||||
|
||||
assert.equal(controller[button.name].value, 0);
|
||||
assert.equal(controller[button.name].state, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('motion properties', function() {
|
||||
motions.forEach(function(motion) {
|
||||
it(motion.name, function() {
|
||||
assert.equal(controller[motion.name].value, 0);
|
||||
assert.equal(controller[motion.name].direction, 0);
|
||||
|
||||
device.emit('data', [1, 233]);
|
||||
|
||||
assert.equal(controller[motion.name].value, 22);
|
||||
assert.equal(controller[motion.name].direction, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('status properties', function() {
|
||||
status.forEach(function(stat) {
|
||||
it(stat.name, function() {
|
||||
device.emit('data', [0, 0, 0, 0, 1, 3]);
|
||||
assert.equal(controller[stat.name].state, '40%');
|
||||
|
||||
device.emit('data', [0, 0, 0, 0, 1, 2]);
|
||||
assert.equal(controller[stat.name].state, 'Charging');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
78
dist/dualshock-controller/test/gyro.tests.js
vendored
Normal file
78
dist/dualshock-controller/test/gyro.tests.js
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// Module dependencies.
|
||||
var Gyro = require('../src/gyro'),
|
||||
assert = require('assert'),
|
||||
sinon = require('sinon'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
config = require('../src/config');
|
||||
|
||||
describe('the Gyro component', function() {
|
||||
'use strict';
|
||||
|
||||
var mockConfig = [{
|
||||
name: "dirrection",
|
||||
directionPin: 0,
|
||||
valuePin: 1
|
||||
}],
|
||||
instance = [{
|
||||
name: 'process'
|
||||
}],
|
||||
dataA = [1, 130],
|
||||
dataB = [2, 130],
|
||||
emitter,
|
||||
spy,
|
||||
gyro;
|
||||
|
||||
beforeEach(function() {
|
||||
emitter = new EventEmitter();
|
||||
spy = sinon.spy();
|
||||
config.setOptions({
|
||||
accelerometerSmoothing: false
|
||||
});
|
||||
config.setControllerConfig({
|
||||
motionInputs: mockConfig
|
||||
});
|
||||
gyro = new Gyro(emitter);
|
||||
});
|
||||
|
||||
describe('object instance', function() {
|
||||
|
||||
it('should have the following shape', function() {
|
||||
//make sure we find these functions.
|
||||
instance.forEach(function(method) {
|
||||
assert.equal(typeof gyro[method.name], 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('process()', function() {
|
||||
|
||||
it('should envoke the dirrection:motion event with positive values', function() {
|
||||
emitter.on('dirrection:motion', spy);
|
||||
gyro.process(dataA);
|
||||
assert.equal(spy.called, true);
|
||||
var expectedValue = {
|
||||
direction: 1,
|
||||
value: 125
|
||||
},
|
||||
spyArgument = spy.args[0][0];
|
||||
|
||||
assert.equal(spyArgument.direction, expectedValue.direction);
|
||||
assert.equal(spyArgument.value, expectedValue.value);
|
||||
});
|
||||
|
||||
it('should envoke the dirrection event with negative values.', function() {
|
||||
emitter.on('dirrection:motion', spy);
|
||||
gyro.process(dataB);
|
||||
assert.equal(spy.called, true);
|
||||
var expectedValue = {
|
||||
direction: 2,
|
||||
value: -130
|
||||
},
|
||||
spyArgument = spy.args[0][0];
|
||||
|
||||
assert.equal(spyArgument.direction, expectedValue.direction);
|
||||
assert.equal(spyArgument.value, expectedValue.value);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
71
dist/dualshock-controller/test/smoothing.tests.js
vendored
Normal file
71
dist/dualshock-controller/test/smoothing.tests.js
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Module dependencies.
|
||||
var Smoothing = require('../src/smoothing'),
|
||||
assert = require('assert');
|
||||
|
||||
describe('the smoothing component', function() {
|
||||
'use strict';
|
||||
|
||||
var smoothing,
|
||||
nonSmoothing,
|
||||
//an instance should have the following functions.
|
||||
instance = [{
|
||||
name: 'readLastPosition'
|
||||
}, {
|
||||
name: 'addToBuffer'
|
||||
}, {
|
||||
name: 'smooth'
|
||||
}];
|
||||
|
||||
beforeEach(function() {
|
||||
smoothing = new Smoothing(true);
|
||||
nonSmoothing = new Smoothing(false);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
nonSmoothing.addToBuffer('testNonSmoothing', i);
|
||||
smoothing.addToBuffer('one', i);
|
||||
smoothing.addToBuffer('two', i + 1);
|
||||
smoothing.addToBuffer('testSmoothing', i);
|
||||
}
|
||||
});
|
||||
|
||||
describe('object instance', function() {
|
||||
it('should have the following shape', function() {
|
||||
//make sure we find these functions.
|
||||
instance.forEach(function(method) {
|
||||
assert.equal(typeof smoothing[method.name], 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('addToBuffer()', function() {
|
||||
it('should add values to the buffer', function() {
|
||||
smoothing.addToBuffer('one', 6);
|
||||
smoothing.addToBuffer('two', 7);
|
||||
|
||||
assert.equal(smoothing.readLastPosition('one'), 6);
|
||||
assert.equal(smoothing.readLastPosition('two'), 7);
|
||||
});
|
||||
});
|
||||
|
||||
describe('readLastPosition()', function() {
|
||||
it('should handle buffers for different objects', function() {
|
||||
assert.equal(smoothing.readLastPosition('one'), 4);
|
||||
assert.equal(smoothing.readLastPosition('two'), 5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('smooth()', function() {
|
||||
it('should return expected values when smoothing', function() {
|
||||
//with the data set smoothing of 6 should be 3.
|
||||
assert.equal(smoothing.smooth('testSmoothing', 6), 3);
|
||||
//with the data set smoothing of 8 should be 4.
|
||||
assert.equal(smoothing.smooth('testSmoothing', 8), 4);
|
||||
});
|
||||
|
||||
it('should return expected values when not smoothing', function() {
|
||||
//with smoothing turned off 9 should return 9
|
||||
assert.equal(nonSmoothing.smooth('testNonSmoothing', 9), 9);
|
||||
//with smoothing turned off 6 should return 6
|
||||
assert.equal(nonSmoothing.smooth('testNonSmoothing', 6), 6);
|
||||
});
|
||||
});
|
||||
});
|
||||
60
dist/dualshock-controller/test/status.tests.js
vendored
Normal file
60
dist/dualshock-controller/test/status.tests.js
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
// Module dependencies.
|
||||
var Status = require('../src/status'),
|
||||
assert = require('assert'),
|
||||
sinon = require('sinon'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
config = require('../src/config');
|
||||
|
||||
describe('the status component', function() {
|
||||
var mockConfig = [{
|
||||
"name": "chargingState",
|
||||
"pin": 0,
|
||||
"states": [{
|
||||
"value": 0,
|
||||
"state": "Charging"
|
||||
}, {
|
||||
"value": 2,
|
||||
"state": "Charging"
|
||||
}, {
|
||||
"value": 3,
|
||||
"state": "40%"
|
||||
}]
|
||||
}],
|
||||
dataA = [0, 0],
|
||||
dataB = [0, 3],
|
||||
instance = [{
|
||||
name: 'process'
|
||||
}],
|
||||
status,
|
||||
emitter,
|
||||
spy;
|
||||
|
||||
beforeEach(function() {
|
||||
emitter = new EventEmitter();
|
||||
spy = sinon.spy();
|
||||
config.setControllerConfig({
|
||||
status: mockConfig
|
||||
});
|
||||
status = new Status(emitter, mockConfig);
|
||||
});
|
||||
|
||||
describe('object instance', function() {
|
||||
it('should have the following shape', function() {
|
||||
//make sure we find these functions.
|
||||
instance.forEach(function(method) {
|
||||
assert.equal(typeof status[method.name], 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('process()', function() {
|
||||
it('process should return an object with the expected values', function() {
|
||||
emitter.on('chargingState:change', spy);
|
||||
status.process(dataA);
|
||||
var spyArgument = spy.args[0][0];
|
||||
assert.equal(typeof spyArgument, 'string');
|
||||
assert.equal(spyArgument, 'Charging');
|
||||
spyArgument = null;
|
||||
});
|
||||
});
|
||||
});
|
||||
40
html/gamepad/ps4controller.js
Normal file
40
html/gamepad/ps4controller.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//Only to be used for PS4 (Dualshock 4) controllers
|
||||
var dualShock = require('../../dist/dualshock-controller/src/dualshock');
|
||||
try {
|
||||
|
||||
var controller = dualShock({
|
||||
config: "dualshock4-generic-driver"
|
||||
});
|
||||
|
||||
controller.on('error', err => console.log(err));
|
||||
|
||||
function setExtras(obj) {
|
||||
controller.setExtras(obj);
|
||||
}
|
||||
var connected = false;
|
||||
|
||||
controller.on('connected', () => {
|
||||
connected = true;
|
||||
});
|
||||
controller.on("disconnected", () => {
|
||||
connected = false;
|
||||
})
|
||||
|
||||
function isConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
function on(event, handler) {
|
||||
controller.on(event, handler);
|
||||
}
|
||||
module.exports = {
|
||||
on,
|
||||
isConnected,
|
||||
setExtras
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
module.exports = {
|
||||
isConnected: ()=>{return false}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ const utils = require("../../utils");
|
|||
const gui = require("./gui");
|
||||
const Gamepad = require("../../gamepad/gamepad");
|
||||
const gamepad = new Gamepad;
|
||||
const controller = require("../../gamepad/ps4controller");
|
||||
|
||||
function gamepadConnected(){
|
||||
console.log("Gamepad connected");
|
||||
|
|
@ -18,6 +19,15 @@ function gamepadConnected(){
|
|||
gui.renderUserCardList(cards);
|
||||
var selected = 0;
|
||||
|
||||
if(controller.isConnected()){
|
||||
controller.setExtras({
|
||||
rumbleLeft: 0, // 0-255 (Rumble left intensity)
|
||||
rumbleRight: 0, // 0-255 (Rumble right intensity)
|
||||
red: 0, // 0-255 (Red intensity)
|
||||
green: 75, // 0-255 (Blue intensity)
|
||||
blue: 225, // 0-255 (Green intensity)
|
||||
});
|
||||
}
|
||||
gamepad.on("press", "d_pad_right", () => {
|
||||
if(selected < max){
|
||||
selected++;
|
||||
|
|
|
|||
358
package-lock.json
generated
358
package-lock.json
generated
|
|
@ -93,8 +93,7 @@
|
|||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
|
|
@ -113,6 +112,54 @@
|
|||
"picomatch": "^2.0.4"
|
||||
}
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
||||
"requires": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^2.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"array-back": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
|
||||
|
|
@ -207,6 +254,42 @@
|
|||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
|
||||
"integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow=="
|
||||
},
|
||||
"bindings": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||
"requires": {
|
||||
"file-uri-to-path": "1.0.0"
|
||||
}
|
||||
},
|
||||
"bl": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
|
||||
"integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
|
||||
"requires": {
|
||||
"readable-stream": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
|
||||
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
|
|
@ -345,6 +428,11 @@
|
|||
"readdirp": "~3.3.0"
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz",
|
||||
"integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw=="
|
||||
},
|
||||
"chromium-pickle-js": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
|
||||
|
|
@ -363,8 +451,7 @@
|
|||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
|
|
@ -499,6 +586,11 @@
|
|||
"proto-list": "~1.2.1"
|
||||
}
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.1.tgz",
|
||||
|
|
@ -509,8 +601,7 @@
|
|||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"cross-zip": {
|
||||
"version": "2.1.6",
|
||||
|
|
@ -616,6 +707,16 @@
|
|||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
|
||||
},
|
||||
"detect-node": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
|
||||
|
|
@ -802,7 +903,6 @@
|
|||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
|
|
@ -834,6 +934,11 @@
|
|||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"expand-template": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
|
|
@ -904,6 +1009,11 @@
|
|||
"array-back": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
|
|
@ -991,6 +1101,11 @@
|
|||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
|
||||
|
|
@ -1025,6 +1140,21 @@
|
|||
"fs-extra": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"requires": {
|
||||
"aproba": "^1.0.3",
|
||||
"console-control-strings": "^1.0.0",
|
||||
"has-unicode": "^2.0.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"signal-exit": "^3.0.0",
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wide-align": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"get-package-info": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz",
|
||||
|
|
@ -1135,6 +1265,11 @@
|
|||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
|
|
@ -1251,6 +1386,11 @@
|
|||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz",
|
||||
|
|
@ -1296,14 +1436,12 @@
|
|||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
|
|
@ -1337,7 +1475,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
|
|
@ -1587,14 +1724,12 @@
|
|||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
},
|
||||
|
|
@ -1602,8 +1737,7 @@
|
|||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -1613,6 +1747,34 @@
|
|||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
|
||||
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
|
||||
},
|
||||
"napi-build-utils": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz",
|
||||
"integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA=="
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.13.0.tgz",
|
||||
"integrity": "sha512-9HrZGFVTR5SOu3PZAnAY2hLO36aW1wmA+FDsVkr85BTST32TLCA1H/AEcatVRAsWLyXS3bqUDYCAjq5/QGuSTA==",
|
||||
"requires": {
|
||||
"semver": "^5.4.1"
|
||||
}
|
||||
},
|
||||
"node-hid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-hid/-/node-hid-1.0.0.tgz",
|
||||
"integrity": "sha512-KOkrN0nn82ffj30iYAmzJmif6h0/5r3NlG68NJQf8hxYpy3pzkr7TjjOL4fgoB4Ehc4YIdinP1F6pGOJqdModg==",
|
||||
"requires": {
|
||||
"bindings": "^1.5.0",
|
||||
"nan": "^2.14.0",
|
||||
"prebuild-install": "^5.3.3"
|
||||
}
|
||||
},
|
||||
"node-wifi": {
|
||||
"version": "2.0.12",
|
||||
"resolved": "https://registry.npmjs.org/node-wifi/-/node-wifi-2.0.12.tgz",
|
||||
|
|
@ -1622,6 +1784,11 @@
|
|||
"command-line-usage": "^5.0.5"
|
||||
}
|
||||
},
|
||||
"noop-logger": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
|
||||
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
|
||||
},
|
||||
"normalize-package-data": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
|
||||
|
|
@ -1665,6 +1832,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"requires": {
|
||||
"are-we-there-yet": "~1.1.2",
|
||||
"console-control-strings": "~1.1.0",
|
||||
"gauge": "~2.7.3",
|
||||
"set-blocking": "~2.0.0"
|
||||
}
|
||||
},
|
||||
"nugget": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz",
|
||||
|
|
@ -1700,8 +1878,7 @@
|
|||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
|
|
@ -1712,8 +1889,7 @@
|
|||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "0.4.0",
|
||||
|
|
@ -1725,7 +1901,6 @@
|
|||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
|
@ -1856,6 +2031,28 @@
|
|||
"xmldom": "0.1.x"
|
||||
}
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz",
|
||||
"integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==",
|
||||
"requires": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"expand-template": "^2.0.3",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"napi-build-utils": "^1.0.1",
|
||||
"node-abi": "^2.7.0",
|
||||
"noop-logger": "^0.1.1",
|
||||
"npmlog": "^4.0.1",
|
||||
"pump": "^3.0.0",
|
||||
"rc": "^1.2.7",
|
||||
"simple-get": "^3.0.3",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"which-pm-runs": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"prepend-http": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
|
||||
|
|
@ -1875,8 +2072,7 @@
|
|||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"progress-stream": {
|
||||
"version": "1.2.0",
|
||||
|
|
@ -1905,7 +2101,6 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
|
|
@ -1927,7 +2122,6 @@
|
|||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"deep-extend": "^0.6.0",
|
||||
"ini": "~1.3.0",
|
||||
|
|
@ -2079,8 +2273,7 @@
|
|||
"safe-buffer": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
|
|
@ -2100,8 +2293,7 @@
|
|||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
},
|
||||
"semver-compare": {
|
||||
"version": "1.0.0",
|
||||
|
|
@ -2120,11 +2312,45 @@
|
|||
"type-fest": "^0.8.0"
|
||||
}
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||
},
|
||||
"simple-concat": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
|
||||
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
|
||||
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
|
||||
"requires": {
|
||||
"decompress-response": "^4.2.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"decompress-response": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
|
||||
"requires": {
|
||||
"mimic-response": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz",
|
||||
"integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"single-line-log": {
|
||||
"version": "1.1.2",
|
||||
|
|
@ -2201,7 +2427,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
|
@ -2218,7 +2443,6 @@
|
|||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
|
|
@ -2244,8 +2468,7 @@
|
|||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"dev": true
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
|
||||
},
|
||||
"sumchecker": {
|
||||
"version": "2.0.2",
|
||||
|
|
@ -2303,6 +2526,49 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"tar-fs": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
|
||||
"integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp": "^0.5.1",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz",
|
||||
"integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==",
|
||||
"requires": {
|
||||
"bl": "^3.0.0",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
|
||||
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"test-value": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
|
||||
|
|
@ -2405,7 +2671,6 @@
|
|||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
|
|
@ -2467,8 +2732,7 @@
|
|||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.3",
|
||||
|
|
@ -2497,6 +2761,19 @@
|
|||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"which-pm-runs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
|
||||
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
||||
"requires": {
|
||||
"string-width": "^1.0.2 || 2"
|
||||
}
|
||||
},
|
||||
"wordwrapjs": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
|
||||
|
|
@ -2509,8 +2786,7 @@
|
|||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "9.0.7",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"electron-reload": "^1.5.0",
|
||||
"node-hid": "^1.0.0",
|
||||
"node-wifi": "^2.0.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue