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);
}