shithub: npe

Download patch

ref: 25d017440f96bd59227c56a902dc7c0bb3e23c4f
parent: 35e2b5b8391c23f01d41a181bc9d6d9dddd5425f
author: Jacob Moody <moody@posixcafe.org>
date: Sun Feb 12 15:32:15 EST 2023

implement SDL_SoftStretch

--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -446,32 +446,33 @@
 	return 0;
 }
 
-int
-SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
+static void
+syncpalette(SDL_Surface *s)
 {
-	Rectangle r, r2;
 	SDL_Color *c;
 	Uint8 *to;
 	int j;
 
+	to = ((Memimage*)s->i)->data->bdata;
+	for(j = 0; j < s->n; j++){
+		c = s->format->palette->colors + s->pixels[j];
+		*to++ = c->b;
+		*to++ = c->g;
+		*to++ = c->r;
+		*to++ = c->a;
+	}
+}
+
+int
+SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
+{
+	Rectangle r, r2;
+
 	r = srcrect == nil ? Rect(0, 0, src->w, src->h) : Rect(srcrect->x, srcrect->y, srcrect->x+srcrect->w, srcrect->y+srcrect->h);
 	r2 = dstrect == nil ? Rect(0, 0, dst->w, dst->h) : Rect(dstrect->x, dstrect->y, dstrect->x+dstrect->w, dstrect->y+dstrect->h);
 
-	switch(src->format->format){
-	case SDL_PIXELFORMAT_ARGB8888:
-	case SDL_PIXELFORMAT_XRGB8888:
-		break;
-	case SDL_PIXELFORMAT_INDEX8:
-		to = ((Memimage*)src->i)->data->bdata;
-		for(j = 0; j < src->n; j++){
-			c = src->format->palette->colors + src->pixels[j];
-			*to++ = c->b;
-			*to++ = c->g;
-			*to++ = c->r;
-			*to++ = c->a;
-		}
-		break;
-	}
+	if(src->format->format == SDL_PIXELFORMAT_INDEX8)
+		syncpalette(src);
 
 	/* FIXME */
 	assert(dst->format->format != SDL_PIXELFORMAT_INDEX8);
@@ -479,9 +480,81 @@
 	return 0;
 }
 
+int
+SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect)
+{
+	Rectangle r, r2;
+	Memimage *rowimg;
+	int w, h;
+	int scale;
+	ulong *s, *d, *e;
+	ulong *out;
+	int i, y;
+
+	r = srcrect == nil ? Rect(0, 0, src->w, src->h) : Rect(srcrect->x, srcrect->y, srcrect->x+srcrect->w, srcrect->y+srcrect->h);
+	r2 = dstrect == nil ? Rect(0, 0, dst->w, dst->h) : Rect(dstrect->x, dstrect->y, dstrect->x+dstrect->w, dstrect->y+dstrect->h);
+
+	w = Dx(r);
+	h = Dy(r);
+
+	scale = Dx(r2)/w;
+	if(scale <= 0)
+		scale = 1;
+	else if(scale > 12)
+		scale = 12;
+
+	rowimg = allocmemimage(Rect(0, 0, scale*w, 1), ((Memimage*)src->i)->chan);
+
+	assert(dst->format->format != SDL_PIXELFORMAT_INDEX8);
+	if(src->format->format == SDL_PIXELFORMAT_INDEX8)
+		syncpalette(src);
+
+	for(y = 0; y < h; y++){
+		s = wordaddr(src->i, Pt(0, y));
+		d = (ulong*)rowimg->data->bdata;
+		e = s + w;
+		for(; s < e; s++){
+			switch(scale){
+			case 12:
+				*d++ = *s;
+			case 11:
+				*d++ = *s;
+			case 10:
+				*d++ = *s;
+			case 9:
+				*d++ = *s;
+			case 8:
+				*d++ = *s;
+			case 7:
+				*d++ = *s;
+			case 6:
+				*d++ = *s;
+			case 5:
+				*d++ = *s;
+			case 4:
+				*d++ = *s;
+			case 3:
+				*d++ = *s;
+			case 2:
+				*d++ = *s;
+			case 1:
+				*d++ = *s;
+			}
+		}
+		d = (ulong*)rowimg->data->bdata;
+		for(i = 0; i < scale; i++){
+			out = wordaddr(dst->i, Pt(0, y*scale + i));
+			memcpy(out, d, scale*w*4);
+		}
+	}
+	freememimage(rowimg);
+	return 0;
+}
+
 void
 SDL_FreeSurface(SDL_Surface *surface)
 {
+	freememimage(surface->i);
 	memset(surface, 0, sizeof(surface));
 	free(surface);
 }