| ... | ... |
@@ -22,6 +22,8 @@ then |
| 22 | 22 |
clang-format -i src/devices/file.c |
| 23 | 23 |
clang-format -i src/devices/mouse.h |
| 24 | 24 |
clang-format -i src/devices/mouse.c |
| 25 |
+ clang-format -i src/devices/controller.h |
|
| 26 |
+ clang-format -i src/devices/controller.c |
|
| 25 | 27 |
clang-format -i src/uxnasm.c |
| 26 | 28 |
clang-format -i src/uxnemu.c |
| 27 | 29 |
clang-format -i src/uxncli.c |
| ... | ... |
@@ -60,7 +62,7 @@ fi |
| 60 | 62 |
|
| 61 | 63 |
echo "Building.." |
| 62 | 64 |
${CC} ${CFLAGS} src/uxnasm.c -o bin/uxnasm
|
| 63 |
-${CC} ${CFLAGS} ${CORE} src/devices/file.c src/devices/mouse.c src/devices/ppu.c src/devices/apu.c src/uxnemu.c ${UXNEMU_LDFLAGS} -o bin/uxnemu
|
|
| 65 |
+${CC} ${CFLAGS} ${CORE} src/devices/file.c src/devices/mouse.c src/devices/controller.c src/devices/ppu.c src/devices/apu.c src/uxnemu.c ${UXNEMU_LDFLAGS} -o bin/uxnemu
|
|
| 64 | 66 |
${CC} ${CFLAGS} ${CORE} src/devices/file.c src/uxncli.c -o bin/uxncli
|
| 65 | 67 |
|
| 66 | 68 |
if [ -d "$HOME/bin" ] |
| 67 | 69 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,38 @@ |
| 1 |
+#include "../uxn.h" |
|
| 2 |
+#include "controller.h" |
|
| 3 |
+ |
|
| 4 |
+/* |
|
| 5 |
+Copyright (c) 2021 Devine Lu Linvega |
|
| 6 |
+Copyright (c) 2021 Andrew Alderwick |
|
| 7 |
+ |
|
| 8 |
+Permission to use, copy, modify, and distribute this software for any |
|
| 9 |
+purpose with or without fee is hereby granted, provided that the above |
|
| 10 |
+copyright notice and this permission notice appear in all copies. |
|
| 11 |
+ |
|
| 12 |
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
| 13 |
+WITH REGARD TO THIS SOFTWARE. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+void |
|
| 17 |
+controller_down(Device *d, Uint8 mask) |
|
| 18 |
+{
|
|
| 19 |
+ d->dat[2] |= mask; |
|
| 20 |
+ uxn_eval(d->u, d->vector); |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 23 |
+void |
|
| 24 |
+controller_up(Device *d, Uint8 mask) |
|
| 25 |
+{
|
|
| 26 |
+ d->dat[2] &= (~mask); |
|
| 27 |
+ uxn_eval(d->u, d->vector); |
|
| 28 |
+} |
|
| 29 |
+ |
|
| 30 |
+void |
|
| 31 |
+controller_key(Device *d, Uint8 key) |
|
| 32 |
+{
|
|
| 33 |
+ if(!key) {
|
|
| 34 |
+ d->dat[3] = key; |
|
| 35 |
+ uxn_eval(d->u, d->vector); |
|
| 36 |
+ d->dat[3] = 0x00; |
|
| 37 |
+ } |
|
| 38 |
+} |
|
| 0 | 39 |
\ No newline at end of file |
| 1 | 40 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 1 |
+/* |
|
| 2 |
+Copyright (c) 2021 Devine Lu Linvega |
|
| 3 |
+Copyright (c) 2021 Andrew Alderwick |
|
| 4 |
+ |
|
| 5 |
+Permission to use, copy, modify, and distribute this software for any |
|
| 6 |
+purpose with or without fee is hereby granted, provided that the above |
|
| 7 |
+copyright notice and this permission notice appear in all copies. |
|
| 8 |
+ |
|
| 9 |
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
| 10 |
+WITH REGARD TO THIS SOFTWARE. |
|
| 11 |
+*/ |
|
| 12 |
+ |
|
| 13 |
+void controller_down(Device *d, Uint8 mask); |
|
| 14 |
+void controller_up(Device *d, Uint8 mask); |
|
| 15 |
+void controller_key(Device *d, Uint8 key); |
|
| 0 | 16 |
\ No newline at end of file |
| ... | ... |
@@ -11,6 +11,7 @@ |
| 11 | 11 |
#include "devices/ppu.h" |
| 12 | 12 |
#include "devices/apu.h" |
| 13 | 13 |
#include "devices/file.h" |
| 14 |
+#include "devices/controller.h" |
|
| 14 | 15 |
#include "devices/mouse.h" |
| 15 | 16 |
#pragma GCC diagnostic pop |
| 16 | 17 |
#pragma clang diagnostic pop |
| ... | ... |
@@ -409,39 +410,29 @@ get_button(SDL_Event *event) |
| 409 | 410 |
return 0x00; |
| 410 | 411 |
} |
| 411 | 412 |
|
| 412 |
-void |
|
| 413 |
-controller_down(Device *d, Uint8 mask) |
|
| 414 |
-{
|
|
| 415 |
- d->dat[2] |= mask; |
|
| 416 |
- uxn_eval(d->u, d->vector); |
|
| 417 |
-} |
|
| 418 |
- |
|
| 419 |
-void |
|
| 420 |
-controller_up(Device *d, Uint8 mask) |
|
| 413 |
+Uint8 |
|
| 414 |
+get_key(SDL_Event *event) |
|
| 421 | 415 |
{
|
| 422 |
- d->dat[2] &= (~mask); |
|
| 423 |
- uxn_eval(d->u, d->vector); |
|
| 416 |
+ SDL_Keymod mods = SDL_GetModState(); |
|
| 417 |
+ if(event->key.keysym.sym < 0x20 || event->key.keysym.sym == SDLK_DELETE) |
|
| 418 |
+ return event->key.keysym.sym; |
|
| 419 |
+ if((mods & KMOD_CTRL) && event->key.keysym.sym >= SDLK_a && event->key.keysym.sym <= SDLK_z) |
|
| 420 |
+ return event->key.keysym.sym - (mods & KMOD_SHIFT) * 0x20; |
|
| 421 |
+ return 0x00; |
|
| 424 | 422 |
} |
| 425 | 423 |
|
| 426 | 424 |
static void |
| 427 |
-doctrl(Uxn *u, SDL_Event *event, int z) |
|
| 425 |
+do_shortcut(Uxn *u, SDL_Event *event) |
|
| 428 | 426 |
{
|
| 429 |
- SDL_Keymod mods = SDL_GetModState(); |
|
| 430 |
- /* clang-format off */ |
|
| 431 |
- switch(event->key.keysym.sym) {
|
|
| 432 |
- case SDLK_F1: if(z) set_zoom(zoom > 2 ? 1 : zoom + 1); break; |
|
| 433 |
- case SDLK_F2: if(z) devsystem->dat[0xe] = !devsystem->dat[0xe]; ppu_clear(&ppu, &ppu.fg); break; |
|
| 434 |
- case SDLK_F3: if(z) capture_screen(); break; |
|
| 435 |
- case SDLK_AC_BACK: |
|
| 436 |
- case SDLK_F4: if(z) restart(u); break; |
|
| 437 |
- } |
|
| 438 |
- /* clang-format on */ |
|
| 439 |
- if(z) {
|
|
| 440 |
- if(event->key.keysym.sym < 0x20 || event->key.keysym.sym == SDLK_DELETE) |
|
| 441 |
- devctrl->dat[3] = event->key.keysym.sym; |
|
| 442 |
- else if((mods & KMOD_CTRL) && event->key.keysym.sym >= SDLK_a && event->key.keysym.sym <= SDLK_z) |
|
| 443 |
- devctrl->dat[3] = event->key.keysym.sym - (mods & KMOD_SHIFT) * 0x20; |
|
| 444 |
- } |
|
| 427 |
+ if(event->key.keysym.sym == SDLK_F1) |
|
| 428 |
+ set_zoom(zoom > 2 ? 1 : zoom + 1); |
|
| 429 |
+ else if(event->key.keysym.sym == SDLK_F2) {
|
|
| 430 |
+ devsystem->dat[0xe] = !devsystem->dat[0xe]; |
|
| 431 |
+ ppu_clear(&ppu, &ppu.fg); |
|
| 432 |
+ } else if(event->key.keysym.sym == SDLK_F3) |
|
| 433 |
+ capture_screen(); |
|
| 434 |
+ else if(event->key.keysym.sym == SDLK_F4) |
|
| 435 |
+ restart(u); |
|
| 445 | 436 |
} |
| 446 | 437 |
|
| 447 | 438 |
static const char *errors[] = {"underflow", "overflow", "division by zero"};
|
| ... | ... |
@@ -467,12 +458,24 @@ run(Uxn *u) |
| 467 | 458 |
while(!devsystem->dat[0xf]) {
|
| 468 | 459 |
SDL_Event event; |
| 469 | 460 |
double elapsed, begin = 0; |
| 470 |
- int ksym; |
|
| 471 | 461 |
if(!BENCH) |
| 472 | 462 |
begin = SDL_GetPerformanceCounter(); |
| 473 | 463 |
while(SDL_PollEvent(&event) != 0) {
|
| 474 |
- /* new handlers */ |
|
| 475 |
- if(event.type == SDL_MOUSEWHEEL) |
|
| 464 |
+ /* Window */ |
|
| 465 |
+ if(event.type == SDL_QUIT) |
|
| 466 |
+ return error("Run", "Quit.");
|
|
| 467 |
+ else if(event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_EXPOSED) |
|
| 468 |
+ redraw(u); |
|
| 469 |
+ else if(event.type == SDL_DROPFILE) {
|
|
| 470 |
+ set_size(WIDTH, HEIGHT, 0); |
|
| 471 |
+ start(u, event.drop.file); |
|
| 472 |
+ SDL_free(event.drop.file); |
|
| 473 |
+ } |
|
| 474 |
+ /* Audio */ |
|
| 475 |
+ else if(event.type >= audio0_event && event.type < audio0_event + POLYPHONY) |
|
| 476 |
+ uxn_eval(u, peek16((devaudio0 + (event.type - audio0_event))->dat, 0)); |
|
| 477 |
+ /* Mouse */ |
|
| 478 |
+ else if(event.type == SDL_MOUSEWHEEL) |
|
| 476 | 479 |
mouse_z(devmouse, event.wheel.y); |
| 477 | 480 |
else if(event.type == SDL_MOUSEBUTTONUP) |
| 478 | 481 |
mouse_up(devmouse, 0x1 << (event.button.button - 1)); |
| ... | ... |
@@ -482,44 +485,19 @@ run(Uxn *u) |
| 482 | 485 |
mouse_xy(devmouse, |
| 483 | 486 |
clamp(event.motion.x - PAD, 0, ppu.width - 1), |
| 484 | 487 |
clamp(event.motion.y - PAD, 0, ppu.height - 1)); |
| 485 |
- else if(event.type == SDL_KEYDOWN) |
|
| 488 |
+ /* Controller */ |
|
| 489 |
+ else if(event.type == SDL_KEYDOWN) {
|
|
| 486 | 490 |
controller_down(devctrl, get_button(&event)); |
| 487 |
- else if(event.type == SDL_KEYUP) |
|
| 491 |
+ controller_key(devctrl, get_key(&event)); |
|
| 492 |
+ do_shortcut(u, &event); |
|
| 493 |
+ } else if(event.type == SDL_KEYUP) |
|
| 488 | 494 |
controller_up(devctrl, get_button(&event)); |
| 489 |
- /* continue */ |
|
| 490 |
- switch(event.type) {
|
|
| 491 |
- case SDL_DROPFILE: |
|
| 492 |
- set_size(WIDTH, HEIGHT, 0); |
|
| 493 |
- start(u, event.drop.file); |
|
| 494 |
- SDL_free(event.drop.file); |
|
| 495 |
- break; |
|
| 496 |
- case SDL_QUIT: |
|
| 497 |
- return error("Run", "Quit.");
|
|
| 498 |
- case SDL_TEXTINPUT: |
|
| 499 |
- devctrl->dat[3] = event.text.text[0]; /* fall-thru */ |
|
| 500 |
- case SDL_KEYDOWN: |
|
| 501 |
- case SDL_KEYUP: |
|
| 502 |
- doctrl(u, &event, event.type == SDL_KEYDOWN); |
|
| 503 |
- uxn_eval(u, devctrl->vector); |
|
| 504 |
- devctrl->dat[3] = 0; |
|
| 505 |
- if(event.type == SDL_KEYDOWN) {
|
|
| 506 |
- ksym = event.key.keysym.sym; |
|
| 507 |
- if(SDL_PeepEvents(&event, 1, SDL_PEEKEVENT, SDL_KEYUP, SDL_KEYUP) == 1 && ksym == event.key.keysym.sym) |
|
| 508 |
- goto breakout; |
|
| 509 |
- } |
|
| 510 |
- break; |
|
| 511 |
- case SDL_WINDOWEVENT: |
|
| 512 |
- if(event.window.event == SDL_WINDOWEVENT_EXPOSED) |
|
| 513 |
- redraw(u); |
|
| 514 |
- break; |
|
| 515 |
- default: |
|
| 516 |
- if(event.type == stdin_event) {
|
|
| 517 |
- console_input(u, event.cbutton.button); |
|
| 518 |
- } else if(event.type >= audio0_event && event.type < audio0_event + POLYPHONY) |
|
| 519 |
- uxn_eval(u, peek16((devaudio0 + (event.type - audio0_event))->dat, 0)); |
|
| 520 |
- } |
|
| 495 |
+ else if(event.type == SDL_TEXTINPUT) |
|
| 496 |
+ controller_key(devctrl, event.text.text[0]); |
|
| 497 |
+ /* Console */ |
|
| 498 |
+ else if(event.type == stdin_event) |
|
| 499 |
+ console_input(u, event.cbutton.button); |
|
| 521 | 500 |
} |
| 522 |
- breakout: |
|
| 523 | 501 |
uxn_eval(u, devscreen->vector); |
| 524 | 502 |
if(ppu.fg.changed || ppu.bg.changed || devsystem->dat[0xe]) |
| 525 | 503 |
redraw(u); |