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