package inputs import ( "fmt" "github.com/karalabe/hid" ) type JoystickEvent struct { Time uint32 // Event timestamp in milliseconds Value int16 // Value of the event (button press or axis movement) Type uint8 // Event type (button or axis) Number uint8 // Axis/button number } const ( JS_EVENT_BUTTON = 0x01 // Button pressed/released JS_EVENT_AXIS = 0x02 // Joystick moved JS_EVENT_INIT = 0x80 // Initial state of device ) type Controller struct { Device *hid.Device } func (c *Controller) ReadState(buf []byte) (*ControllerState, error) { _, err := c.Device.Read(buf) if err != nil { return nil, err } x := buf[0] // Horizontal axis (0–255) y := buf[1] // Vertical axis (0–255) buttons := buf[6] // Buttons as bitfield state := ControllerState{ Joystick: Vec2B{x, y}, Buttons: buttons, } return &state, nil } type Vec2B struct { X byte `json:"x"` Y byte `json:"y"` } type ControllerState struct { Id int `json:"id"` Joystick Vec2B `json:"joystick"` Buttons byte `json:"buttons"` } type ConjureControllerButton int const ( ButtonPower ConjureControllerButton = iota //0 ButtonStart Button1 Button2 Button3 ButtonA ButtonB ButtonC // 7 ) var ConjureControllerButtons = []ConjureControllerButton{ ButtonStart, ButtonPower, Button1, Button2, Button3, ButtonA, ButtonB, ButtonC, } func (s ConjureControllerButton) String() string { switch s { case ButtonA: return "ButtonA" case ButtonB: return "ButtonB" case ButtonC: return "ButtonC" case Button1: return "Button1" case Button2: return "Button2" case Button3: return "Button3" case ButtonStart: return "ButtonStart" case ButtonPower: return "ButtonPower" default: return "Unknown" } } func Start(onStateChange func(ControllerState)) { fmt.Println("Opening devices") const vendorID = 0x0079 const productID = 0x0006 devices := hid.Enumerate(vendorID, productID) if len(devices) == 0 { fmt.Printf("Device with VID:PID %04X:%04X not found\n", vendorID, productID) return } for i, d := range devices { fmt.Printf("Found device %d: %s - VID:%04X PID:%04X\n", i, d.Product, d.VendorID, d.ProductID) go func(i int, d hid.DeviceInfo) { device, err := d.Open() if err != nil { fmt.Printf("Failed to open device %d: %v\n", i, err) return } defer device.Close() controller := Controller{Device: device} buf := make([]byte, 32) fmt.Printf("Reading data from device %d... Press Ctrl+C to exit\n", i) for { state, err := controller.ReadState(buf) if err != nil { fmt.Printf("Read error on device %d: %v\n", i, err) return } state.Id = i // TODO Samuel please fix help me if (state.Buttons != 0 || state.Joystick.X != 127 || state.Joystick.Y != 127) && !(state.Id == 0 && state.Buttons == 128 && state.Joystick.X != 127 && state.Joystick.Y != 127) { // fmt.Printf("Id: %d - %d buttons ", state.Id, state.Buttons) onStateChange(*state) } } }(i, d) } // Prevent the function from exiting select {} } // handleJoystickEvent processes joystick events. func handleJoystickEvent(e JoystickEvent) { if e.Type&JS_EVENT_INIT != 0 { // Ignore initial state events return } if e.Type&JS_EVENT_BUTTON != 0 { if e.Value == 1 { fmt.Printf("Button %d pressed\n", e.Number) } else { fmt.Printf("Button %d released\n", e.Number) } } if e.Type&JS_EVENT_AXIS != 0 { fmt.Printf("Axis %d moved to %d\n", e.Number, e.Value) } }