aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-10-19 12:50:15 +0200
committerBad Diode <bd@badd10de.dev>2022-10-19 12:50:15 +0200
commitf9058cc2dfa087ffcae8d6fe72d9343dcfc9cc15 (patch)
tree4d54fc6a16a42007ac07edadd7b8b656881953bf
parent088c6408bf61c25ed201e2410de3d02e54892d3d (diff)
downloaduxn64-f9058cc2dfa087ffcae8d6fe72d9343dcfc9cc15.tar.gz
uxn64-f9058cc2dfa087ffcae8d6fe72d9343dcfc9cc15.zip
Add initial controller support
-rw-r--r--Makefile4
-rw-r--r--src/main.c112
-rw-r--r--src/ppu.c8
3 files changed, 111 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index f402bd2..2016e10 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ SDK_BIN := $(SDK_BASE)/bin
8LIBULTRA_DIR := $(SDK_BASE)/libultra 8LIBULTRA_DIR := $(SDK_BASE)/libultra
9LIBULTRA_INC := $(LIBULTRA_DIR)/usr/include 9LIBULTRA_INC := $(LIBULTRA_DIR)/usr/include
10LIBULTRA := $(LIBULTRA_DIR)/usr/lib/libgultra.a 10LIBULTRA := $(LIBULTRA_DIR)/usr/lib/libgultra.a
11EMULATOR := ares
11 12
12# Source code location and files to watch for changes. 13# Source code location and files to watch for changes.
13SRC_DIR := src 14SRC_DIR := src
@@ -71,8 +72,7 @@ $(BIN): $(ELF) $(OBJECTS) $(WATCH_SRC) | $(BUILD_DIR)
71 72
72# Test the output .n64 in an emulator. 73# Test the output .n64 in an emulator.
73run: $(BIN) 74run: $(BIN)
74 # TODO: Test roms with MAME or cen64 instead of mupen64 for better accuracy. 75 $(EMULATOR) $(BIN)
75 mupen64plus $(BIN)
76 76
77# Remove build directory. 77# Remove build directory.
78clean: 78clean:
diff --git a/src/main.c b/src/main.c
index 53612d6..d457140 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,13 +12,20 @@ extern u8 _idle_thread_stack[];
12extern u8 _main_thread_stack[]; 12extern 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
19static OSMesg pi_msg[NUM_PI_MSGS]; 19static OSMesg pi_msg[NUM_PI_MSGS];
20static OSMesgQueue pi_msg_queue; 20static OSMesgQueue pi_msg_queue;
21 21
22#define NUM_CONTROLLERS 4
23static OSMesg ctrl_msg[1];
24static OSMesgQueue ctrl_msg_queue;
25static OSContStatus ctrl_status[NUM_CONTROLLERS];
26static OSContPad ctrl_pad[NUM_CONTROLLERS];
27static u8 ctrl_bitpattern;
28
22// Handle for rom memory. 29// Handle for rom memory.
23OSPiHandle *rom_handle; 30OSPiHandle *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
43static u8 uxn_ram[0x10000];
36static Uxn u; 44static Uxn u;
37static Device *devscreen; 45static Device *devscreen;
38static Device *devctrl; 46static Device *devctrl;
39static Device *devmouse; 47static Device *devmouse;
40 48
49#define MOUSE_DELTA 1
50typedef struct Mouse {
51 s32 x;
52 s32 y;
53 // TODO: mouse timeout?
54} Mouse;
55
41int 56int
42uxn_halt(Uxn *u, Uint8 error, Uint16 addr) { 57uxn_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
182void 197void
183poll_input() { 198init_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
204void
205handle_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
194void 275void
195handle_input() { 276poll_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
199static u8 uxn_ram[0x10000];
200
201void 295void
202init_uxn(Uxn *u) { 296init_uxn(Uxn *u) {
203 // Setup UXN memory. 297 // Setup UXN memory.
@@ -237,15 +331,13 @@ init_uxn(Uxn *u) {
237static void 331static void
238main_proc(void *arg) { 332main_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();
diff --git a/src/ppu.c b/src/ppu.c
index 51dc8cb..bd1ce3c 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -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}