shithub: npe

Download patch

ref: db5ef81d558feebfdbf009e3acf087f649403c6d
parent: de199b06f13d2bbde2b4c95cc6de98a8ca483a08
author: Jacob Moody <moody@posixcafe.org>
date: Mon Feb 6 23:13:13 EST 2023

get duke3d working

--- a/include/npe/SDL2/SDL.h
+++ b/include/npe/SDL2/SDL.h
@@ -188,6 +188,7 @@
 
 	SDL_PIXELFORMAT_ARGB8888 = 0x30128888,
 	SDL_PIXELFORMAT_XRGB8888 = 0x16161804,
+	SDL_PIXELFORMAT_INDEX8 = 1,
 	SDL_PIXELFORMAT_RGB24 = 0x17101803,
 	SDL_PIXELFORMAT_RGB888 = SDL_PIXELFORMAT_XRGB8888,
 
@@ -251,6 +252,7 @@
 	int keyset;
 	int w, h;
 	int pitch;
+	int n;
 	uchar pixels[];
 };
 
--- a/libnpe_sdl2/events.c
+++ b/libnpe_sdl2/events.c
@@ -127,6 +127,8 @@
 		break;
 
 	case Cmouse:
+		if(screen == nil)
+			break;
 		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;
--- a/libnpe_sdl2/rwops.c
+++ b/libnpe_sdl2/rwops.c
@@ -1,8 +1,23 @@
 #include "_sdl.h"
 #include <bio.h>
 
+typedef struct {
+	uchar *memdata;
+	int memn;
+	int mempos;
+} Membuf;
+
+static vlong memsize(struct SDL_RWops *);
+static vlong memseek(struct SDL_RWops *, vlong, int);
+static size_t memread(struct SDL_RWops *, void *, size_t, size_t);
+static size_t memwrite(struct SDL_RWops *, const void *, size_t, size_t);
+static int memclose(struct SDL_RWops *);
+
 struct npe_sdl_rwops {
-	Biobuf;
+	union {
+		Biobuf;
+		Membuf;
+	};
 };
 
 static vlong bsize(struct SDL_RWops *);
@@ -57,7 +72,25 @@
 SDL_RWops*
 SDL_RWFromMem(void *mem, int size)
 {
-	return nil;
+	SDL_RWops *o;
+	Membuf *b;
+
+	o = calloc(1, sizeof(*o)+sizeof(npe_sdl_rwops));
+	if(o == nil)
+		return nil;
+	o->p = (void*)(o+1);
+	b = (void*)o->p;
+	b->memdata = mem;
+	b->memn = size;
+	b->mempos = 0;
+
+
+	o->size = memsize;
+	o->seek = memseek;
+	o->read = memread;
+	o->write = memwrite;
+	o->close = memclose;
+	return o;
 }
 
 size_t
@@ -159,4 +192,87 @@
 bclose(struct SDL_RWops *o)
 {
 	return Bterm(o->p);
+}
+
+static vlong
+memseek(struct SDL_RWops *o, vlong off, int whence)
+{
+	Membuf *b;
+
+	b = (Membuf*)o->p;
+	switch(whence){
+	case 0:
+		b->mempos = off;
+		break;
+	case 1:
+		b->mempos += off;
+		break;
+	case 2:
+		b->mempos = b->memn - 1;
+		b->mempos -= off;
+		break;
+	}
+	if(b->mempos < 0)
+		b->mempos = 0;
+
+	return b->mempos;
+}
+
+static size_t
+memread(struct SDL_RWops *o, void *b, size_t sz, size_t n)
+{
+	Membuf *buf;
+	uchar *p, *dot;
+	uchar *end;
+	size_t i;
+	vlong x;
+
+	buf = (Membuf*)o->p;
+	end = buf->memdata + buf->memn;
+	for(i = 0, p = b; i < n; i++, p += sz){
+		dot = buf->memdata + buf->mempos;
+		if(dot + sz >= end){
+			memmove(p, dot, end - dot);
+			buf->mempos = buf->memn;
+			dot = end;
+		}
+		if(dot == end)
+			return i;
+
+		assert(dot < end);
+		memmove(p, dot, sz);
+		buf->mempos += sz;
+	}
+
+	return i;
+}
+
+static size_t
+memwrite(struct SDL_RWops *o, const void *b, size_t sz, size_t n)
+{
+	Membuf *buf;
+	const uchar *p;
+	size_t i;
+
+	buf = (Membuf*)o->p;
+	for(i = 0, p = b; i < n; i++, p += sz){
+		memmove(buf->mempos + buf->memdata, p, sz);
+		buf->mempos += sz;
+	}
+	return i;
+}
+
+static vlong
+memsize(struct SDL_RWops *o)
+{
+	Membuf *b;
+	b = (Membuf*)o->p;
+
+	return b->memn;
+}
+
+static int
+memclose(struct SDL_RWops *o)
+{
+	return 0;
 }
