shithub: npe

Download patch

ref: aeecf799ccb7461d436e3c3a07357ca0fff73180
parent: aaad5f4c82f96f96103c545a5db4e46ef4e22d33
author: Jacob Moody <moody@posixcafe.org>
date: Wed Feb 8 02:14:16 EST 2023

loop getwindow's and don't allocate each blit

how duke3d creates the windows can cause a bug
in which the screen gets stuck nil after starting,
atleast with drawterm. It seems that usually when
getwindow fails it's due to a race, so looping
over seems to at least fix the issue as a hack.

also just give a Surface a memimage so we aren't
allocating one on each blit.

--- a/include/npe/SDL2/SDL.h
+++ b/include/npe/SDL2/SDL.h
@@ -258,7 +258,8 @@
 	int w, h;
 	int pitch;
 	int n;
-	uchar pixels[];
+	void *i;
+	uchar *pixels;
 };
 
 struct SDL_DisplayMode {
--- a/libnpe_sdl2/events.c
+++ b/libnpe_sdl2/events.c
@@ -135,6 +135,12 @@
 		if(screen == nil)
 			break;
 
+		if(eqpt(npe_sdl.m.xy, Pt(-1, -1))){
+			npe_sdl.m.xy = npe_sdl.center;
+			npe_sdl.om.xy = npe_sdl.center;
+			return 0; /* swallow */
+		}
+
 		memset(e, 0, sizeof(*e));
 		e->motion.x = (npe_sdl.m.xy.x - screen->r.min.x) * npe_sdl.scale;
 		e->motion.y = (npe_sdl.m.xy.y - screen->r.min.y) * npe_sdl.scale;
@@ -180,11 +186,8 @@
 	case Cresize:
 		memset(e, 0, sizeof(*e));
 		npe_sdl.fullredraw = 1;
-		if(getwindow(display, Refnone) < 0){
-			fprint(2, "%r\n");
-			/* FIXME do something here? */
-			//threadexitsall(nil);
-		}
+		while(getwindow(display, Refnone) != 1)
+			;
 		e->type = SDL_WINDOWEVENT;
 		e->window.event = SDL_WINDOWEVENT_EXPOSED;
 		e->window.windowID = 1; //TODO more then one?
@@ -371,9 +374,7 @@
 		if(npe_sdl.mgrab == SDL_TRUE){
 			if(!ptinrect(m.xy, npe_sdl.grabout)){
 				moveto(npe_sdl.mctl, npe_sdl.center);
-				npe_sdl.m.xy = npe_sdl.center;
-				npe_sdl.om.xy = npe_sdl.center;
-				continue; /* swallow */
+				m.xy = Pt(-1,-1);
 			}
 		}
 		send(salt[Cmouse].c, &m);
--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -332,18 +332,21 @@
 {
 	SDL_Surface *s;
 	int n;
+	Memimage *i;
 
 	USED(flags, rm, gm, bm, am); /* FIXME flags & masks */
 
 	n = w*h*bpp/8;
-	if((s = calloc(1, sizeof(*s)+n)) == nil){
+	if((s = calloc(1, sizeof(*s))) == nil){
 		werrstr("SDL_CreateRGBSurface: memory");
 		return nil;
 	}
+	s->i = i = allocmemimage(Rect(0,0,w,h), ARGB32);
 	s->format = calloc(1, sizeof(SDL_PixelFormat));
 	switch(bpp){
 	case 32:
 		s->format->format = SDL_PIXELFORMAT_ARGB8888;
+		s->pixels = i->data->bdata;
 		break;
 	case 8:
 		s->format->format = SDL_PIXELFORMAT_INDEX8;
@@ -350,6 +353,7 @@
 		s->format->palette = calloc(1, sizeof(SDL_Palette));
 		s->format->palette->ncolors = 256;
 		s->format->palette->colors = calloc(1, sizeof(SDL_Color) * 256);
+		s->pixels = calloc(1, n);
 		break;
 	default:
 		werrstr("non supported bpp");
@@ -456,16 +460,10 @@
 
 	switch(src->format->format){
 	case SDL_PIXELFORMAT_ARGB8888:
-		i = allocmemimage(r, ARGB32);
-		loadmemimage(i, r, src->pixels, src->n);
-		break;
 	case SDL_PIXELFORMAT_XRGB8888:
-		i = allocmemimage(r, XRGB32);
-		loadmemimage(i, r, src->pixels, src->n);
 		break;
 	case SDL_PIXELFORMAT_INDEX8:
-		i = allocmemimage(r, ARGB32);
-		to = buf = malloc(src->n * 4);
+		to = ((Memimage*)src->i)->data->bdata;
 		for(j = 0; j < src->n; j++){
 			c = src->format->palette->colors + src->pixels[j];
 			*to++ = c->b;
@@ -473,21 +471,14 @@
 			*to++ = c->r;
 			*to++ = c->a;
 		}
-		loadmemimage(i, r, buf, src->n * 4);
 		break;
 	}
 
 	switch(dst->format->format){
 	case SDL_PIXELFORMAT_ARGB8888:
-		i2 = allocmemimage(r2, ARGB32);
-		loadmemimage(i2, r2, dst->pixels, dst->n);
-		break;
 	case SDL_PIXELFORMAT_XRGB8888:
-		i2 = allocmemimage(r2, XRGB32);
-		loadmemimage(i2, r2, dst->pixels, dst->n);
 		break;
 	case SDL_PIXELFORMAT_INDEX8:
-		i2 = allocmemimage(r2, ARGB32);
 		to = buf2 = malloc(dst->n * 4);
 		for(j = 0; j < dst->n; j++){
 			c = dst->format->palette->colors + dst->pixels[j];
@@ -496,20 +487,12 @@
 			*to++ = c->r;
 			*to++ = c->a;
 		}
-		loadmemimage(i2, r2, buf2, dst->n * 4);
 		break;
 	}
 
-	memimagedraw(i2, r2, i, ZP, nil, ZP, S);
+	memimagedraw(dst->i, r2, src->i, ZP, nil, ZP, S);
 
 	assert(dst->format->format != SDL_PIXELFORMAT_INDEX8);
-	unloadmemimage(i2, r2, dst->pixels, dst->n);
-	freememimage(i);
-	freememimage(i2);
-	if(src->format->format == SDL_PIXELFORMAT_INDEX8)
-		free(buf);
-	if(dst->format->format == SDL_PIXELFORMAT_INDEX8)
-		free(buf2);
 	return 0;
 }
 
@@ -823,8 +806,8 @@
 			replclipr(screen, 0, clipr);
 		}
 	}
-	if(screen == nil)
-		return;
+	while(screen == nil && getwindow(display, Refnone) != 1)
+		/* drawterm window change lag */;
 	draw(screen, screen->r, front, nil, ZP);
 	if(cursor != nil && showcursor)
 		draw(screen, r, cursor->i, cursor->m, ZP);
@@ -905,7 +888,8 @@
 			n = fprint(f, "resize -dx %d -dy %d", w+Borderwidth*2, h+Borderwidth*2);
 			close(f);
 			if(n > 0){
-				getwindow(display, Refnone);
+				while(getwindow(display, Refnone) != 1)
+					;
 				npe_sdl.fullredraw = 1;
 			}
 		}
