shithub: npe

Download patch

ref: 83f387e7da28800d823cc5d9590f57f11d3e57d3
parent: cbf06cb5d57dcf1c8fbe27090b9002479c47b92c
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sun May 30 17:01:38 EDT 2021

sdl2: use ARGB32, support SDL_BLENDMODE_BLEND. it IS slower, but stuff works as expected

--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -10,7 +10,8 @@
 };
 
 struct SDL_Texture {
-	Memimage;
+	Memimage *m;
+	SDL_BlendMode blend;
 };
 
 struct SDL_PixelFormat {
@@ -186,9 +187,13 @@
 		werrstr("SDL_CreateTexture: only SDL_PIXELFORMAT_ARGB8888 is supported");
 		goto err;
 	}
-	if((t = (SDL_Texture*)allocmemimage(Rect(0, 0, w, h), XRGB32)) == nil) /* FIXME ARGB32? */
+	if((t = malloc(sizeof(*t))) == nil)
 		goto err;
-	memfillcolor(t, DTransparent);
+	if((t->m = allocmemimage(Rect(0, 0, w, h), ARGB32)) == nil){
+		free(t);
+		goto err;
+	}
+	memfillcolor(t->m, DBlack);
 
 	return t;
 err:
@@ -217,13 +222,25 @@
 SDL_UpdateTexture(SDL_Texture *t, SDL_Rect *re, void *pixels, int pitch)
 {
 	Rectangle r;
+	u8int *pix;
+	int y, my;
 
-	r = re ? Rect(re->x, re->y, re->x+re->w, re->y+re->h) : t->r;
-	/* FIXME non-ARGB8888 */
-	/* FIXME pitch */ USED(pitch);
-	if(loadmemimage(t, r, pixels, Dx(r)*Dy(r)*4) < 0){
-		werrstr("SDL_UpdateTexture: %r");
-		return -1;
+	r = re ? Rect(re->x, re->y, re->x+re->w, re->y+re->h) : t->m->r;
+	pix = pixels;
+	if(pitch == Dx(r)){
+		if(loadmemimage(t->m, r, pix, Dx(r)*Dy(r)*4) < 0){
+			werrstr("SDL_UpdateTexture: %r");
+			return -1;
+		}
+	}else{
+		my = Dy(r);
+		for(y = 0; y < my; y++, pix += pitch, r.min.y += 1){
+			r.max.y = r.min.y + 1;
+			if(loadmemimage(t->m, r, pix, Dx(r)*4) < 0){
+				werrstr("SDL_UpdateTexture: %r");
+				return -1;
+			}
+		}
 	}
 
 	return 0;
@@ -526,6 +543,15 @@
 	npe_nsleep((uvlong)ms*1000000ULL);
 }
 
+static int
+duff(SDL_BlendMode mode)
+{
+	if(mode == SDL_BLENDMODE_BLEND)
+		return SoverD;
+
+	return S;
+}
+
 int
 SDL_RenderCopy(SDL_Renderer *rend, SDL_Texture *t, SDL_Rect *sre, SDL_Rect *dre)
 {
@@ -540,21 +566,21 @@
 		logih = physh;
 	}
 
+	sr = t->m->r;
 	if(sre != nil){
 		sr.min = Pt(sre->x, sre->y);
 		sr.max = addpt(sr.min, Pt(sre->w, sre->h));
-	}else
-		sr = t->r;
+	}
 
+	dr = Rect(0, 0, logiw, logih);
 	if(dre != nil){
 		dr.min = Pt(dre->x, dre->y);
 		dr.max = addpt(dr.min, Pt(dre->w, dre->h));
-	}else /* stretch */
-		dr = Rect(0, 0, logiw, logih);
+	}
 
 	if(back == nil || Dx(back->r) != logiw || Dy(back->r) != logih){
 		freememimage(back);
-		back = allocmemimage(Rect(0, 0, logiw, logih), XRGB32);
+		back = allocmemimage(Rect(0, 0, logiw, logih), ARGB32);
 		if(back == nil){
 			werrstr("SDL_RenderCopy: %r");
 			return -1;
@@ -564,9 +590,9 @@
 	}
 
 	if(dre == nil && (Dx(sr) != logiw || Dy(sr) != logih))
-		npe_sdl_scale((u32int*)byteaddr(t, ZP), Dx(sr), Dy(sr), (u32int*)byteaddr(back, ZP), logiw, logih);
+		npe_sdl_scale((u32int*)byteaddr(t->m, ZP), Dx(sr), Dy(sr), (u32int*)byteaddr(back, ZP), logiw, logih);
 	else
-		memimagedraw(back, dr, t, sr.min, nil, ZP, S);
+		memimagedraw(back, dr, t->m, sr.min, nil, ZP, duff(t->blend));
 
 	return 0;
 }
@@ -760,16 +786,19 @@
 void
 SDL_DestroyTexture(SDL_Texture *t)
 {
-	freememimage(t);
+	freememimage(t->m);
+	free(t);
 }
 
 int
-SDL_SetTextureBlendMode(SDL_Texture *, SDL_BlendMode blendMode)
+SDL_SetTextureBlendMode(SDL_Texture *t, SDL_BlendMode blendMode)
 {
-	if(blendMode != SDL_BLENDMODE_NONE){
-		werrstr("SDL_SetTextureBlendMode: only SDL_BLENDMODE_NONE is supported");
+	if(blendMode != SDL_BLENDMODE_NONE && blendMode != SDL_BLENDMODE_BLEND){
+		werrstr("SDL_SetTextureBlendMode: unsupported blend mode %d", blendMode);
 		return -1;
 	}
+
+	t->blend = blendMode;
 
 	return 0;
 }