shithub: riscv

Download patch

ref: a523ce1282d2fff6d4d052a71e3f32baa0e18a67
parent: c8b73800719e3078fe1f74c9bb703cc8f7564aad
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Sep 14 21:16:48 EDT 2023

doom: draw in a separate proc

--- a/sys/src/games/doom/i_main.c
+++ b/sys/src/games/doom/i_main.c
@@ -4,7 +4,7 @@
 #include "m_argv.h"
 #include "d_main.h"
 
-void main(int argc, char **argv)
+void threadmain(int argc, char **argv)
 {
 	myargc = argc; 
 	myargv = argv; 
--- a/sys/src/games/doom/i_video.c
+++ b/sys/src/games/doom/i_video.c
@@ -8,6 +8,7 @@
 #include <draw.h>
 #include <mouse.h>
 #include <keyboard.h>
+#include <thread.h>
 
 static int resized;
 static int mouseactive;
@@ -16,8 +17,8 @@
 static Rectangle grabout;
 static Point center;
 
-static void kbdproc(void);
-static void mouseproc(void);
+static void kbdproc(void *);
+static void mouseproc(void *);
 
 static uchar cmap[3*256];
 
@@ -24,21 +25,19 @@
 static int kbdpid = -1;
 static int mousepid = -1;
 
-static void
+static int
 catch(void *, char *msg)
 {
 	/* in case we crash, disable mouse grab */
 	if(strncmp(msg, "sys:", 4) == 0)
 		mouseactive = 0;
-	noted(NDFLT);
+	return 0;
 }
 
 void I_InitGraphics(void)
 {
-	int pid;
+	threadnotify(catch, 1);
 
-	notify(catch);
-
 	if(initdraw(nil, nil, "doom") < 0)
 		I_Error("I_InitGraphics failed");
 
@@ -47,27 +46,22 @@
 	center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
 	grabout = insetrect(screen->r, Dx(screen->r)/8);
 
-	if((pid = rfork(RFPROC|RFMEM)) == 0){
-		kbdproc();
-		exits(nil);
-	}
-	kbdpid = pid;
-
-	if((pid = rfork(RFPROC|RFMEM)) == 0){
-		mouseproc();
-		exits(nil);
-	}
-	mousepid = pid;
+	kbdpid = proccreate(kbdproc, nil, 4096);
+	mousepid = proccreate(mouseproc, nil, 4096);
 }
 
+static Channel *conv;
+
 void I_ShutdownGraphics(void)
 {
+	if(conv != nil)
+		chanclose(conv);
 	if(kbdpid != -1){
-		postnote(PNPROC, kbdpid, "shutdown");
+		postnote(PNPROC, threadpid(kbdpid), "shutdown");
 		kbdpid = -1;
 	}
 	if(mousepid != -1){
-		postnote(PNPROC, mousepid, "shutdown");
+		postnote(PNPROC, threadpid(mousepid), "shutdown");
 		mousepid = -1;
 	}
 }
@@ -86,15 +80,75 @@
 	// DELETEME?
 }
 
