-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathinput.scm
More file actions
199 lines (170 loc) · 6.56 KB
/
input.scm
File metadata and controls
199 lines (170 loc) · 6.56 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
;;;; input.scm
;;;; Imported by window.scm
(export make-bindings
make-binding
binding?
binding-id
add-binding
get-binding
remove-binding
change-binding
key-bindings
push-key-bindings
pop-key-bindings
char-callback
mouse-bindings
push-mouse-bindings
pop-mouse-bindings
cursor-movement-callback
scroll-callback
get-cursor-position
set-cursor-position
get-cursor-world-position)
(define-record-type binding
%make-binding
#t
(id) (key) (scancode?) (mods) (press) (release) (pressed?))
(define-record-printer (binding b out)
(fprintf out "#<binding ~S>"
(binding-id b)))
(define (make-binding id key #!key scancode? mods (press (lambda () #f)) (release (lambda () #f))
toggle reverse-toggle)
(let ((mods (if mods
(apply bitwise-ior mods)
0)))
(cond
(toggle
(%make-binding id key scancode? mods
(lambda () (toggle (add1 (toggle))))
(lambda () (toggle (sub1 (toggle))))
#f))
(reverse-toggle
(%make-binding id key scancode? mods
(lambda () (reverse-toggle (sub1 (reverse-toggle))))
(lambda () (reverse-toggle (add1 (reverse-toggle))))
#f))
(else (%make-binding id key scancode? mods press release #f)))))
(define (make-bindings bindings)
(map (lambda (b) (apply make-binding b)) bindings))
(define (add-binding bindings binding)
(cons (apply make-binding binding)
bindings))
(define (get-binding bindings id)
(find (lambda (b) (equal? (binding-id b) id))
bindings))
(define (remove-binding bindings id)
(remove (lambda (b) (equal? (binding-id b) id))
bindings))
(define (change-binding bindings id binding)
(if* (find (lambda (b) (equal? (binding-id b) id))
bindings)
(cons (apply make-binding binding)
(delete it bindings))
(error 'set-binding! "Not a binding id:" id)))
;;; Keyboard
(define key-bindings (make-parameter '()))
(define (push-key-bindings bindings)
(cond
((list? bindings)
(key-callback key-binding-event))
(else (key-callback bindings)))
(key-bindings (cons bindings
(key-bindings))))
(define (pop-key-bindings)
(unless (null? (key-bindings))
(key-bindings (cdr (key-bindings)))
(unless (null? (key-bindings))
(cond
((list? (car (key-bindings)))
(key-callback key-binding-event))
(else (key-callback (car (key-bindings))))))))
(define (key-binding-event key scancode action mods)
(when (not (null? (key-bindings)))
(let ((bindings (car (key-bindings))))
(cond
((= action %+press+)
(let loop ((bindings bindings))
(unless (null? bindings)
(let ((binding (car bindings)))
(if (and (if (binding-scancode? binding)
(= (binding-key binding) scancode)
(= (binding-key binding) key))
(= (binding-mods binding) mods))
(begin ((binding-press binding))
(binding-pressed?-set! binding #t))
(loop (cdr bindings)))))))
;; Release for all bindings that share the same key, even with different mods
((= action %+release+)
(for-each (lambda (binding)
(when (and (if (binding-scancode? binding)
(= (binding-key binding) scancode)
(= (binding-key binding) key))
(binding-pressed? binding))
((binding-release binding))
(binding-pressed?-set! binding #f)))
bindings))))))
(define key-callback (make-parameter (lambda (key scancode action mods) #f)))
(define char-callback (make-parameter (lambda (char) #f)))
(define-external (hpgKeyCallback (c-pointer window) (int key) (int scancode)
(int action) (int mods))
void
((key-callback) key scancode action mods))
(define-external (hpgCharCallback (c-pointer window) (unsigned-int char))
void
((char-callback) char))
;;; Mouse
(define mouse-bindings (make-parameter '()))
(define (push-mouse-bindings bindings)
(mouse-bindings (cons bindings
(mouse-bindings))))
(define (pop-mouse-bindings)
(unless (null? (mouse-bindings))
(mouse-bindings (cdr (mouse-bindings)))))
(define (mouse-click window button action mods)
(when (not (null? (mouse-bindings)))
(let ((bindings (car (mouse-bindings))))
(cond
((= action %+press+)
(let loop ((bindings bindings))
(unless (null? bindings)
(let ((binding (car bindings)))
(if (and (= (binding-key binding) button)
(= (binding-mods binding) mods))
(begin ((binding-press binding))
(binding-pressed?-set! binding #t))
(loop (cdr bindings)))))))
;; Release for all bindings that share the same button, even with different mods
((= action %+release+)
(for-each (lambda (binding)
(when (and (= (binding-key binding) button)
(binding-pressed? binding))
((binding-release binding))
(binding-pressed?-set! binding #f)))
bindings))))))
(define cursor-movement-callback (make-parameter (lambda (x y) #f)))
(define scroll-callback (make-parameter (lambda (x y) #f)))
(define-external (hpgCursorPositionCallback (c-pointer window)
(double x) (double y))
void
((cursor-movement-callback) x y))
(define-external (hpgScrollCallback (c-pointer window)
(double x) (double y))
void
((scroll-callback) x y))
(define (get-cursor-position)
(%get-cursor-position (%window)))
(define (set-cursor-position x y)
(%set-cursor-position (%window) x y))
(define (get-cursor-world-position camera)
(define (scale x) (sub1 (* x 2)))
(let-values (((w h) (get-window-size))
((x y) (get-cursor-position)))
(let* ((ivp (make-f32vector 16))
(x (scale (/ x w)))
(y (scale (- 1 (/ y h))))
(near (make-point x y -1))
(far (make-point x y 1)))
(inverse (scene:camera-view-projection camera) (->pointer ivp))
(m*vector! ivp near)
(m*vector! ivp far)
(values near far))))