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