JoyShockLibrary

repository·master·Indexed 43 days ago

https://github.com/jibbsmart/joyshocklibrary

A Windows-based library providing native support for high-end controllers, including DualShock 4, DualSense, Joy-Cons, and Pro Controllers. It focuses on exposing advanced input features such as gyroscope (IMU) data, motion sensing, and sensor-fused orientation via MOTION_STATE. The library supports C/C++ and C#/Unity integration, offering tools for gyro calibration, coordinate space transformation, and rumble control.

Tokens
2.5K
Snippets
2
Records
15
Agent score
6%

What's inside JoyShockLibrary

  1. Overview of JoyShockLibrary

    master

    JoyShockLibrary is a library designed to enable native support for modern game controllers in PC games. It specifically targets controllers with gyroscope (gyro) capabilities, including:

    • Sony PlayStation DualShock 4 (DS4)
    • Sony PlayStation DualSense
    • Nintendo Switch Joy-Cons (used in pairs)
    • Nintendo Switch Pro Controller

    The library is currently compiled for Windows and provides a way for developers to access versatile input features like motion sensing that are often missing in standard implementations.

  2. Access IMU and Motion data

    master

    JoyShockLibrary provides access to the Inertial Measurement Unit (IMU) and processed motion data.

    IMU_STATE

    Contains raw sensor data:

    • accelX, accelY, accelZ: Accelerometer in g-force.
    • gyroX, gyroY, gyroZ: Gyroscope angular velocity in degrees per second (dps).

    MOTION_STATE

    Contains sensor-fused orientation data:

    • quatW, quatX, quatY, quatZ: Quaternion representing device orientation.
    • accelX, accelY, accelZ: Local acceleration (gravity removed).
    • gravX, gravY, gravZ: Local gravity direction.

    Note on Quaternions: Quaternions are useful for 3D orientation but suffer from "yaw drift". For mouse-like aiming or cursor control, it is highly recommended to use calibrated gyro angular velocities via JslGetAndFlushAccumulatedGyro instead.

  3. Understand Gyro poll rate on Nintendo devices

    master

    Nintendo devices report IMU data every 15ms, even though the hardware reports every 5ms. Each 15ms report contains the last 3 gyro and accelerometer samples.

    JoyShockLibrary averages these 3 samples to provide a single IMU state. While this is sufficient for 2D cursor control, it may result in slightly less accurate 3D rotations compared to processing the 3 reports separately.

  4. Understand GamepadMotionHelpers integration

    master

    JoyShockLibrary offloads gravity calculation and gyro calibration to the GamepadMotionHelpers library.

    When using a newer version of GamepadMotionHelpers with auto-calibration enabled:

    • Calibration is applied rapidly at first.
    • The application rate slows down as the library gains more confidence in the current calibration.
    • Calibration can be reset at any time.
  5. Configure Gyro Space

    master

    You can transform gyro input into different coordinate spaces using JslSetGyroSpace(int deviceId, int gyroSpace). This affects JslGetGyro* functions, JslGetIMUState, and IMU callbacks.

    Available Spaces:

    • 0 (Local Space): Default. No transformation applied. Use this if you want to handle yaw/roll mapping manually.
    • 1 (World Space): Uses gravity to determine "up" and calculates new axes for horizontal/vertical movement. Adapts to player preference but can inherit errors from gravity calculations.
    • 2 (Player Space): Similar to World Space but uses gravity more loosely to avoid accumulating errors from gravity calculations. Recommended for standard controllers where the screen is not attached to the controller.
  6. Calibrate the Gyroscope

    master

    JoyShockLibrary includes tools to handle gyroscope drift through manual and automatic calibration.

    Manual Calibration

    • JslStartContinuousCalibration(int deviceId): Starts collecting gyro data to calculate an ongoing average to offset output.
    • JslPauseContinuousCalibration(int deviceId): Stops collecting data but preserves the current offset.
    • JslResetContinuousCalibration(int deviceId): Deletes all accumulated calibration data.
    • JslSetCalibrationOffset(int deviceId, float xOffset, float yOffset, float zOffset): Manually set the offset.
    • JslGetCalibrationOffset(int deviceId, float& xOffset, float& yOffset, float& zOffset): Retrieve the current offset.

    Automatic Calibration

    • JslSetAutomaticCalibration(int deviceId, bool enabled): Enables automatic recalibration when the controller is detected as being at rest or held still.
    • JslGetAutoCalibrationStatus(int deviceId): Returns a JSL_AUTO_CALIBRATION status indicating if auto-calibration is enabled, if the controller is currently still, and the confidence level of the calibration.
  7. Download and integrate JoyShockLibrary

    master

    To use JoyShockLibrary in your project, download the latest release from the GitHub Releases page.

    Depending on your development environment, you will need the following files:

    • C/C++ Development: Use the provided 64-bit or 32-bit Windows .dll and the JoyShockLibrary.h header file.
    • C# / Unity Development: Use the provided 64-bit or 32-bit Windows .dll and the JoyShockLibrary.cs file.

    Note: The .cs file may not be fully up to date with the latest features but serves as a functional starting point for Unity integration.

  8. Migrate from JoyShockLibrary v2 to v3

    master

    JoyShockLibrary v3 introduced changes to function behaviors:

    JslConnectDevices behavior change

    JslConnectDevices no longer calls JslDisconnectAndDisposeAll automatically. It now only establishes new connections without disrupting existing ones.

    • Requirement: If you need to clear all previous connections before connecting new ones, you must explicitly call JslDisconnectAndDisposeAll before calling JslConnectDevices.
  9. Initialize and manage device connections

    master

    To use the library, you must first register connected devices and obtain their handles.

    1. JslConnectDevices(): Registers connected devices. Returns the number of devices connected. It is thread-safe and can be called at any time (e.g., on OS device change notifications) without interrupting existing connections.
    2. JslGetConnectedDeviceHandles(int* deviceHandleArray, int size): Fills an array with the handles for all connected devices. Use the count returned by JslConnectDevices to ensure you fill the array correctly.
    3. JslStillConnected(int deviceId): Checks if a specific device is still connected.
    4. JslDisconnectAndDisposeAll(): Disconnects all devices and stops polling.
    int numDevices = JslConnectDevices();
    if (numDevices > 0) {
        int handles[numDevices];
        JslGetConnectedDeviceHandles(handles, numDevices);
        // Use handles[0], handles[1], etc.
    }
  10. Handle Bluetooth connectivity issues

    master

    Joy-Cons and Pro Controllers typically connect via Bluetooth. Some Bluetooth adapters may cause input lag, especially when multiple devices (like a pair of Joy-Cons) are connected simultaneously. This is a hardware/adapter limitation and cannot be resolved by JoyShockLibrary.

    Note: Experimental support for connecting supported Switch controllers via USB is available.

  11. Set Controller Rumble

    master

    Use JslSetRumble(int deviceId, int smallRumble, int bigRumble) to trigger vibration.

    • Intensity: Values range from 0 to 255.
    • DualShock 4: Supports two independent rumble types (small and big) that can be set simultaneously.
    • Nintendo: Supports rumble, but JoyShockLibrary does not yet support Nintendo's "HD Rumble" specifically.