font rendering... mostly
[voxelands-alt.git] / src / client / kmap.c
blobb3fbd5a6c511687926ccd70a947be9e18345c088
1 /************************************************************************
2 * events.c
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
20 #include "common.h"
21 #define _WM_EXPOSE_ALL
22 #include "wm.h"
24 #include <stdio.h>
25 #include <string.h>
27 typedef struct bind_s {
28 char str[256];
29 sym_t sym;
30 uint8_t mods;
31 } bind_t;
34 static uint32_t kmap_strtosym(char* str, sym_t *sym)
36 sym->ch = 0;
37 if (utf8_strlen(str) == 1) {
38 sym->type = SYM_TYPE_KEY;
39 sym->sym = utf8_toutf32(str,-1);
40 sym->ch = sym->sym;
41 return 0;
42 }else if (!strcmp(str,"space")) {
43 sym->type = SYM_TYPE_SKEY;
44 sym->sym = SYM_KEY_SPACE;
45 sym->ch = ' ';
46 return 0;
47 }else if (!strcmp(str,"ctrl")) {
48 sym->type = SYM_TYPE_MOD;
49 sym->sym = SYM_MOD_CTRL;
50 return 0;
51 }else if (!strcmp(str,"alt")) {
52 sym->type = SYM_TYPE_MOD;
53 sym->sym = SYM_MOD_ALT;
54 return 0;
55 }else if (!strcmp(str,"shift")) {
56 sym->type = SYM_TYPE_MOD;
57 sym->sym = SYM_MOD_SHIFT;
58 return 0;
59 }else if (!strcmp(str,"super")) {
60 sym->type = SYM_TYPE_MOD;
61 sym->sym = SYM_MOD_SUPER;
62 return 0;
63 }else if (!strcmp(str,"mouse-left")) {
64 sym->type = SYM_TYPE_MOUSE;
65 sym->sym = MOUSE_BUTTON_LEFT;
66 return 0;
67 }else if (!strcmp(str,"mouse-centre")) {
68 sym->type = SYM_TYPE_MOUSE;
69 sym->sym = MOUSE_BUTTON_RIGHT;
70 return 0;
71 }else if (!strcmp(str,"mouse-right")) {
72 sym->type = SYM_TYPE_MOUSE;
73 sym->sym = MOUSE_BUTTON_LEFT;
74 return 0;
75 }else if (!strcmp(str,"scroll-up")) {
76 sym->type = SYM_TYPE_MOUSE;
77 sym->sym = MOUSE_BUTTON_UP;
78 return 0;
79 }else if (!strcmp(str,"scroll-down")) {
80 sym->type = SYM_TYPE_MOUSE;
81 sym->sym = MOUSE_BUTTON_DOWN;
82 return 0;
83 }else if (!strcmp(str,"mouse-motion")) {
84 sym->type = SYM_TYPE_MOUSE;
85 sym->sym = MOUSE_MOTION;
86 return 0;
87 }else if (!strcmp(str,"esc")) {
88 sym->type = SYM_TYPE_SKEY;
89 sym->sym = SYM_KEY_ESCAPE;
90 return 0;
91 }else if (!strcmp(str,"tab")) {
92 sym->type = SYM_TYPE_SKEY;
93 sym->sym = SYM_KEY_TAB;
94 sym->ch = '\n';
95 return 0;
96 }else if (!strcmp(str,"up")) {
97 sym->type = SYM_TYPE_SKEY;
98 sym->sym = SYM_KEY_UP;
99 return 0;
100 }else if (!strcmp(str,"down")) {
101 sym->type = SYM_TYPE_SKEY;
102 sym->sym = SYM_KEY_DOWN;
103 return 0;
104 }else if (!strcmp(str,"right")) {
105 sym->type = SYM_TYPE_SKEY;
106 sym->sym = SYM_KEY_RIGHT;
107 return 0;
108 }else if (!strcmp(str,"left")) {
109 sym->type = SYM_TYPE_SKEY;
110 sym->sym = SYM_KEY_LEFT;
111 return 0;
112 }else if (!strncmp(str,"kp",2)) {
113 sym->type = SYM_TYPE_SKEY;
114 sym->ch = str[2];
115 switch (str[2]) {
116 case '0':
117 sym->sym = SYM_KEY_KP0;
118 break;
119 case '1':
120 sym->sym = SYM_KEY_KP1;
121 break;
122 case '2':
123 sym->sym = SYM_KEY_KP2;
124 break;
125 case '3':
126 sym->sym = SYM_KEY_KP3;
127 break;
128 case '4':
129 sym->sym = SYM_KEY_KP4;
130 break;
131 case '5':
132 sym->sym = SYM_KEY_KP5;
133 break;
134 case '6':
135 sym->sym = SYM_KEY_KP6;
136 break;
137 case '7':
138 sym->sym = SYM_KEY_KP7;
139 break;
140 case '8':
141 sym->sym = SYM_KEY_KP8;
142 break;
143 case '9':
144 sym->sym = SYM_KEY_KP9;
145 break;
146 default:
147 sym->ch = 0;
149 }else if (str[0] == 'f' || str[0] == 'F') {
150 int i = strtol(str+1,NULL,10);
151 if (i < 1 || i > 12)
152 return 1;
153 i--;
154 sym->type = SYM_TYPE_SKEY;
155 sym->sym = SYM_KEY_F1+i;
157 return 1;
160 /* convert a string to sym + modifiers */
161 int kmap_strtobind(bind_t *bind, char* str)
163 char* b;
164 char* n;
165 char* e;
166 sym_t s;
167 if (!str || !str[0])
168 str = "???";
169 if (snprintf(bind->str,256,"%s",str) >= 256)
170 return 1;
172 bind->mods = 0;
173 bind->sym.type = SYM_TYPE_NONE;
174 bind->sym.sym = 0;
175 bind->sym.ch = 0;
177 /* special unbound case */
178 if (!strcmp(str,"???"))
179 return 0;
181 /* single utf8 char is simple */
182 if (utf8_strlen(str) == 1) {
183 bind->sym.type = SYM_TYPE_KEY;
184 bind->sym.sym = utf8_toutf32(str,-1);
185 return 0;
189 n = bind->str;
190 e = utf8_strchr(bind->str,'+',NULL);
192 if (!e) {
193 if (kmap_strtosym(str,&bind->sym)) {
194 strcpy(bind->str,"???");
195 return 1;
197 return 0;
200 while (n && n[0]) {
201 b = n;
202 e = utf8_strchr(b,'+',NULL);
203 if (e) {
204 /* odd case '+' key */
205 if (b == e) {
206 e++;
207 if (*e) {
208 n = e+1;
209 *e = 0;
210 }else{
211 e = NULL;
212 n = NULL;
214 }else{
215 n = e+1;
216 *e = 0;
218 }else{
219 n = NULL;
221 if (kmap_strtosym(b,&s)) {
222 strcpy(bind->str,"???");
223 bind->mods = 0;
224 bind->sym.type = SYM_TYPE_NONE;
225 bind->sym.sym = 0;
226 bind->sym.ch = 0;
227 return 1;
230 switch (s.type) {
231 case SYM_TYPE_KEY:
232 case SYM_TYPE_SKEY:
233 case SYM_TYPE_MOUSE:
234 bind->sym.type = s.type;
235 bind->sym.sym = s.sym;
236 break;
237 case SYM_TYPE_MOD:
238 bind->mods |= s.sym;
239 break;
240 default:
241 strcpy(bind->str,"???");
242 bind->mods = 0;
243 bind->sym.type = SYM_TYPE_NONE;
244 bind->sym.sym = 0;
245 bind->sym.ch = 0;
246 return 1;
249 if (e)
250 *e = '+';
252 if (bind->sym.type != SYM_TYPE_NONE)
253 break;
256 return 0;
259 int kmap_bindtostr(char* str, int size, bind_t *bind)
261 int a = 0;
262 char buff[6];
263 /* special unbound case */
264 if (bind->sym.type == SYM_TYPE_NONE && bind->mods == 0) {
265 strcpy(str,"???");
266 return 0;
269 str[0] = 0;
271 if ((bind->mods&SYM_MOD_CTRL) == SYM_MOD_CTRL) {
272 if (a)
273 strappend(str,size,"+");
274 strappend(str,size,"ctrl");
276 if ((bind->mods&SYM_MOD_ALT) == SYM_MOD_ALT) {
277 if (a)
278 strappend(str,size,"+");
279 strappend(str,size,"alt");
281 if ((bind->mods&SYM_MOD_SHIFT) == SYM_MOD_SHIFT) {
282 if (a)
283 strappend(str,size,"+");
284 strappend(str,size,"shift");
286 if ((bind->mods&SYM_MOD_SUPER) == SYM_MOD_SUPER) {
287 if (a)
288 strappend(str,size,"+");
289 strappend(str,size,"super");
292 switch (bind->sym.type) {
293 case SYM_TYPE_KEY:
294 if (!utf8_fromutf32(buff,6,bind->sym.ch))
295 return 1;
296 if (a)
297 strappend(str,size,"+");
298 strappend(str,size,buff);
299 break;
300 case SYM_TYPE_MOUSE:
301 switch (bind->sym.sym) {
302 case MOUSE_BUTTON_LEFT:
303 if (a)
304 strappend(str,size,"+");
305 strappend(str,size,"mouse-left");
306 break;
307 case MOUSE_BUTTON_CENTRE:
308 if (a)
309 strappend(str,size,"+");
310 strappend(str,size,"mouse-centre");
311 break;
312 case MOUSE_BUTTON_RIGHT:
313 if (a)
314 strappend(str,size,"+");
315 strappend(str,size,"mouse-right");
316 break;
317 case MOUSE_BUTTON_UP:
318 if (a)
319 strappend(str,size,"+");
320 strappend(str,size,"scroll-up");
321 break;
322 case MOUSE_BUTTON_DOWN:
323 if (a)
324 strappend(str,size,"+");
325 strappend(str,size,"scroll-down");
326 break;
327 case MOUSE_MOTION:
328 if (a)
329 strappend(str,size,"+");
330 strappend(str,size,"mouse-motion");
331 break;
332 default:
333 return 1;
335 break;
336 case SYM_TYPE_SKEY:
337 switch (bind->sym.sym) {
338 case SYM_KEY_SPACE:
339 if (a)
340 strappend(str,size,"+");
341 strappend(str,size,"space");
342 break;
343 case SYM_KEY_ESCAPE:
344 if (a)
345 strappend(str,size,"+");
346 strappend(str,size,"escape");
347 break;
348 case SYM_KEY_TAB:
349 if (a)
350 strappend(str,size,"+");
351 strappend(str,size,"tab");
352 break;
353 case SYM_KEY_KP0:
354 if (a)
355 strappend(str,size,"+");
356 strappend(str,size,"kp0");
357 break;
358 case SYM_KEY_KP1:
359 if (a)
360 strappend(str,size,"+");
361 strappend(str,size,"kp1");
362 break;
363 case SYM_KEY_KP2:
364 if (a)
365 strappend(str,size,"+");
366 strappend(str,size,"kp2");
367 break;
368 case SYM_KEY_KP3:
369 if (a)
370 strappend(str,size,"+");
371 strappend(str,size,"kp3");
372 break;
373 case SYM_KEY_KP4:
374 if (a)
375 strappend(str,size,"+");
376 strappend(str,size,"kp4");
377 break;
378 case SYM_KEY_KP5:
379 if (a)
380 strappend(str,size,"+");
381 strappend(str,size,"kp5");
382 break;
383 case SYM_KEY_KP6:
384 if (a)
385 strappend(str,size,"+");
386 strappend(str,size,"kp6");
387 break;
388 case SYM_KEY_KP7:
389 if (a)
390 strappend(str,size,"+");
391 strappend(str,size,"kp7");
392 break;
393 case SYM_KEY_KP8:
394 if (a)
395 strappend(str,size,"+");
396 strappend(str,size,"kp8");
397 break;
398 case SYM_KEY_KP9:
399 if (a)
400 strappend(str,size,"+");
401 strappend(str,size,"kp9");
402 break;
403 case SYM_KEY_UP:
404 if (a)
405 strappend(str,size,"+");
406 strappend(str,size,"up");
407 break;
408 case SYM_KEY_DOWN:
409 if (a)
410 strappend(str,size,"+");
411 strappend(str,size,"down");
412 break;
413 case SYM_KEY_LEFT:
414 if (a)
415 strappend(str,size,"+");
416 strappend(str,size,"left");
417 break;
418 case SYM_KEY_RIGHT:
419 if (a)
420 strappend(str,size,"+");
421 strappend(str,size,"right");
422 break;
423 case SYM_KEY_F1:
424 if (a)
425 strappend(str,size,"+");
426 strappend(str,size,"f1");
427 break;
428 case SYM_KEY_F2:
429 if (a)
430 strappend(str,size,"+");
431 strappend(str,size,"f2");
432 break;
433 case SYM_KEY_F3:
434 if (a)
435 strappend(str,size,"+");
436 strappend(str,size,"f3");
437 break;
438 case SYM_KEY_F4:
439 if (a)
440 strappend(str,size,"+");
441 strappend(str,size,"f4");
442 break;
443 case SYM_KEY_F5:
444 if (a)
445 strappend(str,size,"+");
446 strappend(str,size,"f5");
447 break;
448 case SYM_KEY_F6:
449 if (a)
450 strappend(str,size,"+");
451 strappend(str,size,"f6");
452 break;
453 case SYM_KEY_F7:
454 if (a)
455 strappend(str,size,"+");
456 strappend(str,size,"f7");
457 break;
458 case SYM_KEY_F8:
459 if (a)
460 strappend(str,size,"+");
461 strappend(str,size,"f8");
462 break;
463 case SYM_KEY_F9:
464 if (a)
465 strappend(str,size,"+");
466 strappend(str,size,"f9");
467 break;
468 case SYM_KEY_F10:
469 if (a)
470 strappend(str,size,"+");
471 strappend(str,size,"f10");
472 break;
473 case SYM_KEY_F11:
474 if (a)
475 strappend(str,size,"+");
476 strappend(str,size,"f11");
477 break;
478 case SYM_KEY_F12:
479 if (a)
480 strappend(str,size,"+");
481 strappend(str,size,"f12");
482 break;
483 default:
484 return 1;
486 break;
487 default:;
490 if (str[0] == 0)
491 return 1;
493 return 0;
496 /* check if two bindings match */
497 int kmap_equal(bind_t *b1, bind_t *b2)
499 if (!b1 || !b2)
500 return 0;
501 if (b1->sym.type != b2->sym.type)
502 return 0;
503 if (b1->sym.sym != b2->sym.sym)
504 return 0;
505 if (b1->mods != b2->mods)
506 return 0;
507 return 1;
510 /* does the event binding trigger the action binding? */
511 int kmap_triggers(bind_t *eb, bind_t *ab)
513 if (!eb || !ab)
514 return 0;
515 if (eb->sym.type != ab->sym.type)
516 return 0;
517 if (eb->sym.sym != ab->sym.sym)
518 return 0;
519 if ((eb->mods&ab->mods) != ab->mods)
520 return 0;
521 return 1;