Skip to content

Use Nintendo Switch Joy-Cons as input devices (Bluetooth)

License

Notifications You must be signed in to change notification settings

suchipi/switch-joy-con

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

switch-joy-con

Use Nintendo Switch Joy-Cons as input devices (Bluetooth).

Features

  • Run callback(s) when buttons are pressed/released/changed
  • Toggle player LEDs

Installation

npm install --save switch-joy-con

Usage

const { listConnectedJoyCons } = require("switch-joy-con");

// First, list all the Joy-Cons connected to the computer.
const devices = listConnectedJoyCons();
console.log(devices);
// [
//   {
//     vendorId: 1406,
//     productId: 8198,
//     path: 'IOService:/IOResources/IOBluetoothHCIController/AppleBroadcomBluetoothHostController/IOBluetoothDevice/IOBluetoothL2CAPChannel/IOBluetoothHIDDriver',
//     serialNumber: '94-58-cb-a6-1b-86',
//     manufacturer: 'Unknown',
//     product: 'Joy-Con (L)',
//     release: 1,
//     interface: -1,
//     usagePage: 1,
//     usage: 5,
//     open: [Function: open]
//   },
//   {
//     vendorId: 1406,
//     productId: 8199,
//     path: 'IOService:/IOResources/IOBluetoothHCIController/AppleBroadcomBluetoothHostController/IOBluetoothDevice/IOBluetoothL2CAPChannel/IOBluetoothHIDDriver',
//     serialNumber: '94-58-cb-a5-cb-9d',
//     manufacturer: 'Unknown',
//     product: 'Joy-Con (R)',
//     release: 1,
//     interface: -1,
//     usagePage: 1,
//     usage: 5,
//     open: [Function: open]
//   }
// ]

// Decide which to use, and then call `open` on it.
const left = devices[0].open();

// NOTE: for third-party Joy-Cons, you may have to pass a side string:
// const left = devices[0].open("left");

// The `buttons` property always contains up-to-date buttons state:
console.log(left.buttons);
// {
//   dpadUp: false,
//   dpadDown: false,
//   dpadLeft: false,
//   dpadRight: false,
//   minus: false,
//   screenshot: false,
//   sl: false,
//   sr: false,
//   l: false,
//   zl: false,
//   analogStickPress: false,
//   analogStick: left.Directions.NEUTRAL
// }

// A "change" event will be emitted whenever the button state changes
left.on("change", () => {
  console.log(left.buttons);
});

// Whenever a button is pressed or released, a `down:${buttonName}` or `up:${buttonName}` event is emitted.
left.on("down:minus", () => {
  console.log("minus pressed down");
});
left.on("up:minus", () => {
  console.log("minus depressed");
});

// a `change:${buttonName}` event is also emitted:
left.on("change:minus", (pressed) => {
  console.log(`minus is now: ${pressed ? "pressed" : "unpressed"}`);
});

// The `analogStick` "button" is a number. Use the `Directions` property on the
// instance to understand its value:
left.on("change:analogStick", (value) => {
  switch (value) {
    case left.Directions.UP: {
      console.log("up");
      break;
    }
    case left.Directions.UP_RIGHT: {
      console.log("up-right");
      break;
    }
    case left.Directions.RIGHT: {
      console.log("right");
      break;
    }
    case left.Directions.DOWN_RIGHT: {
      console.log("down-right");
      break;
    }
    case left.Directions.DOWN: {
      console.log("down");
      break;
    }
    case left.Directions.DOWN_LEFT: {
      console.log("down-left");
      break;
    }
    case left.Directions.LEFT: {
      console.log("left");
      break;
    }
    case left.Directions.UP_LEFT: {
      console.log("up-left");
      break;
    }
    case left.Directions.UP_RIGHT: {
      console.log("up-right");
      break;
    }
    case left.Directions.NEUTRAL: {
      console.log("neutral");
      break;
    }
  }
});

// When you're done with the device, call `close` on it:
left.close();

// Usage with a right-side Joy-Con is the same, but it has different button names:
const right = devices[1].open();
console.log(right.buttons);
// {
//   a: false,
//   x: false,
//   b: false,
//   y: false,
//   plus: false,
//   home: false,
//   sl: false,
//   sr: false,
//   r: false,
//   zr: false,
//   analogStickPress: false,
//   analogStick: right.Directions.NEUTRAL
// }