@@ -944,7 +928,8 @@
 		n = fprint(f, "move -minx %d -miny %d", x, y);
 		close(f);
 		if(n > 0){
-			getwindow(display, Refnone);
+			while(getwindow(display, Refnone) != 1)
+				;
 			npe_sdl.fullredraw = 1;
 			npe_sdl.grabout = insetrect(screen->r, Dx(screen->r)/8);
 			npe_sdl.center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
@@ -984,6 +969,8 @@
 SDL_GetDisplayMode(int displayIndex, int modeIndex, SDL_DisplayMode *mode)
 {
 	USED(modeIndex);
+	physw = 1280;
+	physh = 960;
 	return SDL_GetDesktopDisplayMode(displayIndex, mode);
 }
 
@@ -1327,13 +1314,15 @@
 int
 SDL_SetRelativeMouseMode(SDL_bool enabled)
 {
-	npe_sdl.grabout = insetrect(screen->r, Dx(screen->r)/8);
-	npe_sdl.center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
+	if(screen){
+		npe_sdl.grabout = insetrect(screen->r, Dx(screen->r)/8);
+		npe_sdl.center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
+		if(enabled)
+			SDL_ShowCursor(0);
+		else
+			SDL_ShowCursor(1);
+	}
 	npe_sdl.mgrab = enabled;
-	if(enabled)
-		SDL_ShowCursor(0);
-	else
-		SDL_ShowCursor(1);
 	return 0;
 }