--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -334,7 +334,22 @@
 		werrstr("SDL_CreateRGBSurface: memory");
 		return nil;
 	}
-	s->format = &argb8888;
+	s->format = calloc(1, sizeof(SDL_PixelFormat));
+	switch(bpp){
+	case 32:
+		s->format->format = SDL_PIXELFORMAT_ARGB8888;
+		break;
+	case 8:
+		s->format->format = SDL_PIXELFORMAT_INDEX8;
+		s->format->palette = calloc(1, sizeof(SDL_Palette));
+		s->format->palette->ncolors = 256;
+		s->format->palette->colors = calloc(1, sizeof(SDL_Color) * 256);
+		break;
+	default:
+		werrstr("non supported bpp");
+		return nil;
+	}
+	
 	s->w = w;
 	s->h = h;
 	s->pitch = w*bpp/8;
@@ -342,6 +357,7 @@
 	s->clip_rect.y = 0;
 	s->clip_rect.w = w;
 	s->clip_rect.h = h;
+	s->n = n;
 
 	return s;
 }
@@ -389,30 +405,106 @@
 int
 SDL_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color)
 {
-	USED(dst);
+	Uint32 *p;
+	int i;
 	USED(rect);
-	USED(color);
-	return -1;
+
+	switch(dst->format->format){
+	case SDL_PIXELFORMAT_XRGB8888:
+	case SDL_PIXELFORMAT_ARGB8888:
+		p = (Uint32*)dst->pixels;
+		for(i = 0; i < dst->n / sizeof(*p); i++)
+			p[i] = color;
+		break;
+	case SDL_PIXELFORMAT_INDEX8:
+		for(i = 0; i < dst->n; i++)
+			dst->pixels[i] = color;
+		break;
+	}
+
+	return 0;
 }
 
 int
 SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Color *colors, int firstcolor, int ncolors)
 {
-	USED(palette);
-	USED(colors);
-	USED(firstcolor);
-	USED(ncolors);
-	return -1;
+	int i;
+
+	assert(palette->ncolors >= firstcolor + ncolors);
+	for(i = firstcolor; i < firstcolor + ncolors; i++)
+		palette->colors[i] = colors[i - firstcolor];
+	return 0;
 }
 
 int
 SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
 {
-	USED(src);
-	USED(srcrect);
-	USED(dst);
-	USED(dstrect);
-	return -1;
+	Rectangle r, r2;
+	Memimage *i, *i2;
+	SDL_Color *c;
+	Uint8 *buf, *to, *buf2;
+	int j;
+
+	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:
+		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);
+		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;
+		}
+		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];
+			*to++ = c->b;
+			*to++ = c->g;
+			*to++ = c->r;
+			*to++ = c->a;
+		}
+		loadmemimage(i2, r2, buf2, dst->n * 4);
+		break;
+	}
+
+	memimagedraw(i2, r2, 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;
 }
 
 void
@@ -725,6 +817,8 @@
 			replclipr(screen, 0, clipr);
 		}
 	}
+	if(screen == nil)
+		return;
 	draw(screen, screen->r, front, nil, ZP);
 	if(cursor != nil && showcursor)
 		draw(screen, r, cursor->i, cursor->m, ZP);
@@ -1226,7 +1320,7 @@
 SDL_SetRelativeMouseMode(SDL_bool enabled)
 {
 	/* FIXME implement mouse grab */
-	return -1;
+	return 0;
 }
 
 void