commit a34ceda

neauoire  ·  2022-03-27 02:58:48 +0000 UTC
parent 51542bc
Starting controller
8 files changed,  +266, -192
+3, -3
 1@@ -9,10 +9,10 @@ echo "Building.."
 2 mkdir -p bin
 3 
 4 # Build(debug)
 5-gcc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/uxn.c src/devices/system.c src/devices/screen.c src/uxn11.c -o bin/uxn11 -lX11
 6+gcc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/uxn.c src/devices/system.c src/devices/screen.c src/devices/controller.c src/uxn11.c -o bin/uxn11 -lX11
 7 
 8 # Build(release)
 9-# gcc src/uxn.c src/devices/system.c src/devices/screen.c src/uxn11.c -o bin/uxn11 -lX11
10+# gcc src/uxn.c src/devices/system.c src/devices/screen.c src/devices/controller.c src/uxn11.c -o bin/uxn11 -lX11
11 
12 echo "Running.."
13-bin/uxn11 etc/screen.rom
14+bin/uxn11 etc/controller.rom
+0, -0
+52, -0
 1@@ -0,0 +1,52 @@
 2+#include "../uxn.h"
 3+#include "controller.h"
 4+
 5+/*
 6+Copyright (c) 2021 Devine Lu Linvega
 7+Copyright (c) 2021 Andrew Alderwick
 8+
 9+Permission to use, copy, modify, and distribute this software for any
10+purpose with or without fee is hereby granted, provided that the above
11+copyright notice and this permission notice appear in all copies.
12+
13+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14+WITH REGARD TO THIS SOFTWARE.
15+*/
16+
17+void
18+controller_down(Device *d, Uint8 mask)
19+{
20+	if(mask) {
21+		d->dat[2] |= mask;
22+		uxn_eval(d->u, GETVECTOR(d));
23+	}
24+}
25+
26+void
27+controller_up(Device *d, Uint8 mask)
28+{
29+	if(mask) {
30+		d->dat[2] &= (~mask);
31+		uxn_eval(d->u, GETVECTOR(d));
32+	}
33+}
34+
35+void
36+controller_key(Device *d, Uint8 key)
37+{
38+	if(key) {
39+		d->dat[3] = key;
40+		uxn_eval(d->u, GETVECTOR(d));
41+		d->dat[3] = 0x00;
42+	}
43+}
44+
45+void
46+controller_special(Device *d, Uint8 key)
47+{
48+	if(key) {
49+		d->dat[4] = key;
50+		uxn_eval(d->u, GETVECTOR(d));
51+		d->dat[4] = 0x00;
52+	}
53+}
+16, -0
 1@@ -0,0 +1,16 @@
 2+/*
 3+Copyright (c) 2021 Devine Lu Linvega
 4+Copyright (c) 2021 Andrew Alderwick
 5+
 6+Permission to use, copy, modify, and distribute this software for any
 7+purpose with or without fee is hereby granted, provided that the above
 8+copyright notice and this permission notice appear in all copies.
 9+
10+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11+WITH REGARD TO THIS SOFTWARE.
12+*/
13+
14+void controller_down(Device *d, Uint8 mask);
15+void controller_up(Device *d, Uint8 mask);
16+void controller_key(Device *d, Uint8 key);
17+void controller_special(Device *d, Uint8 key);
+0, -150
  1@@ -1,150 +0,0 @@
  2-#include "ppu.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-static Uint8 blending[5][16] = {
 17-	{0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0},
 18-	{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3},
 19-	{1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1},
 20-	{2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2},
 21-	{1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}};
 22-
 23-static Uint8 font[][8] = {
 24-	{0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c},
 25-	{0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10},
 26-	{0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80, 0x80, 0xfe},
 27-	{0x00, 0x7c, 0x82, 0x02, 0x1c, 0x02, 0x82, 0x7c},
 28-	{0x00, 0x0c, 0x14, 0x24, 0x44, 0x84, 0xfe, 0x04},
 29-	{0x00, 0xfe, 0x80, 0x80, 0x7c, 0x02, 0x82, 0x7c},
 30-	{0x00, 0x7c, 0x82, 0x80, 0xfc, 0x82, 0x82, 0x7c},
 31-	{0x00, 0x7c, 0x82, 0x02, 0x1e, 0x02, 0x02, 0x02},
 32-	{0x00, 0x7c, 0x82, 0x82, 0x7c, 0x82, 0x82, 0x7c},
 33-	{0x00, 0x7c, 0x82, 0x82, 0x7e, 0x02, 0x82, 0x7c},
 34-	{0x00, 0x7c, 0x82, 0x02, 0x7e, 0x82, 0x82, 0x7e},
 35-	{0x00, 0xfc, 0x82, 0x82, 0xfc, 0x82, 0x82, 0xfc},
 36-	{0x00, 0x7c, 0x82, 0x80, 0x80, 0x80, 0x82, 0x7c},
 37-	{0x00, 0xfc, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfc},
 38-	{0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x82, 0x7c},
 39-	{0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80, 0x80, 0x80}};
 40-
 41-void
 42-ppu_palette(Ppu *p, Uint8 *addr)
 43-{
 44-	int i, shift;
 45-	for(i = 0, shift = 4; i < 4; ++i, shift ^= 4) {
 46-		Uint8
 47-			r = (addr[0 + i / 2] >> shift) & 0x0f,
 48-			g = (addr[2 + i / 2] >> shift) & 0x0f,
 49-			b = (addr[4 + i / 2] >> shift) & 0x0f;
 50-		p->palette[i] = 0x0f000000 | r << 16 | g << 8 | b;
 51-		p->palette[i] |= p->palette[i] << 4;
 52-	}
 53-	p->fg.changed = p->bg.changed = 1;
 54-}
 55-
 56-void
 57-ppu_resize(Ppu *p, Uint16 width, Uint16 height)
 58-{
 59-	Uint8
 60-		*bg = realloc(p->bg.pixels, width * height),
 61-		*fg = realloc(p->fg.pixels, width * height);
 62-	if(bg) p->bg.pixels = bg;
 63-	if(fg) p->fg.pixels = fg;
 64-	if(bg && fg) {
 65-		p->width = width;
 66-		p->height = height;
 67-		ppu_clear(p, &p->bg);
 68-		ppu_clear(p, &p->fg);
 69-	}
 70-}
 71-
 72-void
 73-ppu_clear(Ppu *p, Layer *layer)
 74-{
 75-	Uint32 i, size = p->width * p->height;
 76-	for(i = 0; i < size; ++i)
 77-		layer->pixels[i] = 0x00;
 78-	layer->changed = 1;
 79-}
 80-
 81-#pragma weak ppu_redraw
 82-void
 83-ppu_redraw(Ppu *p, Uint32 *screen)
 84-{
 85-	Uint32 i, size = p->width * p->height, palette[16];
 86-	for(i = 0; i < 16; ++i)
 87-		palette[i] = p->palette[(i >> 2) ? (i >> 2) : (i & 3)];
 88-	for(i = 0; i < size; ++i)
 89-		screen[i] = palette[p->fg.pixels[i] << 2 | p->bg.pixels[i]];
 90-	p->fg.changed = p->bg.changed = 0;
 91-}
 92-
 93-void
 94-ppu_write(Ppu *p, Layer *layer, Uint16 x, Uint16 y, Uint8 color)
 95-{
 96-	if(x < p->width && y < p->height) {
 97-		Uint32 i = x + y * p->width;
 98-		Uint8 prev = layer->pixels[i];
 99-		if(color != prev) {
100-			layer->pixels[i] = color;
101-			layer->changed = 1;
102-		}
103-	}
104-}
105-
106-void
107-ppu_blit(Ppu *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy, Uint8 twobpp)
108-{
109-	int v, h, opaque = blending[4][color];
110-	for(v = 0; v < 8; ++v) {
111-		Uint16 c = sprite[v] | (twobpp ? sprite[v + 8] : 0) << 8;
112-		for(h = 7; h >= 0; --h, c >>= 1) {
113-			Uint8 ch = (c & 1) | ((c >> 7) & 2);
114-			if(opaque || ch)
115-				ppu_write(p,
116-					layer,
117-					x + (flipx ? 7 - h : h),
118-					y + (flipy ? 7 - v : v),
119-					blending[ch][color]);
120-		}
121-	}
122-}
123-
124-void
125-ppu_debug(Ppu *p, Uint8 *stack, Uint8 wptr, Uint8 rptr, Uint8 *memory)
126-{
127-	Uint8 i, x, y, b;
128-	for(i = 0; i < 0x20; ++i) {
129-		x = ((i % 8) * 3 + 1) * 8, y = (i / 8 + 1) * 8, b = stack[i];
130-		/* working stack */
131-		ppu_blit(p, &p->fg, x, y, font[(b >> 4) & 0xf], 1 + (wptr == i) * 0x7, 0, 0, 0);
132-		ppu_blit(p, &p->fg, x + 8, y, font[b & 0xf], 1 + (wptr == i) * 0x7, 0, 0, 0);
133-		y = 0x28 + (i / 8 + 1) * 8;
134-		b = memory[i];
135-		/* return stack */
136-		ppu_blit(p, &p->fg, x, y, font[(b >> 4) & 0xf], 3, 0, 0, 0);
137-		ppu_blit(p, &p->fg, x + 8, y, font[b & 0xf], 3, 0, 0, 0);
138-	}
139-	/* return pointer */
140-	ppu_blit(p, &p->fg, 0x8, y + 0x10, font[(rptr >> 4) & 0xf], 0x2, 0, 0, 0);
141-	ppu_blit(p, &p->fg, 0x10, y + 0x10, font[rptr & 0xf], 0x2, 0, 0, 0);
142-	/* guides */
143-	for(x = 0; x < 0x10; ++x) {
144-		ppu_write(p, &p->fg, x, p->height / 2, 2);
145-		ppu_write(p, &p->fg, p->width - x, p->height / 2, 2);
146-		ppu_write(p, &p->fg, p->width / 2, p->height - x, 2);
147-		ppu_write(p, &p->fg, p->width / 2, x, 2);
148-		ppu_write(p, &p->fg, p->width / 2 - 0x10 / 2 + x, p->height / 2, 2);
149-		ppu_write(p, &p->fg, p->width / 2, p->height / 2 - 0x10 / 2 + x, 2);
150-	}
151-}
+0, -37
 1@@ -1,37 +0,0 @@
 2-#include <stdlib.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-typedef unsigned char Uint8;
