commit d07e885

pnthr  ·  2026-07-17 16:40:12 +0000 UTC
parent c30e59b
Added double buffer and removed gnu plus some unused things
3 files changed,  +63, -45
+5, -0
 1@@ -9,6 +9,11 @@
 2 /*-test
 3 /screenshot-*.bmp
 4 
 5+src/wlr-layer-shell-client-protocol.c
 6+src/wlr-layer-shell-client-protocol.h
 7+src/xdg-shell-client-protocol.h
 8+src/xdg-shell-protocol.c
 9+
10 *snarf
11 *theme
12 
+4, -3
 1@@ -3,11 +3,12 @@ DEBUG_flags=-std=c99 -D_POSIX_C_SOURCE=199309L -DDEBUG -Wall -Wno-unknown-pragma
 2 PREFIX=${HOME}/.local
 3 
 4 WAYLAND_SCANNER=wayland-scanner
 5-XDG_XML=$(shell pkg-config --variable=pkgdatadir wayland-protocols)/stable/xdg-shell/xdg-shell.xml
 6+XDG_XML=`pkg-config --variable=pkgdatadir wayland-protocols`/stable/xdg-shell/xdg-shell.xml
 7 WLR_XML=src/wlr-layer-shell-unstable-v1.xml
 8 
 9 PROTO_C=src/xdg-shell-protocol.c src/wlr-layer-shell-client-protocol.c
10 PROTO_H=src/xdg-shell-client-protocol.h src/wlr-layer-shell-client-protocol.h
11+LIBS=`pkg-config --cflags --libs wayland-client xkbcommon`
12 
13 run: bin/uxn12 bin/m_pc.rom bin/perifs.rom
14 	bin/uxn12 bin/m_pc.rom bin/perifs.rom run
15@@ -50,10 +51,10 @@ archive:
16 
17 bin/uxn12: src/uxn12.c $(PROTO_C) $(PROTO_H)
18 	mkdir -p bin
19-	cc ${RELEASE_flags} ${CFLAGS} -s src/uxn12.c $(PROTO_C) -lwayland-client -lxkbcommon -o bin/uxn12
20+	cc ${RELEASE_flags} ${CFLAGS} -s src/uxn12.c $(PROTO_C) $(LIBS) -o bin/uxn12
21 bin/uxn12-debug: src/uxn12.c $(PROTO_C) $(PROTO_H)
22 	mkdir -p bin
23-	cc ${DEBUG_flags} ${CFLAGS} -s src/uxn12.c $(PROTO_C) -lwayland-client -lxkbcommon -o bin/uxn12-debug
24+	cc ${DEBUG_flags} ${CFLAGS} -s src/uxn12.c $(PROTO_C) $(LIBS) -o bin/uxn12-debug
25 
26 # Tools
27 
+54, -42
  1@@ -1,10 +1,8 @@
  2-#define _GNU_SOURCE
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <unistd.h>
  6 #include <string.h>
  7 #include <sys/mman.h>
  8-#include <sys/timerfd.h>
  9 #include <poll.h>
 10 #include <wayland-client.h>
 11 #include <xkbcommon/xkbcommon.h>
 12@@ -54,7 +52,7 @@ static inline void poke2(Uint8 *d, Uint16 v) { d[0] = v >> 8, d[1] = v; }
 13 @|System ------------------------------------------------------------ */
 14 
 15 static char *system_boot_path;
 16-static void emu_screenshot();
 17+static void emu_screenshot(void);
 18 
 19 static void
 20 system_print(char *name, int r)
 21@@ -159,11 +157,7 @@ console_input(int c, unsigned int type)
 22 		uxn_eval(console_vector);
 23 }
 24 
 25-#undef _POSIX_C_SOURCE
 26-#define _POSIX_C_SOURCE 200112L
 27-
 28 #include <signal.h>
 29-#include <sys/select.h>
 30 #include <sys/wait.h>
 31 
 32 #ifdef __linux
 33@@ -355,6 +349,8 @@ static int screen_width, screen_height, screen_wmar2, screen_hmar2;
 34 static int *screen_pixels, screen_palette[16];
 35 static Uint8 *screen_layers;
 36 
 37+void emu_redraw(void), emu_resize(void);
 38+
 39 static const Uint8 blend_lut[16][2][4] = {
 40 	{{0, 0, 1, 2}, {0, 0, 4, 8}},
 41 	{{0, 1, 2, 3}, {0, 4, 8, 12}},
 42@@ -373,7 +369,6 @@ static const Uint8 blend_lut[16][2][4] = {
 43 	{{3, 2, 3, 1}, {12, 8, 12, 4}},
 44 	{{3, 3, 1, 2}, {12, 12, 4, 8}}};
 45 
 46-void emu_redraw(void), emu_resize(void);
 47 
 48 static void
 49 system_deo_colorize(void)
 50@@ -435,7 +430,6 @@ screen_redraw(void)
 51 			}
 52 		}
 53 	}
 54-	emu_redraw();
 55 	screen_reqdraw = 0;
 56 }
 57 
 58@@ -1104,17 +1098,17 @@ static struct xdg_wm_base *emu_wm;
 59 static struct wl_surface *emu_surf;
 60 static struct xdg_surface *emu_xdgsurf;
 61 static struct xdg_toplevel *emu_top;
 62-static struct wl_buffer *emu_buf;
 63+static struct wl_buffer *emu_bufs[2];
 64 static struct zwlr_layer_shell_v1 *emu_layer_shell;
 65 static struct zwlr_layer_surface_v1 *emu_layer_surf;
 66 static int use_layer_shell = 0;
 67 static int layer_shell_x = 0;
 68 static int layer_shell_y = 0;
 69-static int emu_timer;
 70 static int emu_configured;
 71+static int active_buf;
 72 
 73 static void *shm_data;
 74-static int shm_size, shm_width, shm_height;
 75+static int shm_size, shm_bufsize, shm_width, shm_height;
 76 
 77 static struct xkb_context *xkb_ctx;
 78 static struct xkb_keymap *xkb_map;
 79@@ -1134,30 +1128,56 @@ emu_resize(void)
 80 		int fd;
 81 		if(shm_data)
 82 			munmap(shm_data, shm_size);
 83-		if(emu_buf)
 84-			wl_buffer_destroy(emu_buf);
 85-		fd = memfd_create("uxn-wl", MFD_CLOEXEC);
 86-		ftruncate(fd, size);
 87-		shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 88-		pool = wl_shm_create_pool(emu_shm, fd, size);
 89-		emu_buf = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888);
 90+		if(emu_bufs[0])
 91+			wl_buffer_destroy(emu_bufs[0]);
 92+		if(emu_bufs[1])
 93+			wl_buffer_destroy(emu_bufs[1]);
 94+		char tmpl[] = "/tmp/uxn-wl-XXXXXX";
 95+		fd = mkstemp(tmpl);
 96+		unlink(tmpl);
 97+		ftruncate(fd, size * 2);
 98+		shm_data = mmap(NULL, size * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 99+		pool = wl_shm_create_pool(emu_shm, fd, size * 2);
100+		emu_bufs[0] = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888);
101+		emu_bufs[1] = wl_shm_pool_create_buffer(pool, size, width, height, stride, WL_SHM_FORMAT_XRGB8888);
102 		wl_shm_pool_destroy(pool);
103 		close(fd);
104-		shm_size = size, shm_width = width, shm_height = height;
105+		shm_size = size * 2, shm_bufsize = size, shm_width = width, shm_height = height;
106 	}
107-	screen_pixels = (int *)shm_data;
108+	screen_pixels = (int *)((Uint8 *)shm_data + active_buf * shm_bufsize);
109+	active_buf = 0;
110 }
111 
112+static void frame_callback(void *, struct wl_callback *, uint32_t);
113+
114+static const struct wl_callback_listener frame_listener = {
115+	.done = frame_callback,
116+};
117+
118 void
119 emu_redraw(void)
120 {
121 	if(!emu_configured)
122 		return;
123-	wl_surface_attach(emu_surf, emu_buf, 0, 0);
124+	wl_callback_add_listener(wl_surface_frame(emu_surf), &frame_listener, NULL);
125+	wl_surface_attach(emu_surf, emu_bufs[active_buf], 0, 0);
126 	wl_surface_damage_buffer(emu_surf, 0, 0, screen_width * screen_zoom, screen_height * screen_zoom);
127 	wl_surface_commit(emu_surf);
128 }
129 
130+static void
131+frame_callback(void *data, struct wl_callback *cb, uint32_t time)
132+{
133+	wl_callback_destroy(cb);
134+	int old = active_buf;
135+	active_buf ^= 1;
136+	memcpy((Uint8 *)shm_data + active_buf * shm_bufsize,
137+	       (Uint8 *)shm_data + old * shm_bufsize, shm_bufsize);
138+	screen_pixels = (int *)((Uint8 *)shm_data + active_buf * shm_bufsize);
139+	screen_update();
140+	emu_redraw();
141+}
142+
143 static void
144 emu_restart(unsigned int soft)
145 {
146@@ -1403,10 +1423,10 @@ static const struct wl_registry_listener reg_listener = {
147 	.global = reg_global,
148 };
149 
150+
151 static int
152 emu_init(void)
153 {
154-	static const struct itimerspec screen_tspec = {{0, 16666666}, {0, 16666666}};
155 	xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
156 	emu_dpy = wl_display_connect(NULL);
157 	if(!emu_dpy)
158@@ -1440,10 +1460,6 @@ emu_init(void)
159 		wl_surface_commit(emu_surf);
160 	}
161 	wl_display_roundtrip(emu_dpy);
162-	emu_timer = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
163-	if(emu_timer < 0)
164-		return !fprintf(stderr, "timerfd_create: failed\n");
165-	timerfd_settime(emu_timer, 0, &screen_tspec, NULL);
166 	return 1;
167 }
168 
169@@ -1451,25 +1467,20 @@ static void
170 emu_run(void)
171 {
172 	int has_input, stdin_active = 1;
173-	char expirations[8], coninp[CONINBUFSIZE];
174-	struct pollfd fds[3];
175+	char coninp[CONINBUFSIZE];
176+	struct pollfd fds[2];
177 	fds[0].fd = wl_display_get_fd(emu_dpy), fds[0].events = POLLIN;
178-	fds[1].fd = emu_timer, fds[1].events = POLLIN;
179-	fds[2].fd = STDIN_FILENO, fds[2].events = POLLIN | POLLHUP;
180+	fds[1].fd = STDIN_FILENO, fds[1].events = POLLIN | POLLHUP;
181 	while(!dev[0x0f]) {
182 		wl_display_dispatch_pending(emu_dpy);
183 		wl_display_flush(emu_dpy);
184 		/* only poll stdin while it's still active */
185-		if(poll(fds, stdin_active ? 3 : 2, -1) <= 0)
186+		if(poll(fds, stdin_active ? 2 : 1, -1) <= 0)
187 			continue;
188 		if(fds[0].revents & POLLIN)
189 			wl_display_dispatch(emu_dpy);
190-		if(fds[1].revents & POLLIN) {
191-			read(emu_timer, expirations, sizeof expirations);
192-			screen_update();
193-		}
194-		has_input = stdin_active && (fds[2].revents & POLLIN);
195-		if(has_input || (stdin_active && (fds[2].revents & POLLHUP))) {
196+		has_input = stdin_active && (fds[1].revents & POLLIN);
197+		if(has_input || (stdin_active && (fds[1].revents & POLLHUP))) {
198 			int i, n = read(STDIN_FILENO, coninp, CONINBUFSIZE - 1);
199 			if(n > 0) {
200 				for(i = 0; i < n; i++)
201@@ -1481,10 +1492,10 @@ emu_run(void)
202 		}
203 		datetime_busy = 0;
204 	}
205-	if(emu_timer >= 0)
206-		close(emu_timer);
207-	if(emu_buf)
208-		wl_buffer_destroy(emu_buf);
209+	if(emu_bufs[0])
210+		wl_buffer_destroy(emu_bufs[0]);
211+	if(emu_bufs[1])
212+		wl_buffer_destroy(emu_bufs[1]);
213 	if(emu_top)
214 		xdg_toplevel_destroy(emu_top);
215 	if(emu_xdgsurf)
216@@ -1535,6 +1546,7 @@ main(int argc, char **argv)
217 		if(!emu_init())
218 			return !fprintf(stdout, "Could not initialize %s.\n", argv[0]);
219 		screen_update();
220+		emu_redraw();
221 		emu_run();
222 	}
223 	return dev[0x0f] & 0x7f;