0xcafed00d / joystick

Go Joystick API
MIT License
62 stars 17 forks source link

Xbox Controller #9

Open notnil opened 3 months ago

notnil commented 3 months ago

Not sure if this is an intended use case but I am trying to map to Xbox wireless controller buttons. All of them work except the D-Pad and Left / Right triggers. I am testing on Mac but targeting Linux. Any ideas? Adapted from https://github.com/orsinium-labs/gamepad for the latest Xbox.

package gamepad

import (
    "fmt"

    "github.com/0xcafed00d/joystick"
)

type GamePad struct {
    js joystick.Joystick
}

func NewGamepad(id int) (*GamePad, error) {
    js, err := joystick.Open(id)
    if err != nil {
        return nil, err
    }
    return &GamePad{js: js}, nil
}

// The current state of the gamepad
func (g *GamePad) State() (State, error) {
    jState, err := g.js.Read()
    // print the buttons integer in binary
    fmt.Printf("Buttons: %b\n", jState.Buttons)
    for i, ax := range jState.AxisData {
        fmt.Printf("Axis %d: %d\n", i, ax)
    }
    state := newState(jState)
    return state, err
}

type Stick struct {
    X int
    Y int
}

type State struct {
    A                bool
    B                bool
    X                bool
    Y                bool
    LeftBumper       bool
    RightBumper      bool
    Back             bool
    Start            bool
    Guide            bool
    LeftStickButton  bool
    RightStickButton bool
    DPadUp           bool
    DPadDown         bool
    DPadLeft         bool
    DPadRight        bool
    LeftStick        Stick
    RightStick       Stick
}

func newState(state joystick.State) State {
    return State{
        A:                (state.Buttons & 0b_0001) > 0,
        B:                (state.Buttons & 0b_0010) > 0,
        X:                (state.Buttons & 0b_1000) > 0,
        Y:                (state.Buttons & 0b_0001_0000) > 0,
        LeftBumper:       state.Buttons&0b_0100_0000 > 0,
        RightBumper:      state.Buttons&0b_1000_0000 > 0,
        Back:             (state.Buttons & 0b_0100_0000_0000) > 0,
        Start:            (state.Buttons & 0b_1000_0000_0000) > 0,
        Guide:            (state.Buttons & 0b_0001_0000_0000_0000) > 0,
        LeftStickButton:  (state.Buttons & 0b_0010_0000_0000_0000) > 0,
        RightStickButton: (state.Buttons & 0b_0100_0000_0000_0000) > 0,
        LeftStick: Stick{
            X: state.AxisData[0],
            Y: state.AxisData[1],
        },
        RightStick: Stick{
            X: state.AxisData[2],
            Y: state.AxisData[3],
        },
    }
}
0xcafed00d commented 3 months ago

The dpad is not treated as buttons, but rather as 2 additional axis, also the left and right triggers are treated as a single combined axis. This is a limitation of the HID protocol used by the controller when not using the XINPUT interface in windows.