Initial commit.
[existenz.git] / client / joystick.lisp
1 ;;; -*- mode: lisp; syntax: common-lisp; package: existenz-client; coding: utf-8-unix; -*-
2
3 (in-package #:existenz-client)
4 \f
5 ;; cat /dev/input/event6 |hexdump
6
7 (define-enum linux-input-event-type (u16)
8   ev-syn       #x00
9   ev-key       #x01
10   ev-rel       #x02
11   ev-abs       #x03
12   ev-msc       #x04
13   ev-sw        #x05
14   ev-led       #x11
15   ev-snd       #x12
16   ev-rep       #x14
17   ev-ff        #x15
18   ev-pwr       #x16
19   ev-ff-status #x17
20   ev-max       #x1f)
21
22 (define-enum linux-input-event-syn (u16)
23   syn-report    0
24   syn-config    1
25   syn-mt-report 2)
26
27 (define-enum linux-input-event-button (u16)
28   btn-mouse    #x110
29   btn-left     #x110
30   btn-right    #x111
31   btn-middle   #x112
32
33   btn-joystick #x120
34   btn-trigger  #x120
35   btn-thumb    #x121
36   btn-thumb2   #x122
37   btn-top      #x123
38   btn-top2     #x124
39   btn-pinkie   #x125
40
41   btn-gamepad  #x130
42   btn-a        #x130
43   btn-b        #x131
44   btn-c        #x132
45   btn-x        #x133
46   btn-y        #x134
47   btn-z        #x135)
48
49 (define-enum linux-input-event-rel (u16)
50   rel-x #x00
51   rel-y #x01
52   rel-z #x02
53   rel-rx #x03
54   rel-ry #x04
55   rel-rz #x05
56   rel-hwheel #x06
57   rel-dial   #x07
58   rel-wheel  #x08
59   rel-misc   #x09)
60
61 (define-binary-struct linux-input-event ()
62   (tv-sec 0 :binary-type s64)
63   (tv-usec 0 :binary-type s64)
64   (type 0 :binary-type linux-input-event-type)
65   (code 0 :binary-type u16)
66   (value 0 :binary-type s32))
67
68 (defun read-input-event (pathname)
69   (with-open-file (stream pathname :element-type '(unsigned-byte 8))
70     (loop
71       (when (listen stream)
72         (let ((event (read-binary 'linux-input-event stream)))
73           (when (eq (linux-input-event-type event) 'ev-key)
74             (setf (linux-input-event-code event)
75                   (enum-symbolic-value 'linux-input-event-button
76                                        (linux-input-event-code event)))
77             (logv event)))))))
78
79 (logv 'idle)
80 (let ((mouse-rel-x 0)
81       (mouse-rel-y 0))
82   (iolib:set-io-handler event-base (sb-sys:fd-stream-fd mouse) :read
83                         (lambda (fd event exception)
84                           (let ((event (read-binary 'linux-input-event mouse)))
85                             (when (eq (linux-input-event-type event) 'ev-key)
86                               (setf (linux-input-event-code event)
87                                     (enum-symbolic-value 'linux-input-event-button
88                                                          (linux-input-event-code event))))
89                             (when (eq (linux-input-event-type event) 'ev-rel)
90                               (setf (linux-input-event-code event)
91                                     (enum-symbolic-value 'linux-input-event-rel
92                                                          (linux-input-event-code event)))
93                               (case (linux-input-event-code event)
94                                 (rel-x (incf mouse-rel-x (linux-input-event-value event)))
95                                 (rel-y (incf mouse-rel-y (linux-input-event-value event))))))))
96   (iolib:event-dispatch event-base :timeout 0.01)
97   (iolib:remove-fd-handlers event-base (sb-sys:fd-stream-fd mouse))
98   (setf rotate-y (* (- mouse-rel-x) (to-radian 0.5)))
99   (setf rotate-x (* (- mouse-rel-y) (to-radian 0.5))))