17-typedef unsigned short Uint16;
18-typedef unsigned int Uint32;
19-
20-typedef struct Layer {
21-	Uint8 *pixels;
22-	Uint8 changed;
23-} Layer;
24-
25-typedef struct Ppu {
26-	Uint32 palette[4];
27-	Uint16 width, height;
28-	Layer fg, bg;
29-} Ppu;
30-
31-void ppu_palette(Ppu *p, Uint8 *addr);
32-void ppu_resize(Ppu *p, Uint16 width, Uint16 height);
33-void ppu_clear(Ppu *p, Layer *layer);
34-void ppu_redraw(Ppu *p, Uint32 *screen);
35-
36-void ppu_write(Ppu *p, Layer *layer, Uint16 x, Uint16 y, Uint8 color);
37-void ppu_blit(Ppu *p, Layer *layer, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 color, Uint8 flipx, Uint8 flipy, Uint8 twobpp);
38-void ppu_debug(Ppu *p, Uint8 *stack, Uint8 wptr, Uint8 rptr, Uint8 *memory);
+47, -2
 1@@ -12,6 +12,9 @@
 2 #include "uxn.h"
 3 #include "devices/system.h"
 4 #include "devices/screen.h"
 5+#include "devices/controller.h"
 6+
 7+static Device *devctrl;
 8 
 9 static int
