main.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "log"
  6. "net/http"
  7. "github.com/gvalkov/golang-evdev"
  8. )
  9. const (
  10. gamepadChanBufSize = 16
  11. // Logitech gamepad codes
  12. codeLeftAnalogX = 0
  13. codeLeftAnalogY = 1
  14. codeLeftAnalogZ = 2
  15. codeRightAnalogX = 3
  16. codeRightAnalogY = 4
  17. codeRightAnalogZ = 5
  18. codeDPadX = 16
  19. codeDPadY = 17
  20. codeA = 304
  21. codeB = 305
  22. codeX = 307
  23. codeY = 308
  24. codeLeft = 310
  25. codeRight = 311
  26. codeBack = 314
  27. codeStart = 315
  28. codeLogitech = 316
  29. codeLeftAnalog = 317
  30. codeRightAnalog = 318
  31. // event types
  32. button = iota
  33. axisX
  34. axisY
  35. axisZ
  36. )
  37. type event struct {
  38. code int
  39. value int32
  40. }
  41. func (e event) String() string {
  42. var code string
  43. switch e.code {
  44. case button:
  45. code = "button"
  46. case axisX:
  47. code = "X"
  48. case axisY:
  49. code = "Y"
  50. case axisZ:
  51. code = "Z"
  52. }
  53. return fmt.Sprintf("%v %v", code, e.value)
  54. }
  55. type gamepadEvents struct {
  56. leftAnalog, rightAnalog, dpad chan event
  57. a, b, x, y chan event
  58. left, right chan event
  59. back, start, logitech chan event
  60. }
  61. func main() {
  62. var (
  63. gamepad string
  64. listen string
  65. )
  66. flag.StringVar(&gamepad, "gamepad", "/dev/input/event0", "the gamepad device path")
  67. flag.StringVar(&listen, "listen", "localhost:8080", "the HTTP listen address and port")
  68. flag.Parse()
  69. if !evdev.IsInputDevice(gamepad) {
  70. log.Fatalf("%v is not an input device", gamepad)
  71. }
  72. device, err := evdev.Open(gamepad)
  73. if err != nil {
  74. log.Fatalf("error opening gamepad: %v", err)
  75. }
  76. events := &gamepadEvents{
  77. leftAnalog: make(chan event, gamepadChanBufSize),
  78. rightAnalog: make(chan event, gamepadChanBufSize),
  79. dpad: make(chan event, gamepadChanBufSize),
  80. a: make(chan event, gamepadChanBufSize),
  81. b: make(chan event, gamepadChanBufSize),
  82. x: make(chan event, gamepadChanBufSize),
  83. y: make(chan event, gamepadChanBufSize),
  84. left: make(chan event, gamepadChanBufSize),
  85. right: make(chan event, gamepadChanBufSize),
  86. back: make(chan event, gamepadChanBufSize),
  87. start: make(chan event, gamepadChanBufSize),
  88. logitech: make(chan event, gamepadChanBufSize),
  89. }
  90. go control(events)
  91. go gamepadRead(device, events)
  92. log.Fatalf("error listening and serving: %v", http.ListenAndServe(listen, nil))
  93. }
  94. func control(events *gamepadEvents) {
  95. for {
  96. select {
  97. case e := <-events.leftAnalog:
  98. log.Println("left analog", e)
  99. case e := <-events.rightAnalog:
  100. log.Println("right analog", e)
  101. case e := <-events.dpad:
  102. log.Println("dpad", e)
  103. case e := <-events.a:
  104. log.Println("a", e)
  105. case e := <-events.b:
  106. log.Println("b", e)
  107. case e := <-events.x:
  108. log.Println("x", e)
  109. case e := <-events.y:
  110. log.Println("y", e)
  111. case e := <-events.left:
  112. log.Println("left", e)
  113. case e := <-events.right:
  114. log.Println("right", e)
  115. case e := <-events.back:
  116. log.Println("back", e)
  117. case e := <-events.start:
  118. log.Println("start", e)
  119. case e := <-events.logitech:
  120. log.Println("logitech", e)
  121. }
  122. }
  123. }
  124. func gamepadRead(device *evdev.InputDevice, events *gamepadEvents) {
  125. for {
  126. e, err := device.ReadOne()
  127. if err != nil {
  128. log.Fatalf("error reading from gamepad: %v", err)
  129. }
  130. switch e.Type {
  131. case evdev.EV_ABS:
  132. switch e.Code {
  133. case codeLeftAnalogX:
  134. events.leftAnalog <- event{code: axisX, value: e.Value}
  135. case codeLeftAnalogY:
  136. events.leftAnalog <- event{code: axisY, value: e.Value}
  137. case codeLeftAnalogZ:
  138. events.leftAnalog <- event{code: axisZ, value: e.Value}
  139. case codeRightAnalogX:
  140. events.rightAnalog <- event{code: axisX, value: e.Value}
  141. case codeRightAnalogY:
  142. events.rightAnalog <- event{code: axisY, value: e.Value}
  143. case codeRightAnalogZ:
  144. events.rightAnalog <- event{code: axisZ, value: e.Value}
  145. case codeDPadX:
  146. events.dpad <- event{code: axisX, value: e.Value}
  147. case codeDPadY:
  148. events.dpad <- event{code: axisY, value: e.Value}
  149. }
  150. case evdev.EV_KEY:
  151. switch e.Code {
  152. case codeA:
  153. events.a <- event{code: button, value: e.Value}
  154. case codeB:
  155. events.b <- event{code: button, value: e.Value}
  156. case codeX:
  157. events.x <- event{code: button, value: e.Value}
  158. case codeY:
  159. events.y <- event{code: button, value: e.Value}
  160. case codeLeft:
  161. events.left <- event{code: button, value: e.Value}
  162. case codeRight:
  163. events.right <- event{code: button, value: e.Value}
  164. case codeBack:
  165. events.back <- event{code: button, value: e.Value}
  166. case codeStart:
  167. events.start <- event{code: button, value: e.Value}
  168. case codeLogitech:
  169. events.logitech <- event{code: button, value: e.Value}
  170. case codeLeftAnalog:
  171. events.leftAnalog <- event{code: button, value: e.Value}
  172. case codeRightAnalog:
  173. events.rightAnalog <- event{code: button, value: e.Value}
  174. }
  175. }
  176. }
  177. }