aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-08-30 16:13:48 +0200
committerBad Diode <bd@badd10de.dev>2023-08-30 16:13:48 +0200
commite8fdb17d27a33988fb79c792d69ff15c16a0e59c (patch)
tree40d65b7c96b5951878d798c87495808e2d8bb908 /src
parentac0fb608825c032e58bb533e30a77b1911b9bae9 (diff)
downloaduxngba-e8fdb17d27a33988fb79c792d69ff15c16a0e59c.tar.gz
uxngba-e8fdb17d27a33988fb79c792d69ff15c16a0e59c.zip
Add back input handling function
Diffstat (limited to 'src')
-rw-r--r--src/devices.c207
-rw-r--r--src/input.c205
-rw-r--r--src/main.c99
-rw-r--r--src/uxn-core.c32
4 files changed, 290 insertions, 253 deletions
diff --git a/src/devices.c b/src/devices.c
index 48d062d..e031a85 100644
--- a/src/devices.c
+++ b/src/devices.c
@@ -1,26 +1,5 @@
1static time_t seconds = 0; 1static time_t seconds = 0;
2 2
3typedef enum {
4 CONTROL_CONTROLLER,
5 CONTROL_MOUSE,
6 CONTROL_KEYBOARD,
7} ControlMethod;
8
9const ControlMethod ctrl_methods[] = {
10 CONTROL_METHODS
11};
12static ControlMethod ctrl_idx = 0;
13
14#define MOUSE_DELTA 1
15typedef struct Mouse {
16 int x;
17 int y;
18} Mouse;
19
20// static Uxn u;
21
22static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2};
23
24int 3int
25uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr) { 4uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr) {
26 (void)u; 5 (void)u;
@@ -309,189 +288,3 @@ uxn_deo(Uxn *u, u8 addr) {
309 } 288 }
310} 289}
311 290
312IWRAM_CODE
313void
314handle_input(Uxn *u) {
315 // poll_keys();
316 // if (key_tap(KEY_SELECT)) {
317 // // Reset control variables on method switch.
318 // switch (ctrl_methods[ctrl_idx]) {
319 // case CONTROL_CONTROLLER: {
320 // u8 *d = &u->dev[0x80];
321 // d[2] = 0;
322 // uxn_eval(u, PEEK2(d));
323 // d[3] = 0;
324 // } break;
325 // case CONTROL_MOUSE: {
326 // u8 *d = &u->dev[0x90];
327 // d[6] = 0;
328 // d[7] = 0;
329 // POKE2(d + 0x2, -10);
330 // POKE2(d + 0x4, -10);
331 // uxn_eval(u, PEEK2(d));
332 // } break;
333 // case CONTROL_KEYBOARD: {
334 // toggle_keyboard();
335 // } break;
336 // }
337
338 // // Update ctrl_idx.
339 // ctrl_idx = (ctrl_idx + 1 > (int)LEN(ctrl_methods) - 1) ? 0 : ctrl_idx + 1;
340
341 // // Initialize controller variables here.
342 // if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
343 // toggle_keyboard();
344 // }
345 // }
346
347 // if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) {
348 // u8 *d = &u->dev[0x80];
349 // // TODO: We don't need ifs if we use KEY_INPUTS directly and maybe just
350 // // swap some things if needed.
351 // u8 *flag = &d[2];
352 // if (key_tap(KEY_A)) {
353 // *flag |= 0x01;
354 // } else {
355 // *flag &= ~0x01;
356 // }
357 // if (key_tap(KEY_B)) {
358 // *flag |= 0x02;
359 // } else {
360 // *flag &= ~0x02;
361 // }
362 // if (key_tap(KEY_L)) {
363 // *flag |= 0x04;
364 // } else {
365 // *flag &= ~0x04;
366 // }
367 // if (key_tap(KEY_R)) {
368 // *flag |= 0x08;
369 // } else {
370 // *flag &= ~0x08;
371 // }
372 // if (key_tap(KEY_UP)) {
373 // *flag |= 0x10;
374 // } else {
375 // *flag &= ~0x10;
376 // }
377 // if (key_tap(KEY_DOWN)) {
378 // *flag |= 0x20;
379 // } else {
380 // *flag &= ~0x20;
381 // }
382 // if (key_tap(KEY_LEFT)) {
383 // *flag |= 0x40;
384 // } else {
385 // *flag &= ~0x40;
386 // }
387 // if (key_tap(KEY_RIGHT)) {
388 // *flag |= 0x80;
389 // } else {
390 // *flag &= ~0x80;
391 // }
392
393 // if (key_prev != key_curr) {
394 // uxn_eval(u, PEEK2(d));
395 // }
396 // d[3] = 0;
397 // } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) {
398 // u8 *d = &u->dev[0x90];
399 // // Detect "mouse key press".
400 // u8 flag = d[6];
401 // bool event = false;
402 // if (key_tap(KEY_B)) {
403 // event = true;
404 // flag |= 0x01;
405 // } else if (key_released(KEY_B)) {
406 // event = true;
407 // flag &= ~0x01;
408 // }
409 // if (key_tap(KEY_A)) {
410 // event = true;
411 // flag |= 0x10;
412 // } else if (key_released(KEY_A)) {
413 // event = true;
414 // flag &= ~0x10;
415 // }
416
417 // // Handle chording.
418 // d[6] = flag;
419 // if(flag == 0x10 && (d[6] & 0x01)) {
420 // d[7] = 0x01;
421 // }
422 // if(flag == 0x01 && (d[6] & 0x10)) {
423 // d[7] = 0x10;
424 // }
425
426 // // Detect mouse movement.
427 // if (key_pressed(KEY_UP)) {
428 // event = true;
429 // mouse.y = CLAMP(mouse.y - MOUSE_DELTA, 0, SCREEN_HEIGHT - 8);
430 // } else if (key_pressed(KEY_DOWN)) {
431 // event = true;
432 // mouse.y = CLAMP(mouse.y + MOUSE_DELTA, 0, SCREEN_HEIGHT - 8);
433 // }
434 // if (key_pressed(KEY_LEFT)) {
435 // event = true;
436 // mouse.x = CLAMP(mouse.x - MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
437 // } else if (key_pressed(KEY_RIGHT)) {
438 // event = true;
439 // mouse.x = CLAMP(mouse.x + MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
440 // }
441
442 // // Eval mouse.
443 // POKE2(d + 0x2, mouse.x);
444 // POKE2(d + 0x4, mouse.y);
445 // if (event) {
446 // uxn_eval(u, PEEK2(d));
447 // }
448 // } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
449 // u8 *d = &u->dev[0x80];
450 // if (key_tap(KEY_LEFT)) {
451 // update_cursor(cursor_position - 1);
452 // } else if (key_tap(KEY_RIGHT)) {
453 // update_cursor(cursor_position + 1);
454 // }
455 // if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) {
456 // update_cursor(cursor_position - KEYBOARD_ROW_SIZE);
457 // } else if (key_tap(KEY_DOWN)
458 // && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) {
459 // update_cursor(cursor_position + KEYBOARD_ROW_SIZE);
460 // }
461 // if (key_tap(KEY_B)) {
462 // u8 symbol = keyboard[cursor_position].symbol;
463 // switch (symbol) {
464 // case 0x7f: {
465 // // Backspace.
466 // d[3] = 0x08;
467 // } break;
468 // case 0x14: {
469 // // New line.
470 // d[3] = 0x0d;
471 // } break;
472 // case 0x18: {
473 // // Arrow up.
474 // d[2] = 0x10;
475 // } break;
476 // case 0x19: {
477 // // Arrow down.
478 // d[2] = 0x20;
479 // } break;
480 // case 0x1b: {
481 // // Arrow left.
482 // d[2] = 0x40;
483 // } break;
484 // case 0x1a: {
485 // // Arrow right.
486 // d[2] = 0x80;
487 // } break;
488 // default: {
489 // d[3] = symbol;
490 // } break;
491 // }
492 // uxn_eval(u, PEEK2(d));
493 // d[3] = 0;
494 // }
495 // }
496}
497
diff --git a/src/input.c b/src/input.c
new file mode 100644
index 0000000..c257271
--- /dev/null
+++ b/src/input.c
@@ -0,0 +1,205 @@
1typedef enum {
2 CONTROL_CONTROLLER,
3 CONTROL_MOUSE,
4 CONTROL_KEYBOARD,
5} ControlMethod;
6
7const ControlMethod ctrl_methods[] = {
8 CONTROL_MOUSE,
9 CONTROL_CONTROLLER,
10};
11static ControlMethod ctrl_idx = 0;
12
13#define MOUSE_DELTA 1
14typedef struct Mouse {
15 int x;
16 int y;
17} Mouse;
18
19static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2};
20
21void
22handle_input() {
23 poll_keys();
24 if (key_tap(KEY_SELECT)) {
25 // Reset control variables on method switch.
26 switch (ctrl_methods[ctrl_idx]) {
27 case CONTROL_CONTROLLER: {
28 u8 *d = &device_data[0x80];
29 d[2] = 0;
30 uxn_eval_asm(PEEK2(d));
31 d[3] = 0;
32 } break;
33 case CONTROL_MOUSE: {
34 u8 *d = &device_data[0x90];
35 d[6] = 0;
36 d[7] = 0;
37 POKE2(d + 0x2, -10);
38 POKE2(d + 0x4, -10);
39 uxn_eval_asm(PEEK2(d));
40 } break;
41 case CONTROL_KEYBOARD: {
42 toggle_keyboard();
43 } break;
44 }
45
46 // Update ctrl_idx.
47 ctrl_idx = (ctrl_idx + 1 > (int)LEN(ctrl_methods) - 1) ? 0 : ctrl_idx + 1;
48
49 // Initialize controller variables here.
50 if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
51 toggle_keyboard();
52 }
53 }
54
55 if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) {
56 u8 *d = &device_data[0x80];
57 // TODO: We don't need ifs if we use KEY_INPUTS directly and maybe just
58 // swap some things if needed.
59 u8 *flag = &d[2];
60 if (key_tap(KEY_A)) {
61 *flag |= 0x01;
62 } else {
63 *flag &= ~0x01;
64 }
65 if (key_tap(KEY_B)) {
66 *flag |= 0x02;
67 } else {
68 *flag &= ~0x02;
69 }
70 if (key_tap(KEY_L)) {
71 *flag |= 0x04;
72 } else {
73 *flag &= ~0x04;
74 }
75 if (key_tap(KEY_R)) {
76 *flag |= 0x08;
77 } else {
78 *flag &= ~0x08;
79 }
80 if (key_tap(KEY_UP)) {
81 *flag |= 0x10;
82 } else {
83 *flag &= ~0x10;
84 }
85 if (key_tap(KEY_DOWN)) {
86 *flag |= 0x20;
87 } else {
88 *flag &= ~0x20;
89 }
90 if (key_tap(KEY_LEFT)) {
91 *flag |= 0x40;
92 } else {
93 *flag &= ~0x40;
94 }
95 if (key_tap(KEY_RIGHT)) {
96 *flag |= 0x80;
97 } else {
98 *flag &= ~0x80;
99 }
100
101 if (key_prev != key_curr) {
102 uxn_eval_asm(PEEK2(d));
103 }
104 d[3] = 0;
105 } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) {
106 u8 *d = &device_data[0x90];
107 // Detect "mouse key press".
108 u8 flag = d[6];
109 bool event = false;
110 if (key_tap(KEY_B)) {
111 event = true;
112 flag |= 0x01;
113 } else if (key_released(KEY_B)) {
114 event = true;
115 flag &= ~0x01;
116 }
117 if (key_tap(KEY_A)) {
118 event = true;
119 flag |= 0x10;
120 } else if (key_released(KEY_A)) {
121 event = true;
122 flag &= ~0x10;
123 }
124
125 // Handle chording.
126 d[6] = flag;
127 if(flag == 0x10 && (d[6] & 0x01)) {
128 d[7] = 0x01;
129 }
130 if(flag == 0x01 && (d[6] & 0x10)) {
131 d[7] = 0x10;
132 }
133
134 // Detect mouse movement.
135 if (key_pressed(KEY_UP)) {
136 event = true;
137 mouse.y = CLAMP(mouse.y - MOUSE_DELTA, 0, SCREEN_HEIGHT - 8);
138 } else if (key_pressed(KEY_DOWN)) {
139 event = true;
140 mouse.y = CLAMP(mouse.y + MOUSE_DELTA, 0, SCREEN_HEIGHT - 8);
141 }
142 if (key_pressed(KEY_LEFT)) {
143 event = true;
144 mouse.x = CLAMP(mouse.x - MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
145 } else if (key_pressed(KEY_RIGHT)) {
146 event = true;
147 mouse.x = CLAMP(mouse.x + MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
148 }
149
150 // Eval mouse.
151 POKE2(d + 0x2, mouse.x);
152 POKE2(d + 0x4, mouse.y);
153 if (event) {
154 uxn_eval_asm(PEEK2(d));
155 }
156 } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
157 u8 *d = &device_data[0x80];
158 if (key_tap(KEY_LEFT)) {
159 update_cursor(cursor_position - 1);
160 } else if (key_tap(KEY_RIGHT)) {
161 update_cursor(cursor_position + 1);
162 }
163 if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) {
164 update_cursor(cursor_position - KEYBOARD_ROW_SIZE);
165 } else if (key_tap(KEY_DOWN)
166 && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) {
167 update_cursor(cursor_position + KEYBOARD_ROW_SIZE);
168 }
169 if (key_tap(KEY_B)) {
170 u8 symbol = keyboard[cursor_position].symbol;
171 switch (symbol) {
172 case 0x7f: {
173 // Backspace.
174 d[3] = 0x08;
175 } break;
176 case 0x14: {
177 // New line.
178 d[3] = 0x0d;
179 } break;
180 case 0x18: {
181 // Arrow up.
182 d[2] = 0x10;
183 } break;
184 case 0x19: {
185 // Arrow down.
186 d[2] = 0x20;
187 } break;
188 case 0x1b: {
189 // Arrow left.
190 d[2] = 0x40;
191 } break;
192 case 0x1a: {
193 // Arrow right.
194 d[2] = 0x80;
195 } break;
196 default: {
197 d[3] = symbol;
198 } break;
199 }
200 uxn_eval_asm(PEEK2(d));
201 d[3] = 0;
202 }
203 }
204}
205
diff --git a/src/main.c b/src/main.c
index 3402c2a..1cca942 100644
--- a/src/main.c
+++ b/src/main.c
@@ -15,6 +15,8 @@
15#include "common.h" 15#include "common.h"
16#include "filesystem.c" 16#include "filesystem.c"
17 17
18#include "uxn-core.c"
19
18#include "uxn.c" 20#include "uxn.c"
19#include "ppu.c" 21#include "ppu.c"
20#include "apu.c" 22#include "apu.c"
@@ -24,41 +26,9 @@
24#include "rom.c" 26#include "rom.c"
25#include "config.c" 27#include "config.c"
26#include "profiling.c" 28#include "profiling.c"
29#include "input.c"
27#include "devices.c" 30#include "devices.c"
28 31
29extern void uxn_eval_asm(u16 pc);
30
31// Stacks (On IWRAM).
32extern u8 wst[256];
33extern u8 rst[256];
34extern uintptr_t wst_ptr;
35extern uintptr_t rst_ptr;
36
37// DEO/DEI mapping functiosn and device data (On IWRAM).
38extern uintptr_t deo_map[16];
39extern uintptr_t dei_map[16];
40extern u8 device_data[256];
41
42// DEBUG: ONLY
43// extern u8 device_0[16];
44// extern u8 device_1[16];
45// extern u8 device_2[16];
46// extern u8 device_3[16];
47// extern u8 device_4[16];
48// extern u8 device_5[16];
49// extern u8 device_6[16];
50// extern u8 device_7[16];
51// extern u8 device_8[16];
52// extern u8 device_a[16];
53// extern u8 device_b[16];
54// extern u8 device_c[16];
55// extern u8 device_d[16];
56// extern u8 device_e[16];
57// extern u8 device_f[16];
58
59EWRAM_BSS
60u8 uxn_ram[KB(64)];
61
62void 32void
63deo_console(u8 *dev, u8 port) { 33deo_console(u8 *dev, u8 port) {
64 switch(port) { 34 switch(port) {
@@ -184,7 +154,27 @@ dei_system(u8 *dev, u8 port) {
184 case 0x5: { 154 case 0x5: {
185 // TODO: Return rst_ptr, but is it the offset instead? 155 // TODO: Return rst_ptr, but is it the offset instead?
186 } break; 156 } break;
187 default: { return dev[port]; } break; } 157 default: { return dev[port]; } break;
158 }
159}
160
161u8
162dei_datetime(u8 *dev, u8 port) {
163 struct tm *t = gmtime(&seconds);
164 switch(port) {
165 case 0x0: return (t->tm_year + 1900) >> 8;
166 case 0x1: return (t->tm_year + 1900);
167 case 0x2: return t->tm_mon;
168 case 0x3: return t->tm_mday;
169 case 0x4: return t->tm_hour;
170 case 0x5: return t->tm_min;
171 case 0x6: return t->tm_sec;
172 case 0x7: return t->tm_wday;
173 case 0x8: return t->tm_yday >> 8;
174 case 0x9: return t->tm_yday;
175 case 0xa: return t->tm_isdst;
176 default: return dev[port];
177 }
188} 178}
189 179
190void 180void
@@ -220,19 +210,21 @@ init_uxn() {
220 deo_map[i] = deo_stub; 210 deo_map[i] = deo_stub;
221 dei_map[i] = dei_stub; 211 dei_map[i] = dei_stub;
222 } 212 }
223 deo_map[0] = deo_system; 213 deo_map[0x0] = deo_system;
224 dei_map[0] = dei_system; 214 dei_map[0x0] = dei_system;
225 deo_map[1] = deo_console; 215 deo_map[0x1] = deo_console;
226 deo_map[2] = deo_screen; 216 deo_map[0x2] = deo_screen;
227 dei_map[2] = dei_screen; 217 dei_map[0x2] = dei_screen;
218 dei_map[0xc] = dei_datetime;
228} 219}
229 220
230typedef enum DebugFlags { 221typedef enum DebugFlags {
231 SHOW_ROM = (1 << 0), 222 SHOW_ROM = (1 << 0),
232 SHOW_WST = (1 << 1), 223 SHOW_WST = (1 << 1),
233 SHOW_RST = (1 << 2), 224 SHOW_RST = (1 << 2),
234 SHOW_ZP = (1 << 3), 225 SHOW_ZP = (1 << 3),
235 SHOW_DEV = (1 << 4), 226 SHOW_DEV = (1 << 4),
227 SHOW_DEV2 = (1 << 5),
236} DebugFlags; 228} DebugFlags;
237 229
238void 230void
@@ -262,6 +254,21 @@ print_debug_info(u8 flags) {
262 } 254 }
263 txt_printf("\n"); 255 txt_printf("\n");
264 } 256 }
257 if (flags & SHOW_DEV2) {
258 txt_printf("\nDEV MEM");
259 for (size_t i = 128; i < 256; i++) {
260 if (i % 8 == 0) {
261 txt_printf("\n");
262 }
263 if (i % 16 == 0) {
264 txt_printf("|");
265 } else {
266 txt_printf(" ");
267 }
268 txt_printf("%02x", device_data[i]);
269 }
270 txt_printf("\n");
271 }
265 if (flags & SHOW_WST) { 272 if (flags & SHOW_WST) {
266 txt_printf("\nWST ("); 273 txt_printf("\nWST (");
267 txt_printf("SIZE: %d)", wst_ptr - (uintptr_t)wst); 274 txt_printf("SIZE: %d)", wst_ptr - (uintptr_t)wst);
@@ -333,10 +340,10 @@ main(void) {
333 PROF(uxn_eval_asm(PAGE_PROGRAM), eval_cycles); 340 PROF(uxn_eval_asm(PAGE_PROGRAM), eval_cycles);
334 while(true) { 341 while(true) {
335 txt_position(0, 0); 342 txt_position(0, 0);
336 // print_debug_info(SHOW_WST); 343 print_debug_info(SHOW_DEV2);
337 bios_vblank_wait(); 344 bios_vblank_wait();
338 FRAME_START(); 345 FRAME_START();
339 // PROF(handle_input(&u), input_cycles); 346 PROF(handle_input(), input_cycles);
340 PROF(uxn_eval_asm(PEEK2(&device_data[0x20])), eval_cycles); 347 PROF(uxn_eval_asm(PEEK2(&device_data[0x20])), eval_cycles);
341 // PROF(sound_mix(), mix_cycles); 348 // PROF(sound_mix(), mix_cycles);
342 // TODO: allow configuration to do VSYNC at 15 or 30 fps to avoid too 349 // TODO: allow configuration to do VSYNC at 15 or 30 fps to avoid too
diff --git a/src/uxn-core.c b/src/uxn-core.c
new file mode 100644
index 0000000..6ff4c50
--- /dev/null
+++ b/src/uxn-core.c
@@ -0,0 +1,32 @@
1extern void uxn_eval_asm(u16 pc);
2
3// Stacks (On IWRAM).
4extern u8 wst[256];
5extern u8 rst[256];
6extern uintptr_t wst_ptr;
7extern uintptr_t rst_ptr;
8
9// DEO/DEI mapping functiosn and device data (On IWRAM).
10extern uintptr_t deo_map[16];
11extern uintptr_t dei_map[16];
12extern u8 device_data[256];
13
14// DEBUG: ONLY
15// extern u8 device_0[16];
16// extern u8 device_1[16];
17// extern u8 device_2[16];
18// extern u8 device_3[16];
19// extern u8 device_4[16];
20// extern u8 device_5[16];
21// extern u8 device_6[16];
22// extern u8 device_7[16];
23// extern u8 device_8[16];
24// extern u8 device_a[16];
25// extern u8 device_b[16];
26// extern u8 device_c[16];
27// extern u8 device_d[16];
28// extern u8 device_e[16];
29// extern u8 device_f[16];
30
31EWRAM_BSS
32u8 uxn_ram[KB(64)];