123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- package main
- import (
- "flag"
- "fmt"
- "log"
- "net/http"
- "github.com/gvalkov/golang-evdev"
- )
- const (
- gamepadChanBufSize = 16
- // Logitech gamepad codes
- codeLeftAnalogX = 0
- codeLeftAnalogY = 1
- codeLeftAnalogZ = 2
- codeRightAnalogX = 3
- codeRightAnalogY = 4
- codeRightAnalogZ = 5
- codeDPadX = 16
- codeDPadY = 17
- codeA = 304
- codeB = 305
- codeX = 307
- codeY = 308
- codeLeft = 310
- codeRight = 311
- codeBack = 314
- codeStart = 315
- codeLogitech = 316
- codeLeftAnalog = 317
- codeRightAnalog = 318
- // event types
- button = iota
- axisX
- axisY
- axisZ
- )
- type event struct {
- code int
- value int32
- }
- func (e event) String() string {
- var code string
- switch e.code {
- case button:
- code = "button"
- case axisX:
- code = "X"
- case axisY:
- code = "Y"
- case axisZ:
- code = "Z"
- }
- return fmt.Sprintf("%v %v", code, e.value)
- }
- type gamepadEvents struct {
- leftAnalog, rightAnalog, dpad chan event
- a, b, x, y chan event
- left, right chan event
- back, start, logitech chan event
- }
- func main() {
- var (
- gamepad string
- listen string
- )
- flag.StringVar(&gamepad, "gamepad", "/dev/input/event0", "the gamepad device path")
- flag.StringVar(&listen, "listen", "localhost:8080", "the HTTP listen address and port")
- flag.Parse()
- if !evdev.IsInputDevice(gamepad) {
- log.Fatalf("%v is not an input device", gamepad)
- }
- device, err := evdev.Open(gamepad)
- if err != nil {
- log.Fatalf("error opening gamepad: %v", err)
- }
- events := &gamepadEvents{
- leftAnalog: make(chan event, gamepadChanBufSize),
- rightAnalog: make(chan event, gamepadChanBufSize),
- dpad: make(chan event, gamepadChanBufSize),
- a: make(chan event, gamepadChanBufSize),
- b: make(chan event, gamepadChanBufSize),
- x: make(chan event, gamepadChanBufSize),
- y: make(chan event, gamepadChanBufSize),
- left: make(chan event, gamepadChanBufSize),
- right: make(chan event, gamepadChanBufSize),
- back: make(chan event, gamepadChanBufSize),
- start: make(chan event, gamepadChanBufSize),
- logitech: make(chan event, gamepadChanBufSize),
- }
- go control(events)
- go gamepadRead(device, events)
- log.Fatalf("error listening and serving: %v", http.ListenAndServe(listen, nil))
- }
- func control(events *gamepadEvents) {
- for {
- select {
- case e := <-events.leftAnalog:
- log.Println("left analog", e)
- case e := <-events.rightAnalog:
- log.Println("right analog", e)
- case e := <-events.dpad:
- log.Println("dpad", e)
- case e := <-events.a:
- log.Println("a", e)
- case e := <-events.b:
- log.Println("b", e)
- case e := <-events.x:
- log.Println("x", e)
- case e := <-events.y:
- log.Println("y", e)
- case e := <-events.left:
- log.Println("left", e)
- case e := <-events.right:
- log.Println("right", e)
- case e := <-events.back:
- log.Println("back", e)
- case e := <-events.start:
- log.Println("start", e)
- case e := <-events.logitech:
- log.Println("logitech", e)
- }
- }
- }
- func gamepadRead(device *evdev.InputDevice, events *gamepadEvents) {
- for {
- e, err := device.ReadOne()
- if err != nil {
- log.Fatalf("error reading from gamepad: %v", err)
- }
- switch e.Type {
- case evdev.EV_ABS:
- switch e.Code {
- case codeLeftAnalogX:
- events.leftAnalog <- event{code: axisX, value: e.Value}
- case codeLeftAnalogY:
- events.leftAnalog <- event{code: axisY, value: e.Value}
- case codeLeftAnalogZ:
- events.leftAnalog <- event{code: axisZ, value: e.Value}
- case codeRightAnalogX:
- events.rightAnalog <- event{code: axisX, value: e.Value}
- case codeRightAnalogY:
- events.rightAnalog <- event{code: axisY, value: e.Value}
- case codeRightAnalogZ:
- events.rightAnalog <- event{code: axisZ, value: e.Value}
- case codeDPadX:
- events.dpad <- event{code: axisX, value: e.Value}
- case codeDPadY:
- events.dpad <- event{code: axisY, value: e.Value}
- }
- case evdev.EV_KEY:
- switch e.Code {
- case codeA:
- events.a <- event{code: button, value: e.Value}
- case codeB:
- events.b <- event{code: button, value: e.Value}
- case codeX:
- events.x <- event{code: button, value: e.Value}
- case codeY:
- events.y <- event{code: button, value: e.Value}
- case codeLeft:
- events.left <- event{code: button, value: e.Value}
- case codeRight:
- events.right <- event{code: button, value: e.Value}
- case codeBack:
- events.back <- event{code: button, value: e.Value}
- case codeStart:
- events.start <- event{code: button, value: e.Value}
- case codeLogitech:
- events.logitech <- event{code: button, value: e.Value}
- case codeLeftAnalog:
- events.leftAnalog <- event{code: button, value: e.Value}
- case codeRightAnalog:
- events.rightAnalog <- event{code: button, value: e.Value}
- }
- }
- }
- }
|