-void I_FinishUpdate(void)
+static int screenconvi;
+static uchar screenconv[2][SCREENWIDTH*SCREENHEIGHT];
+
+static void
+convproc(void *p)
 {
+	static uchar buf[SCREENWIDTH*3*12];
+	int i, y, scale, oldscale;
 	Image *rowimg;
 	Rectangle r;
-	int y, scale;
 	uchar *s, *e, *d, *m;
-	uchar buf[SCREENWIDTH*3*12];
 
+	oldscale = 0;
+	rowimg = nil;
+	for(;;){
+		if((s = recvp(p)) == nil)
+			break;
+		scale = Dx(screen->r)/SCREENWIDTH;
+		if(scale <= 0)
+			scale = 1;
+		else if(scale > 12)
+			scale = 12;
+
+		/* where to draw the scaled row */
+		r = rectsubpt(rectaddpt(Rect(0, 0, scale*SCREENWIDTH, scale), center),
+			Pt(scale*SCREENWIDTH/2, scale*SCREENHEIGHT/2));
+
+		/* the row image, y-axis gets scaled with repl flag */
+		if(scale != oldscale){
+			if(rowimg != nil)
+				freeimage(rowimg);
+			rowimg = allocimage(display, Rect(0, 0, scale*SCREENWIDTH, 1), RGB24, scale > 1, DNofill);
+			if(rowimg == nil)
+				sysfatal("allocimage: %r");
+			oldscale = scale;
+		}
+
+		for(y = 0; y < SCREENHEIGHT; y++){
+			d = buf;
+			e = s + SCREENWIDTH;
+			for(; s < e; s++){
+				m = &cmap[*s * 3];
+				for(i = 0; i < scale; i++, d += 3){
+					d[0] = m[2];
+					d[1] = m[1];
+					d[2] = m[0];
+				}
+			}
+			loadimage(rowimg, rowimg->r, buf, d - buf);
+			draw(screen, r, rowimg, nil, ZP);
+			r.min.y += scale;
+			r.max.y += scale;
+		}
+
+		flushimage(display, 1);
+	}
+	if(rowimg != nil)
+		freeimage(rowimg);
+	threadexits(nil);
+}
+
+void I_FinishUpdate(void)
+{
 	if(resized){
+		if(conv != nil){
+			sendp(conv, nil);
+			chanfree(conv);
+			conv = nil;
+		}
 		resized = 0;
 		if(getwindow(display, Refnone) < 0)
 			sysfatal("getwindow: %r");
@@ -106,86 +160,13 @@
 		grabout = insetrect(screen->r, Dx(screen->r)/8);
 	}
 
-	scale = Dx(screen->r)/SCREENWIDTH;
-	if(scale <= 0)
-		scale = 1;
-	else if(scale > 12)
-		scale = 12;
-
-	/* where to draw the scaled row */
-	r = rectsubpt(rectaddpt(Rect(0, 0, scale*SCREENWIDTH, scale), center),
-		Pt(scale*SCREENWIDTH/2, scale*SCREENHEIGHT/2));
-
-	/* the row image, y-axis gets scaled with repl flag */
-	rowimg = allocimage(display, Rect(0, 0, scale*SCREENWIDTH, 1), RGB24, scale > 1, DNofill);
-	if(rowimg == nil)
-		sysfatal("allocimage: %r");
-
-	s = screens[0];
-	for(y = 0; y < SCREENHEIGHT; y++){
-		d = buf;
-		e = s + SCREENWIDTH;
-		for(; s < e; s++){
-			m = &cmap[*s * 3];
-			switch(scale){
-			case 12:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 11:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 10:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 9:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 8:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 7:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 6:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 5:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 4:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 3:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 2:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			case 1:
-				*d++ = m[2];
-				*d++ = m[1];
-				*d++ = m[0];
-			}
-		}
-		loadimage(rowimg, rowimg->r, buf, d - buf);
-		draw(screen, r, rowimg, nil, ZP);
-		r.min.y += scale;
-		r.max.y += scale;
+	if(conv == nil){
+		conv = chancreate(sizeof(uchar*), 0);
+		proccreate(convproc, conv, 4096);
 	}
-	freeimage(rowimg);
-
-	flushimage(display, 1);
+	memmove(screenconv[screenconvi], screens[0], sizeof(screenconv[0]));
+	if(nbsendp(conv, screenconv[screenconvi]) > 0)
+		screenconvi = (screenconvi + 1) % nelem(screenconv);
 }
 
 void I_MouseEnable(int on)
@@ -280,7 +261,7 @@
 }
 
 static void
-kbdproc(void)
+kbdproc(void *)
 {
 	char buf[128], buf2[128], *s;
 	int kfd, n;
@@ -348,10 +329,11 @@
 		}
 		strcpy(buf2, buf);
 	}
+	threadexits(nil);
 }
 
 static void
-mouseproc(void)
+mouseproc(void *)
 {
 	int fd, n, nerr;
 	Mouse m, om;
@@ -403,5 +385,6 @@
 			break;
 		}
 	}
+	threadexits(nil);
 }