aboutsummaryrefslogtreecommitdiffstats
path: root/src/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input.c')
-rw-r--r--src/input.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/input.c b/src/input.c
new file mode 100644
index 0000000..c78864d
--- /dev/null
+++ b/src/input.c
@@ -0,0 +1,203 @@
1typedef enum {
2 CONTROL_CONTROLLER,
3 CONTROL_MOUSE,
4 CONTROL_KEYBOARD,
5} ControlMethod;
6
7const ControlMethod ctrl_methods[] = {
8 CONTROL_METHODS
9};
10static ControlMethod ctrl_idx = 0;
11
12#define MOUSE_DELTA 1
13typedef struct Mouse {
14 int x;
15 int y;
16} Mouse;
17
18static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2};
19
20void
21handle_input() {
22 poll_keys();
23 if (key_tap(KEY_L) || key_tap(KEY_R)) {
24 // Reset control variables on method switch.
25 switch (ctrl_methods[ctrl_idx]) {
26 case CONTROL_CONTROLLER: {
27 u8 *d = &device_data[0x80];
28 d[2] = 0;
29 uxn_eval_asm(PEEK2(d));
30 d[3] = 0;
31 } break;
32 case CONTROL_MOUSE: {
33 u8 *d = &device_data[0x90];
34 d[6] = 0;
35 d[7] = 0;
36 POKE2(d + 0x2, -10);
37 POKE2(d + 0x4, -10);
38 uxn_eval_asm(PEEK2(d));
39 } break;
40 case CONTROL_KEYBOARD: {
41 toggle_keyboard();
42 } break;
43 }
44
45 // Update ctrl_idx.
46 ctrl_idx = (ctrl_idx + 1 > (int)LEN(ctrl_methods) - 1) ? 0 : ctrl_idx + 1;
47
48 // Initialize controller variables here.
49 if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
50 toggle_keyboard();
51 }
52 }
53
54 if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) {
55 u8 *d = &device_data[0x80];
56 // TODO: We don't need ifs if we use KEY_INPUTS directly and maybe just
57 // swap some things if needed.
58 u8 *flag = &d[2];
59 if (key_tap(KEY_A)) {
60 *flag |= 0x01;
61 } else {
62 *flag &= ~0x01;
63 }
64 if (key_tap(KEY_B)) {
65 *flag |= 0x02;
66 } else {
67 *flag &= ~0x02;
68 }
69 if (key_tap(KEY_SELECT)) {
70 *flag |= 0x04;
71 } else {
72 *flag &= ~0x04;
73 }
74 if (key_tap(KEY_START)) {
75 *flag |= 0x08;
76 } else {
77 *flag &= ~0x08;
78 }
79 if (key_tap(KEY_UP)) {
80 *flag |= 0x10;
81 } else {
82 *flag &= ~0x10;
83 }
84 if (key_tap(KEY_DOWN)) {
85 *flag |= 0x20;
86 } else {
87 *flag &= ~0x20;
88 }
89 if (key_tap(KEY_LEFT)) {
90 *flag |= 0x40;
91 } else {
92 *flag &= ~0x40;
93 }
94 if (key_tap(KEY_RIGHT)) {
95 *flag |= 0x80;
96 } else {
97 *flag &= ~0x80;
98 }
99
100 if (key_prev != key_curr) {
101 uxn_eval_asm(PEEK2(d));
102 }
103 d[3] = 0;
104 } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) {
105 u8 *d = &device_data[0x90];
106 // Detect "mouse key press".
107 u8 flag = d[6];
108 bool event = false;
109 if (key_tap(KEY_B)) {
110 event = true;
111 flag |= 0x01;
112 } else if (key_released(KEY_B)) {
113 event = true;
114 flag &= ~0x01;
115 }
116 if (key_tap(KEY_A)) {
117 event = true;
118 flag |= 0x10;
119 } else if (key_released(KEY_A)) {
120 event = true;
121 flag &= ~0x10;
122 }
123
124 // Handle chording.
125 d[6] = flag;
126 if(flag == 0x10 && (d[6] & 0x01)) {
127 d[7] = 0x01;
128 }
129 if(flag == 0x01 && (d[6] & 0x10)) {
130 d[7] = 0x10;
131 }
132
133 // Detect mouse movement.
134 if (key_pressed(KEY_UP)) {
135 event = true;
136 mouse.y = CLAMP(mouse.y - MOUSE_DELTA, 0, SCREEN_HEIGHT - 8);
137 } else if (key_pressed(KEY_DOWN)) {
138 event = true;
139 mouse.y = CLAMP(mouse.y + MOUSE_DELTA, 0, SCREEN_HEIGHT - 8);
140 }
141 if (key_pressed(KEY_LEFT)) {
142 event = true;
143 mouse.x = CLAMP(mouse.x - MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
144 } else if (key_pressed(KEY_RIGHT)) {
145 event = true;
146 mouse.x = CLAMP(mouse.x + MOUSE_DELTA, 0, SCREEN_WIDTH - 8);
147 }
148
149 // Eval mouse.
150 POKE2(d + 0x2, mouse.x);
151 POKE2(d + 0x4, mouse.y);
152 if (event) {
153 uxn_eval_asm(PEEK2(d));
154 }
155 } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
156 u8 *d = &device_data[0x80];
157 if (key_tap(KEY_LEFT)) {
158 update_cursor(cursor_position - 1);
159 } else if (key_tap(KEY_RIGHT)) {
160 update_cursor(cursor_position + 1);
161 }
162 if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) {
163 update_cursor(cursor_position - KEYBOARD_ROW_SIZE);
164 } else if (key_tap(KEY_DOWN)
165 && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) {
166 update_cursor(cursor_position + KEYBOARD_ROW_SIZE);
167 }
168 if (key_tap(KEY_B)) {
169 u8 symbol = keyboard[cursor_position].symbol;
170 switch (symbol) {
171 case 0x7f: {
172 // Backspace.
173 d[3] = 0x08;
174 } break;
175 case 0x14: {
176 // New line.
177 d[3] = 0x0d;
178 } break;
179 case 0x18: {
180 // Arrow up.
181 d[2] = 0x10;
182 } break;
183 case 0x19: {
184 // Arrow down.
185 d[2] = 0x20;
186 } break;
187 case 0x1b: {
188 // Arrow left.
189 d[2] = 0x40;
190 } break;
191 case 0x1a: {
192 // Arrow right.
193 d[2] = 0x80;
194 } break;
195 default: {
196 d[3] = symbol;
197 } break;
198 }
199 uxn_eval_asm(PEEK2(d));
200 d[3] = 0;
201 }
202 }
203}