10 error(char *msg, const char *err)
11@@ -64,6 +67,18 @@ load(Uxn *u, char *filepath)
12 	return 1;
13 }
14 
15+/* /usr/include/X11/keysymdef.h */
16+
17+#define XK_Left 0xff51
18+#define XK_Up 0xff52
19+#define XK_Right 0xff53
20+#define XK_Down 0xff54
21+
22+#define XK_Home 0xff50
23+#define XK_Shift 0xffe1
24+#define XK_Control 0xffe3
25+#define XK_Alt 0xffe9
26+
27 void
28 processEvent(Display *display, Window window, XImage *ximage, int width, int height)
29 {
30@@ -73,6 +88,28 @@ processEvent(Display *display, Window window, XImage *ximage, int width, int hei
31 	case Expose:
32 		XPutImage(display, window, DefaultGC(display, 0), ximage, 0, 0, 0, 0, width, height);
33 		break;
34+	case KeyPress: {
35+		XKeyPressedEvent *e = (XKeyPressedEvent *)&ev;
36+		if(e->keycode == XKeysymToKeycode(display, XK_Up)) controller_down(devctrl, 0x10);
37+		if(e->keycode == XKeysymToKeycode(display, XK_Down)) controller_down(devctrl, 0x20);
38+		if(e->keycode == XKeysymToKeycode(display, XK_Left)) controller_down(devctrl, 0x40);
39+		if(e->keycode == XKeysymToKeycode(display, XK_Right)) controller_down(devctrl, 0x80);
40+		if(e->keycode == XKeysymToKeycode(display, XK_Control)) controller_down(devctrl, 0x01);
41+		if(e->keycode == XKeysymToKeycode(display, XK_Alt)) controller_down(devctrl, 0x02);
42+		if(e->keycode == XKeysymToKeycode(display, XK_Shift)) controller_down(devctrl, 0x04);
43+		if(e->keycode == XKeysymToKeycode(display, XK_Home)) controller_down(devctrl, 0x08);
44+	} break;
45+	case KeyRelease: {
46+		XKeyPressedEvent *e = (XKeyPressedEvent *)&ev;
47+		if(e->keycode == XKeysymToKeycode(display, XK_Up)) controller_up(devctrl, 0x10);
48+		if(e->keycode == XKeysymToKeycode(display, XK_Down)) controller_up(devctrl, 0x20);
49+		if(e->keycode == XKeysymToKeycode(display, XK_Left)) controller_up(devctrl, 0x40);
50+		if(e->keycode == XKeysymToKeycode(display, XK_Right)) controller_up(devctrl, 0x80);
51+		if(e->keycode == XKeysymToKeycode(display, XK_Control)) controller_up(devctrl, 0x01);
52+		if(e->keycode == XKeysymToKeycode(display, XK_Alt)) controller_up(devctrl, 0x02);
53+		if(e->keycode == XKeysymToKeycode(display, XK_Shift)) controller_up(devctrl, 0x04);
54+		if(e->keycode == XKeysymToKeycode(display, XK_Home)) controller_up(devctrl, 0x08);
55+	} break;
56 	case ButtonPress:
57 		exit(0);
58 	}
59@@ -91,7 +128,7 @@ start(Uxn *u)
60 	/* empty    */ uxn_port(u, 0x5, nil_dei, nil_deo);
61 	/* empty    */ uxn_port(u, 0x6, nil_dei, nil_deo);
62 	/* empty    */ uxn_port(u, 0x7, nil_dei, nil_deo);
63-	/* empty    */ uxn_port(u, 0x8, nil_dei, nil_deo);
64+	/* control  */ devctrl = uxn_port(u, 0x8, nil_dei, nil_deo);
65 	/* empty    */ uxn_port(u, 0x9, nil_dei, nil_deo);
66 	/* file     */ uxn_port(u, 0xa, nil_dei, nil_deo);
67 	/* datetime */ uxn_port(u, 0xb, nil_dei, nil_deo);
68@@ -102,6 +139,11 @@ start(Uxn *u)
69 	return 1;
70 }
71 
72+void
73+redraw(void)
74+{
75+}
76+
77 int
78 main(int argc, char **argv)
79 {
80@@ -132,10 +174,13 @@ main(int argc, char **argv)
81 
82 	ximage = XCreateImage(display, visual, DefaultDepth(display, DefaultScreen(display)), ZPixmap, 0, (char *)uxn_screen.pixels, uxn_screen.width, uxn_screen.height, 32, 0);
83 
84-	XSelectInput(display, window, ButtonPressMask | ExposureMask);
85+	XSelectInput(display, window, ButtonPressMask | ExposureMask | KeyPressMask | KeyReleaseMask);
86 	XMapWindow(display, window);
87 	while(1) {
88 		processEvent(display, window, ximage, uxn_screen.width, uxn_screen.height);
89+
90+		if(uxn_screen.fg.changed || uxn_screen.bg.changed)
91+			redraw();
92 	}
93 	return 0;
94 }
+148, -0
  1@@ -0,0 +1,148 @@
  2+#include <stdio.h>
  3+#include <stdlib.h>
  4+
  5+#include "uxn.h"
  6+#include "devices/system.h"
  7+#include "devices/file.h"
  8+#include "devices/datetime.h"
  9+
 10+/*
 11+Copyright (c) 2021 Devine Lu Linvega
 12+
 13+Permission to use, copy, modify, and distribute this software for any
 14+purpose with or without fee is hereby granted, provided that the above
 15+copyright notice and this permission notice appear in all copies.
 16+
 17+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 18+WITH REGARD TO THIS SOFTWARE.
 19+*/
 20+
 21+static Device *devfile0;
 22+
 23+static int
 24+error(char *msg, const char *err)
 25+{
 26+	fprintf(stderr, "Error %s: %s\n", msg, err);
 27+	return 0;
 28+}
 29+
 30+void
 31+system_deo_special(Device *d, Uint8 port)
 32+{
 33+	(void)d;
 34+	(void)port;
 35+}
 36+
 37+static void
 38+console_deo(Device *d, Uint8 port)
 39+{
 40+	FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr
 41+												  : 0;
 42+	if(fd) {
 43+		fputc(d->dat[port], fd);
 44+		fflush(fd);
 45+	}
 46+}
 47+
 48+static void
 49+file_deo(Device *d, Uint8 port)
 50+{
 51+	file_i_deo(d - devfile0, d, port);
 52+}
 53+
 54+static Uint8
 55+file_dei(Device *d, Uint8 port)
 56+{
 57+	return file_i_dei(d - devfile0, d, port);
 58+}
 59+
 60+static Uint8
 61+nil_dei(Device *d, Uint8 port)
 62+{
 63+	return d->dat[port];
 64+}
 65+
 66+static void
 67+nil_deo(Device *d, Uint8 port)
 68+{
 69+	(void)d;
 70+	(void)port;
 71+}
 72+
 73+static int
 74+console_input(Uxn *u, char c)
 75+{
 76+	Device *d = &u->dev[1];
 77+	d->dat[0x2] = c;
 78+	return uxn_eval(u, GETVECTOR(d));
 79+}
 80+
 81+static void
 82+run(Uxn *u)
 83+{
 84+	Device *d = &u->dev[0];
 85+	while(!d->dat[0xf]) {
 86+		int c = fgetc(stdin);
 87+		if(c != EOF)
 88+			console_input(u, (Uint8)c);
 89+	}
 90+}
 91+
 92+static int
 93+load(Uxn *u, char *filepath)
 94+{
 95+	FILE *f;
 96+	int r;
 97+	if(!(f = fopen(filepath, "rb"))) return 0;
 98+	r = fread(u->ram + PAGE_PROGRAM, 1, 0x10000 - PAGE_PROGRAM, f);
 99+	fclose(f);
100+	if(r < 1) return 0;
101+	fprintf(stderr, "Loaded %s\n", filepath);
102+	return 1;
103+}
104+
105+static int
106+start(Uxn *u)
107+{
108+	if(!uxn_boot(u, (Uint8 *)calloc(0x10000, sizeof(Uint8))))
109+		return error("Boot", "Failed");
110+	/* system   */ uxn_port(u, 0x0, system_dei, system_deo);
111+	/* console  */ uxn_port(u, 0x1, nil_dei, console_deo);
112+	/* empty    */ uxn_port(u, 0x2, nil_dei, nil_deo);
113+	/* empty    */ uxn_port(u, 0x3, nil_dei, nil_deo);
114+	/* empty    */ uxn_port(u, 0x4, nil_dei, nil_deo);
115+	/* empty    */ uxn_port(u, 0x5, nil_dei, nil_deo);
116+	/* empty    */ uxn_port(u, 0x6, nil_dei, nil_deo);
117+	/* empty    */ uxn_port(u, 0x7, nil_dei, nil_deo);
118+	/* empty    */ uxn_port(u, 0x8, nil_dei, nil_deo);
119+	/* empty    */ uxn_port(u, 0x9, nil_dei, nil_deo);
120+	/* file0    */ devfile0 = uxn_port(u, 0xa, file_dei, file_deo);
121+	/* file1    */ uxn_port(u, 0xb, file_dei, file_deo);
122+	/* datetime */ uxn_port(u, 0xc, datetime_dei, nil_deo);
123+	/* empty    */ uxn_port(u, 0xd, nil_dei, nil_deo);
124+	/* empty    */ uxn_port(u, 0xe, nil_dei, nil_deo);
125+	/* empty    */ uxn_port(u, 0xf, nil_dei, nil_deo);
126+	return 1;
127+}
128+
129+int
130+main(int argc, char **argv)
131+{
132+	Uxn u;
133+	int i;
134+	if(argc < 2)
135+		return error("Usage", "uxncli game.rom args");
136+	if(!start(&u))
137+		return error("Start", "Failed");
138+	if(!load(&u, argv[1]))
139+		return error("Load", "Failed");
140+	if(!uxn_eval(&u, PAGE_PROGRAM))
141+		return error("Init", "Failed");
142+	for(i = 2; i < argc; i++) {
143+		char *p = argv[i];
144+		while(*p) console_input(&u, *p++);
145+		console_input(&u, '\n');
146+	}
147+	run(&u);
148+	return 0;
149+}