// If you need to tell whether a Joy-Con is a left or right Joy-Con, use the `side` property:
console.log(left.side); // "left"
console.log(right.side); // "right"

API Documentation

The "switch-joy-con" module has one named export, listConnectedJoyCons.

listConnectedJoyCons() => Array<JoyConDescription>

Returns an array of objects, each describing a connected Joy-Con.

The objects have the following properties:

interface JoyConDescription {
  vendorId: number;
  productId: number;
  path: string;
  serialNumber: string;
  manufacturer: string;
  product: string;
  release: number;
  interface: number;
  usagePage: number;
  usage: number;
  open: () => JoyCon;
}

The most important thing here is the open method, which returns a JoyCon instance.

JoyCon

You can obtain a JoyCon instance by calling open on a JoyConDescription, as returned by listConnectedJoyCons().

Each JoyCon adheres to the following interface:

interface JoyCon extends EventEmitter {
  // Whether the Joy-Con attaches to the left or right side of a Switch.
  // The buttons will differ depending on this.
  side: "left" | "right";

  // An object containing the current button state.
  buttons:  // If `side` is "left", `buttons` will have the following properties:
    | {
        // If a button is pressed, its value will be `true`. Otherwise, it will be `false`.
        dpadUp: boolean;
        dpadDown: boolean;
        dpadLeft: boolean;
        dpadRight: boolean;
        minus: boolean;
        screenshot: boolean;
        sl: boolean;
        sr: boolean;
        l: boolean;
        zl: boolean;
        analogStickPress: boolean;

        // Use the `Directions` property on the JoyCon to understand this number.
        analogStick: number;
      }
    // Otherwise (if `side` is "right"), `buttons` will have these properties:
    | {
        // If a button is pressed, its value will be `true`. Otherwise, it will be `false`.
        a: boolean;
        x: boolean;
        b: boolean;
        y: boolean;
        plus: boolean;
        home: boolean;
        sl: boolean;
        sr: boolean;
        r: boolean;
        zr: boolean;
        analogStickPress: boolean;

        // Use the `Directions` property on the JoyCon to understand this number.
        analogStick: number;
      };

  // The analog stick direction constants for this Joy-Con. Note that these differ
  // between left/right Joy-Cons, so always rely on this property.
  Directions: {
    LEFT: number;
    UP_LEFT: number;
    UP: number;
    UP_RIGHT: number;
    RIGHT: number;
    DOWN_RIGHT: number;
    DOWN: number;
    DOWN_LEFT: number;
    NEUTRAL: number;
  };

  // Call this method when you are done using the Joy-Con.
  // It won't be disconnected from Bluetooth, but the handle
  // will be released so it can be used by another application.
  close();

  // LED values that can be provided to the `setPlayerLEDs` method.
  LED_VALUES: {
    // Indicates that the LED in this slot should be lit up solid.
    ONE: number;
    TWO: number;
    THREE: number;
    FOUR: number;

    // Indicates that the LED in this slot should be flashing on and off.
    ONE_FLASH: number;
    TWO_FLASH: number;
    THREE_FLASH: number;
    FOUR_FLASH: number;
  };

  // Set which player LEDs are lit. Use value(s) from the `LED_VALUES` property.
  // To turn on more than one LED, add them together; eg:
  // setPlayerLEDs(LED_VALUES.ONE + LED_VALUES.TWO)
  setPlayerLEDs(value: number);
}

JoyCons are also EventEmitters, and they emit the following events:

  • change - Button state has changed. Inspect the buttons property on the device for more info.
  • change:${buttonName} - A specific button changed state. The event listener will be called with one argument, containing the new button value.
  • down:${buttonName} - A specific button is now being held down.
  • up:${buttonName} - A specific button is no longer being held down.

List of button names:

  • a
  • x
  • b
  • y
  • plus
  • home
  • l
  • r
  • zl
  • zr
  • dpadUp
  • dpadDown
  • dpadLeft
  • dpadRight
  • minus
  • screenshot
  • sl
  • sr
  • analogStickPress
  • analogStick

License

MIT

About

Use Nintendo Switch Joy-Cons as input devices (Bluetooth)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published