diff options
author | Bad Diode <bd@badd10de.dev> | 2022-10-19 12:50:15 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-10-19 12:50:15 +0200 |
commit | f9058cc2dfa087ffcae8d6fe72d9343dcfc9cc15 (patch) | |
tree | 4d54fc6a16a42007ac07edadd7b8b656881953bf /src | |
parent | 088c6408bf61c25ed201e2410de3d02e54892d3d (diff) | |
download | uxn64-f9058cc2dfa087ffcae8d6fe72d9343dcfc9cc15.tar.gz uxn64-f9058cc2dfa087ffcae8d6fe72d9343dcfc9cc15.zip |
Add initial controller support
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 112 | ||||
-rw-r--r-- | src/ppu.c | 8 |
2 files changed, 109 insertions, 11 deletions
@@ -12,13 +12,20 @@ extern u8 _idle_thread_stack[]; | |||
12 | extern u8 _main_thread_stack[]; | 12 | extern u8 _main_thread_stack[]; |
13 | 13 | ||
14 | // | 14 | // |
15 | // Message buffers and queues. | 15 | // Message buffers, queues and devices. |
16 | // | 16 | // |
17 | 17 | ||
18 | #define NUM_PI_MSGS 8 | 18 | #define NUM_PI_MSGS 8 |
19 | static OSMesg pi_msg[NUM_PI_MSGS]; | 19 | static OSMesg pi_msg[NUM_PI_MSGS]; |
20 | static OSMesgQueue pi_msg_queue; | 20 | static OSMesgQueue pi_msg_queue; |
21 | 21 | ||
22 | #define NUM_CONTROLLERS 4 | ||
23 | static OSMesg ctrl_msg[1]; | ||
24 | static OSMesgQueue ctrl_msg_queue; | ||
25 | static OSContStatus ctrl_status[NUM_CONTROLLERS]; | ||
26 | static OSContPad ctrl_pad[NUM_CONTROLLERS]; | ||
27 | static u8 ctrl_bitpattern; | ||
28 | |||
22 | // Handle for rom memory. | 29 | // Handle for rom memory. |
23 | OSPiHandle *rom_handle; | 30 | OSPiHandle *rom_handle; |
24 | 31 | ||
@@ -33,11 +40,19 @@ OSPiHandle *rom_handle; | |||
33 | 40 | ||
34 | #define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X)) | 41 | #define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X)) |
35 | 42 | ||
43 | static u8 uxn_ram[0x10000]; | ||
36 | static Uxn u; | 44 | static Uxn u; |
37 | static Device *devscreen; | 45 | static Device *devscreen; |
38 | static Device *devctrl; | 46 | static Device *devctrl; |
39 | static Device *devmouse; | 47 | static Device *devmouse; |
40 | 48 | ||
49 | #define MOUSE_DELTA 1 | ||
50 | typedef struct Mouse { | ||
51 | s32 x; | ||
52 | s32 y; | ||
53 | // TODO: mouse timeout? | ||
54 | } Mouse; | ||
55 | |||
41 | int | 56 | int |
42 | uxn_halt(Uxn *u, Uint8 error, Uint16 addr) { | 57 | uxn_halt(Uxn *u, Uint8 error, Uint16 addr) { |
43 | (void)u; | 58 | (void)u; |
@@ -180,7 +195,18 @@ screen_deo(Device *d, u8 port) { | |||
180 | } | 195 | } |
181 | 196 | ||
182 | void | 197 | void |
183 | poll_input() { | 198 | init_ctrl(void) { |
199 | osCreateMesgQueue(&ctrl_msg_queue, ctrl_msg, 1); | ||
200 | osSetEventMesg(OS_EVENT_SI, &ctrl_msg_queue, NULL); | ||
201 | osContInit(&ctrl_msg_queue, &ctrl_bitpattern, &ctrl_status[0]); | ||
202 | } | ||
203 | |||
204 | void | ||
205 | handle_input(int i) { | ||
206 | // RESET? | ||
207 | // devctrl->dat[2] = 0; | ||
208 | // uxn_eval(&u, GETVECTOR(devctrl)); | ||
209 | // devctrl->dat[3] = 0; | ||
184 | // NOTE: | 210 | // NOTE: |
185 | // - Analog can act as a mouse and/or dissapear if it was not moved in | 211 | // - Analog can act as a mouse and/or dissapear if it was not moved in |
186 | // X seconds. L/R buttons act as the mouse buttons. | 212 | // X seconds. L/R buttons act as the mouse buttons. |
@@ -188,16 +214,84 @@ poll_input() { | |||
188 | // - MAYBE: The C buttons can control the keyboard somehow? A virtual | 214 | // - MAYBE: The C buttons can control the keyboard somehow? A virtual |
189 | // keyboard that is? With Z to confirm keypresses? | 215 | // keyboard that is? With Z to confirm keypresses? |
190 | // - Start can just pause the application if no other use is in place. | 216 | // - Start can just pause the application if no other use is in place. |
191 | // STUB... | 217 | OSContPad prev_pad = ctrl_pad[i]; |
218 | osContGetReadData(&ctrl_pad[i]); | ||
219 | OSContPad current_pad = ctrl_pad[i]; | ||
220 | // TODO: Check for controller changes. | ||
221 | if (prev_pad.button != current_pad.button) { | ||
222 | u8 *uxn_ctrl = &devctrl->dat[2]; | ||
223 | if (current_pad.button & U_JPAD || current_pad.button & U_CBUTTONS) { | ||
224 | *uxn_ctrl |= 0x10; | ||
225 | } else { | ||
226 | *uxn_ctrl &= ~0x10; | ||
227 | } | ||
228 | if (current_pad.button & D_JPAD || current_pad.button & D_CBUTTONS) { | ||
229 | *uxn_ctrl |= 0x20; | ||
230 | } else { | ||
231 | *uxn_ctrl &= ~0x20; | ||
232 | } | ||
233 | if (current_pad.button & L_JPAD || current_pad.button & L_CBUTTONS) { | ||
234 | *uxn_ctrl |= 0x40; | ||
235 | } else { | ||
236 | *uxn_ctrl &= ~0x40; | ||
237 | } | ||
238 | if (current_pad.button & R_JPAD || current_pad.button & R_CBUTTONS) { | ||
239 | *uxn_ctrl |= 0x80; | ||
240 | } else { | ||
241 | *uxn_ctrl &= ~0x80; | ||
242 | } | ||
243 | if (current_pad.button & A_BUTTON) { | ||
244 | *uxn_ctrl |= 0x01; | ||
245 | } else { | ||
246 | *uxn_ctrl &= ~0x01; | ||
247 | } | ||
248 | if (current_pad.button & B_BUTTON) { | ||
249 | *uxn_ctrl |= 0x02; | ||
250 | } else { | ||
251 | *uxn_ctrl &= ~0x02; | ||
252 | } | ||
253 | if (current_pad.button & START_BUTTON) { | ||
254 | *uxn_ctrl |= 0x08; | ||
255 | } else { | ||
256 | *uxn_ctrl &= ~0x08; | ||
257 | } | ||
258 | if (current_pad.button & Z_TRIG) { | ||
259 | *uxn_ctrl |= 0x04; | ||
260 | } else { | ||
261 | *uxn_ctrl &= ~0x04; | ||
262 | } | ||
263 | uxn_eval(&u, GETVECTOR(devctrl)); | ||
264 | devctrl->dat[3] = 0; | ||
265 | // TODO: L/R mouse ? || stick x || xtick y || errno? | ||
266 | } | ||
267 | // TODO: Check for "mouse" changes. | ||
268 | // if (controller_now != in.controller) { | ||
269 | // devctrl->dat[2] = controller_now; | ||
270 | // uxn_eval(&u, GETVECTOR(devctrl)); | ||
271 | // in.controller = controller_now; | ||
272 | // } | ||
192 | } | 273 | } |
193 | 274 | ||
194 | void | 275 | void |
195 | handle_input() { | 276 | poll_input() { |
196 | // STUB... | 277 | // Get current ctrl status. |
278 | osContStartQuery(&ctrl_msg_queue); | ||
279 | osRecvMesg(&ctrl_msg_queue, NULL, OS_MESG_BLOCK); | ||
280 | |||
281 | // Reads the data from the first active controller. | ||
282 | for(int i = 0; i < NUM_CONTROLLERS; i++){ | ||
283 | osContGetQuery(&ctrl_status[i]); | ||
284 | if(((ctrl_bitpattern >> i) & 1) && (ctrl_status[i].errno == 0)){ | ||
285 | if((ctrl_status[i].type & CONT_TYPE_MASK) == CONT_TYPE_NORMAL){ | ||
286 | osContStartReadData(&ctrl_msg_queue); | ||
287 | osRecvMesg(&ctrl_msg_queue, NULL, OS_MESG_BLOCK); | ||
288 | handle_input(i); | ||
289 | break; | ||
290 | } | ||
291 | } | ||
292 | } | ||
197 | } | 293 | } |
198 | 294 | ||
199 | static u8 uxn_ram[0x10000]; | ||
200 | |||
201 | void | 295 | void |
202 | init_uxn(Uxn *u) { | 296 | init_uxn(Uxn *u) { |
203 | // Setup UXN memory. | 297 | // Setup UXN memory. |
@@ -237,15 +331,13 @@ init_uxn(Uxn *u) { | |||
237 | static void | 331 | static void |
238 | main_proc(void *arg) { | 332 | main_proc(void *arg) { |
239 | (void)arg; | 333 | (void)arg; |
240 | |||
241 | init_ppu(); | 334 | init_ppu(); |
242 | 335 | init_ctrl(); | |
243 | init_uxn(&u); | 336 | init_uxn(&u); |
244 | 337 | ||
245 | // Main loop. | 338 | // Main loop. |
246 | while (true) { | 339 | while (true) { |
247 | poll_input(); | 340 | poll_input(); |
248 | handle_input(); | ||
249 | uxn_eval(&u, GETVECTOR(devscreen)); | 341 | uxn_eval(&u, GETVECTOR(devscreen)); |
250 | blit_framebuffer(); | 342 | blit_framebuffer(); |
251 | swap_buffers(); | 343 | swap_buffers(); |
@@ -149,6 +149,12 @@ blit_framebuffer(void) { | |||
149 | } | 149 | } |
150 | dirty_lines[j] = 0; | 150 | dirty_lines[j] = 0; |
151 | } | 151 | } |
152 | fb_copy_test(); // CPU blit | 152 | // FIXME: This is a hack, we should only have to write to the framebuffer |
153 | // once, if there were actually no changes is better not to swap buffers at | ||
154 | // all right? | ||
155 | fb_copy_test(); // CPU blit (A) | ||
156 | current_fb ^= 1; | ||
157 | fb_copy_test(); // CPU blit (B) | ||
158 | current_fb ^= 1; | ||
153 | reqdraw = 0; | 159 | reqdraw = 0; |
154 | } | 160 | } |