-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathcontroller.lisp
62 lines (55 loc) · 2.03 KB
/
controller.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
(defpackage #:NES-controller
(:nicknames #:controller)
(:use #:cl)
(:export #:make-controller
#:read-controller
#:write-controller
#:update-controller
#:controller
#:controller-buttons-callback
#:*keymap*
#:get-buttons))
(in-package :NES-controller)
(declaim (optimize (speed 3) (safety 1)))
(defstruct controller
(buttons
(make-array 8 :element-type '(unsigned-byte 8) :initial-element 0)
:type (simple-array (unsigned-byte 8) 1))
(index 0 :type (unsigned-byte 3))
(strobe 0 :type (unsigned-byte 1))
(buttons-callback (lambda()) :type function))
(defun read-controller (c)
(declare (controller c))
(let ((value (aref (controller-buttons c) (controller-index c))))
(setf
(controller-index c)
(if (not (ldb-test (byte 1 0) (controller-strobe c)))
(ldb (byte 3 0) (1+ (controller-index c)))
0))
value))
(defun write-controller (c val)
(declare (controller c) ((unsigned-byte 8) val))
(when (ldb-test (byte 1 0) (setf (controller-strobe c) (ldb (byte 1 0) val)))
(setf (controller-index c) 0)))
(defun update-controller (c)
(declare (controller c))
(when (ldb-test (byte 1 0) (controller-strobe c))
(setf (controller-buttons c) (the (simple-array (unsigned-byte 8) 1) (funcall (controller-buttons-callback c))))))
(defvar *keymap*
'((:a . :scancode-left)
(:b . :scancode-down)
(:select . :scancode-grave)
(:start . :scancode-tab)
(:up . :scancode-w)
(:down . :scancode-s)
(:left . :scancode-a)
(:right . :scancode-d))
"The mapping of the controller #1 buttons to SDL keycodes. Caveat Emptor, the
button-names are for reference, the mapping is determined by the Order.")
(defun get-buttons ()
(let ((buttons (make-array 8 :element-type '(unsigned-byte 8) :initial-element 0)))
(loop :for index :from 0
:for (button-name . button-key) :in *keymap*
:do
(setf (aref buttons index) (if (sdl2:keyboard-state-p button-key) 1 0)))
buttons))