ref: b699be1156cb41be910dadb3c8a6df0bea12bf67
parent: d85902512f9a5208b21a39ea7d861c236d701ca1
author: Jacob Moody <moody@posixcafe.org>
date: Wed Aug 30 20:20:38 EDT 2023
sdl2: refactor image channel code, more palette function coverage
--- a/include/npe/SDL2/SDL.h
+++ b/include/npe/SDL2/SDL.h
@@ -46,7 +46,18 @@
#define SDL_zero(x) do{ memset(&(x), 0, sizeof(x)); }while(0)
#define SDL_memset memset
+#define SDL_malloc malloc
#define SDL_realloc realloc
+#define SDL_calloc calloc
+#define SDL_memcpy memcpy
+#define SDL_memmove memmove
+#define SDL_memcmp memcmp
+#define SDL_printf printf
+#define SDL_snprintf snprintf
+#define SDL_strlen strlen
+#define SDL_strlcpy strlcpy
+#define SDL_strstr strstr
+#define SDL_strncmp strncmp
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_scancode.h>
@@ -81,6 +92,7 @@
void SDL_RaiseWindow(SDL_Window *window);
int SDL_UpdateTexture(SDL_Texture *texture, SDL_Rect *rect, void *pixels, int pitch);
int SDL_RenderClear(SDL_Renderer *renderer);
+int SDL_RenderFillRect(SDL_Renderer *r, SDL_Rect *rect);
int SDL_GetWindowDisplayIndex(SDL_Window *window);
void SDL_FreeSurface(SDL_Surface *surface);
Uint32 SDL_GetGlobalMouseState(int *x, int *y);
@@ -92,6 +104,7 @@
SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int w, int h, int bpp, Uint32 fmt);
SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 rm, Uint32 gm, Uint32 bm, Uint32 am);
SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int w, int h, int bpp, int pitch, Uint32 rm, Uint32 gm, Uint32 bm, Uint32 am);
+void SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat *format, Uint8 *r, Uint8 *g, Uint8 *b);
Uint32 SDL_MapRGB(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b);
int SDL_SetColorKey(SDL_Surface *surface, int flag, Uint32 key);
int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag);
@@ -121,6 +134,7 @@
void SDL_DestroyTexture(SDL_Texture *texture);
void SDL_DestroyRenderer(SDL_Renderer *renderer);
void SDL_DestroyWindow(SDL_Window *window);
+int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect *rect);
int SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode);
void SDL_SetWindowTitle(SDL_Window *window, char *title);
int SDL_SetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode blendMode);
@@ -127,6 +141,7 @@
SDL_bool SDL_SetHint(char *name, char *value);
SDL_Window *SDL_CreateWindow(char *title, int x, int y, int w, int h, Uint32 flags);
SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags);
+int SDL_CreateWindowAndRenderer(int width, int height, Uint32 window_flags, SDL_Window **window, SDL_Renderer **renderer);
int SDL_SetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode);
char *SDL_GetCurrentVideoDriver(void);
SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h);
@@ -133,6 +148,7 @@
void SDL_EnableScreenSaver(void);
Uint32 SDL_GetTicks(void);
int SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h);
+void SDL_RenderGetViewport(SDL_Renderer *rebderer, SDL_Rect *rect);
int SDL_SaveBMP(SDL_Surface *s, const char *file);
void SDL_ClearError(void);
int SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 alpha);
@@ -156,7 +172,9 @@
#define SDL_mutexV(x) SDL_UnlockMutex(x)
#define SDL_mutexP(x) SDL_LockMutex(x)
int SDL_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color);
+SDL_Palette *SDL_AllocPalette(int ncolors);
int SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Color *colors, int firstcolor, int ncolors);
+int SDL_SetSurfacePalette(SDL_Surface *s, SDL_Palette *palette);
int SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);
int SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect);
int SDL_LockTexture(SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch);
@@ -197,7 +215,10 @@
SDL_PIXELFORMAT_INDEX8 = 0x13000801,
SDL_PIXELFORMAT_RGB24 = 0x17101803,
SDL_PIXELFORMAT_ABGR8888 = 0x16762004,
+ SDL_PIXELFORMAT_XBGR8888 = 0x16561804,
+ SDL_PIXELFORMAT_BGR24 = 0x17401803,
SDL_PIXELFORMAT_RGB888 = SDL_PIXELFORMAT_XRGB8888,
+ SDL_PIXELFORMAT_BGR888 = SDL_PIXELFORMAT_XBGR8888,
/* shit no one cares about */
SDL_TEXTUREACCESS_STREAMING = 0,
@@ -245,6 +266,7 @@
#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH"
#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING"
+#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC"
struct SDL_Point {
int x, y;
@@ -288,6 +310,7 @@
struct SDL_PixelFormat {
SDL_Palette *palette;
int format;
+ int BytesPerPixel;
};
struct SDL_RendererInfo {
--- a/include/npe/SDL2/SDL_events.h
+++ b/include/npe/SDL2/SDL_events.h
@@ -58,6 +58,7 @@
typedef struct SDL_Keysym SDL_Keysym;
typedef struct SDL_Event SDL_Event;
typedef int SDL_eventaction;
+typedef int (*SDL_EventFilter)(void *userdata, SDL_Event *event);
struct SDL_WindowEvent {
Uint32 type;
@@ -127,6 +128,7 @@
struct {
int x, y;
int xrel, yrel;
+ int state;
}motion;
struct {
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE+1];
@@ -145,5 +147,9 @@
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 minType, Uint32 maxType);
Uint32 SDL_GetWindowID(SDL_Window *window);
void SDL_PumpEvents(void);
+void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata);
+SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode key);
+Uint8* SDL_GetKeyboardState(int *numkeys);
+char* SDL_GetKeyName(SDL_Keycode key);
#endif
--- a/include/npe/string.h
+++ b/include/npe/string.h
@@ -5,5 +5,6 @@
char *strerror(int errnum);
int strerror_r(int errnum, char *buf, size_t buflen);
+size_t strlcpy(char *dst, char *src, size_t sz);
#endif
--- a/libnpe/mkfile
+++ b/libnpe/mkfile
@@ -62,6 +62,7 @@
strerror.$O\
strerror_r.$O\
strftime.$O\
+ strlcpy.$O\
trunc.$O\
unlink.$O\
usleep.$O\
--- /dev/null
+++ b/libnpe/strlcpy.c
@@ -1,0 +1,19 @@
+#include <string.h>
+
+size_t
+strlcpy(char *dst, char *src, size_t sz)
+{
+ char *start;
+
+ start = src;
+ if(sz == 0)
+ return strlen(start);
+
+ while(sz-- > 0 && (*dst++ = *src++) != '\0')
+ ;
+ if(dst[-1] != '\0')
+ dst[-1] = '\0';
+ while(*src++)
+ ;
+ return src - start - 1;
+}
--- a/libnpe_sdl2/_sdl.h
+++ b/libnpe_sdl2/_sdl.h
@@ -1,6 +1,7 @@
#include <SDL2/SDL.h>
#include <sys/stat.h>
#include <stdint.h>
+#include <string.h>
#include <tos.h>
#include <thread.h>
#include <draw.h>
--- a/libnpe_sdl2/events.c
+++ b/libnpe_sdl2/events.c
@@ -26,7 +26,6 @@
[Numchan] = { nil, nil, CHANNOBLK },
};
-static int rune2scancode(Rune r);
static void kbdproc(void *);
static void mouseproc(void *);
@@ -91,7 +90,22 @@
return quitreq;
}
+struct {
+ SDL_EventFilter f;
+ void *aux;
+} filter = {
+ nil,
+ nil,
+};
+
void
+SDL_SetEventFilter(SDL_EventFilter f, void *userdata)
+{
+ filter.f = f;
+ filter.aux = userdata;
+}
+
+void
SDL_PumpEvents(void)
{
/* FIXME does it matter? */
@@ -116,20 +130,20 @@
break;
e->type = SDL_TEXTINPUT;
e->text.text[runetochar(e->text.text, &rune)] = 0;
- return 1;
+ goto Filter;
}else if((npe_sdl.hints & Altf4noclose) == 0 && (kmod & KMOD_LALT) != 0 && rune == (KF|4)){
e->type = SDL_QUIT;
quitreq = 1;
- return 1;
+ goto Filter;
}else{
e->type = (t == Rup) ? SDL_KEYUP : SDL_KEYDOWN;
e->key.repeat = t == Rrepeat;
- e->key.keysym.scancode = rune2scancode(rune);
+ e->key.keysym.scancode = SDL_GetScancodeFromKey(rune);
if(rune == '\n')
rune = SDLK_RETURN;
e->key.keysym.sym = rune;
e->key.state = e->type;
- return 1;
+ goto Filter;
}
break;
@@ -153,7 +167,8 @@
npe_sdl.mredraw = 1;
if(npe_sdl.m.buttons == npe_sdl.om.buttons){
e->type = SDL_MOUSEMOTION;
- return 1;
+ e->motion.state = npe_sdl.m.buttons;
+ goto Filter;
}
}
if(npe_sdl.m.buttons == npe_sdl.om.buttons)
@@ -163,25 +178,25 @@
e->type = down ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
e->button.button = SDL_BUTTON_LEFT;
npe_sdl.om.buttons = (npe_sdl.om.buttons & ~1) | (npe_sdl.m.buttons & 1);
- return 1;
+ goto Filter;
}
if((down = (npe_sdl.m.buttons & 2)) != (npe_sdl.om.buttons & 2)){ /* middle */
e->type = down ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
e->button.button = SDL_BUTTON_MIDDLE;
npe_sdl.om.buttons = (npe_sdl.om.buttons & ~2) | (npe_sdl.m.buttons & 2);
- return 1;
+ goto Filter;
}
if((down = (npe_sdl.m.buttons & 4)) != (npe_sdl.om.buttons & 4)){ /* right */
e->type = down ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
e->button.button = SDL_BUTTON_RIGHT;
npe_sdl.om.buttons = (npe_sdl.om.buttons & ~4) | (npe_sdl.m.buttons & 4);
- return 1;
+ goto Filter;
}
if(npe_sdl.m.buttons & (8|16)){
e->type = SDL_MOUSEWHEEL;
e->wheel.x = 0;
e->wheel.y = (npe_sdl.m.buttons & 8) ? 1 : -1;
- return 1;
+ goto Filter;
}
break;
@@ -193,10 +208,15 @@
e->type = SDL_WINDOWEVENT;
e->window.event = SDL_WINDOWEVENT_EXPOSED;
e->window.windowID = 1; //TODO more then one?
- return 1;
+ goto Filter;
}
return 0;
+
+Filter:
+ if(filter.f != nil && filter.f(filter.aux, e) == 0)
+ return 0;
+ return 1;
}
int
@@ -211,8 +231,8 @@
return r;
}
-static int
-rune2scancode(Rune r)
+SDL_Scancode
+SDL_GetScancodeFromKey(SDL_Keycode r)
{
if(r >= 'a' && r <= 'z')
return r - 'a' + SDL_SCANCODE_A;
@@ -282,12 +302,29 @@
return r;
}
+static Uint8 kbdstate[SDL_NUM_SCANCODES];
+
+Uint8*
+SDL_GetKeyboardState(int *numkeys)
+{
+ if(numkeys != nil)
+ *numkeys = SDL_NUM_SCANCODES;
+ return kbdstate;
+}
+
+char*
+SDL_GetKeyName(SDL_Keycode key)
+{
+ USED(key);
+ return ""; /* FIXME */
+}
+
static void
kbdproc(void *)
{
char buf[128], buf2[128], *s;
int kfd, n, kbin, t;
- Rune r, o;
+ Rune r, scan, o;
threadsetname("kbdproc");
if((kfd = open("/dev/kbd", OREAD|OCEXEC)) < 0)
@@ -325,8 +362,12 @@
case 'k':
s = buf+1;
+ memset(kbdstate, 0, sizeof kbdstate);
while(*s){
s += chartorune(&r, s);
+ scan = SDL_GetScancodeFromKey(r);
+ if(scan < nelem(kbdstate))
+ kbdstate[scan] = 1;
if(utfrune(buf2+1, r) == nil){
t = Rdown;
if(r == Kalt){
@@ -356,8 +397,12 @@
case 'K':
s = buf2+1;
+ memset(kbdstate, 0, sizeof kbdstate);
while(*s){
s += chartorune(&r, s);
+ scan = SDL_GetScancodeFromKey(r);
+ if(scan < nelem(kbdstate))
+ kbdstate[scan] = 1;
if(utfrune(buf+1, r) == nil){
if(r == Kalt)
kmod &= ~KMOD_LALT;
--- a/libnpe_sdl2/sdl2.c
+++ b/libnpe_sdl2/sdl2.c
@@ -21,22 +21,6 @@
Point hot;
};
-static SDL_PixelFormat argb8888 = {
- .format = SDL_PIXELFORMAT_ARGB8888,
-};
-
-static SDL_PixelFormat xrgb8888 = {
- .format = SDL_PIXELFORMAT_XRGB8888,
-};
-
-static SDL_PixelFormat abgr8888 = {
- .format = SDL_PIXELFORMAT_ABGR8888,
-};
-
-static SDL_PixelFormat rgb24 = {
- .format = SDL_PIXELFORMAT_RGB24,
-};
-
static SDL_Window onewin;
static SDL_Renderer oneren;
static Memimage *back;
@@ -47,6 +31,9 @@
static int showcursor = SDL_ENABLE;
static char basepath[PATH_MAX];
static u32int renddrawcol = DBlack;
+struct {
+ Uint32 r, g, b, a;
+} defmask;
struct npe_sdl npe_sdl = {0};
@@ -92,6 +79,114 @@
USED(w); USED(flag);
}
+static int
+chan2mask(Uint32 chan, Uint32 *rm, Uint32 *gm, Uint32 *bm, Uint32 *am)
+{
+ switch(chan){
+ case ARGB32:
+ *am = 0xFF000000;
+ if(0){
+ case XRGB32:
+ *am = 0x00000000;
+ }
+ case RGB24:
+ *rm = 0x00FF0000;
+ *gm = 0x0000FF00;
+ *bm = 0x000000FF;
+ break;
+ case ABGR32:
+ *am = 0xFF000000;
+ if(0){
+ case XBGR32:
+ *am = 0x00000000;
+ }
+ case BGR24:
+ *bm = 0x00FF0000;
+ *gm = 0x0000FF00;
+ *rm = 0x000000FF;
+ break;
+ default:
+ assert(0);
+ }
+ return 0;
+}
+
+static ulong
+mask2chan(int bpp, Uint32 rm, Uint32 gm, Uint32 bm, Uint32 am)
+{
+ USED(gm, bm);
+
+ switch(bpp){
+ case 8:
+ return CMAP8;
+ case 24:
+ if(rm & 0xFF0000)
+ return RGB24;
+ else
+ return BGR24;
+ case 32:
+ if(am == 0){
+ if(rm & 0xFF0000)
+ return XRGB32;
+ else
+ return XBGR32;
+ } else {
+ if(rm & 0xFF0000)
+ return ARGB32;
+ else
+ return XBGR32;
+ }
+ }
+ assert(0);
+ return 0;
+}
+
+static Uint32
+chan2pixel(ulong chan)
+{
+ switch(chan){
+ case ARGB32:
+ return SDL_PIXELFORMAT_ARGB8888;
+ case XRGB32:
+ return SDL_PIXELFORMAT_XRGB8888;
+ case RGB24:
+ return SDL_PIXELFORMAT_RGB24;
+ case ABGR32:
+ return SDL_PIXELFORMAT_ABGR8888;
+ case XBGR32:
+ return SDL_PIXELFORMAT_XBGR8888;
+ case BGR24:
+ return SDL_PIXELFORMAT_BGR24;
+ case CMAP8:
+ return SDL_PIXELFORMAT_INDEX8;
+ }
+ assert(0);
+ return 0;
+}
+
+static ulong
+pixel2chan(Uint32 format)
+{
+ switch(format){
+ case SDL_PIXELFORMAT_ARGB8888:
+ return ARGB32;
+ case SDL_PIXELFORMAT_XRGB8888:
+ return XRGB32;
+ case SDL_PIXELFORMAT_RGB24:
+ return RGB24;
+ case SDL_PIXELFORMAT_ABGR8888:
+ return ABGR32;
+ case SDL_PIXELFORMAT_XBGR8888:
+ return XBGR32;
+ case SDL_PIXELFORMAT_BGR24:
+ return BGR24;
+ case SDL_PIXELFORMAT_INDEX8:
+ return CMAP8;
+ }
+ assert(0);
+ return 0;
+}
+
int
SDL_Init(int mask)
{
@@ -113,7 +208,10 @@
npe_sdl.scale = 1;
physw = Dx(screen->r);
physh = Dy(screen->r);
-
+ if(chan2mask(screen->chan, &defmask.r, &defmask.g, &defmask.b, &defmask.a) < 0){
+ werrstr("SDL_Init: unsupported screen channel");
+ return -1;
+ }
return 0;
err:
werrstr("SDL_Init: %r");
@@ -223,17 +321,7 @@
SDL_Texture *t;
int dformat;
- switch(format){
- case SDL_PIXELFORMAT_ARGB8888:
- dformat = ARGB32;
- break;
- case SDL_PIXELFORMAT_XRGB8888:
- dformat = XRGB32;
- break;
- case SDL_PIXELFORMAT_ABGR8888:
- dformat = ABGR32;
- break;
- default:
+ if((dformat = pixel2chan(format)) == 0){
werrstr("SDL_CreateTexture: format is not supported");
goto err;
}
@@ -342,6 +430,14 @@
}
int
+SDL_RenderFillRect(SDL_Renderer *r, SDL_Rect *rect)
+{
+ /* FIXME */
+ assert(rect == nil);
+ return SDL_RenderClear(r);
+}
+
+int
SDL_SetRenderDrawColor(SDL_Renderer *, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
renddrawcol = r<<24 | g<<16 | b<<8 | a;
@@ -368,40 +464,37 @@
}
SDL_Surface *
-SDL_CreateRGBSurface(Uint32 flags, int w, int h, int bpp, Uint32 rm, Uint32 gm, Uint32 bm, Uint32 am)
+SDL_CreateRGBSurface(Uint32, int w, int h, int bpp, Uint32 rm, Uint32 gm, Uint32 bm, Uint32 am)
{
SDL_Surface *s;
int n;
- Memimage *i;
+ ulong chan;
- USED(flags, rm, gm, bm, am); /* FIXME flags & masks */
-
+ rm = rm ? rm : defmask.r;
+ gm = gm ? gm : defmask.g;
+ bm = bm ? bm : defmask.b;
+ if((chan = mask2chan(bpp, rm, gm, bm, am)) == 0){
+ werrstr("bad bpp and/or mask");
+ return nil;
+ }
n = w*h*bpp/8;
if((s = calloc(1, sizeof(*s))) == nil){
werrstr("SDL_CreateRGBSurface: memory");
return nil;
}
- s->i = i = allocmemimage(Rect(0,0,w,h), screen->chan);
+ s->i = allocmemimage(Rect(0,0,w,h), chan == CMAP8 ? screen->chan : chan);
s->format = calloc(1, sizeof(SDL_PixelFormat));
- switch(bpp){
- case 32:
- s->format->format = SDL_PIXELFORMAT_ARGB8888;
- s->pixels = i->data->bdata;
- break;
- case 24:
- s->format->format = SDL_PIXELFORMAT_RGB24;
- s->pixels = calloc(1, n);
- break;
- case 8:
- s->format->format = SDL_PIXELFORMAT_INDEX8;
+ s->format->BytesPerPixel = bpp/8;
+ s->format->format = chan2pixel(chan);
+ if(chan == CMAP8){
+ s->i = allocmemimage(Rect(0,0,w,h), screen->chan);
s->format->palette = calloc(1, sizeof(SDL_Palette));
s->format->palette->ncolors = 256;
s->format->palette->colors = calloc(1, sizeof(SDL_Color) * 256);
s->pixels = calloc(1, n);
- break;
- default:
- werrstr("non supported bpp");
- return nil;
+ }else{
+ s->i = allocmemimage(Rect(0,0,w,h), chan);
+ s->pixels = ((Memimage*)s->i)->data->bdata;
}
s->w = w;
@@ -436,27 +529,17 @@
SDL_Surface *
SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int w, int h, int bpp, Uint32 fmt)
{
- SDL_PixelFormat *f;
SDL_Surface *s;
+ ulong chan;
+ Uint32 rm, gm, bm, am;
- if(fmt == SDL_PIXELFORMAT_ARGB8888)
- f = &argb8888;
- else if(fmt == SDL_PIXELFORMAT_XRGB8888)
- f = &xrgb8888;
- else if(fmt == SDL_PIXELFORMAT_RGB24)
- f = &rgb24;
- else if(fmt == SDL_PIXELFORMAT_ABGR8888)
- f = &abgr8888;
- else{
+ if((chan = pixel2chan(fmt)) == 0){
werrstr("SDL_CreateRGBSurfaceWithFormat: FIXME format %8ux not implemented", fmt);
return nil;
}
-
- if((s = SDL_CreateRGBSurface(flags, w, h, bpp, 0, 0, 0, 0)) == nil)
+ chan2mask(chan, &rm, &gm, &bm, &am);
+ if((s = SDL_CreateRGBSurface(flags, w, h, bpp, rm, bm, gm, am)) == nil)
return nil;
-
- s->format = f;
-
return s;
}
@@ -470,6 +553,7 @@
switch(dst->format->format){
case SDL_PIXELFORMAT_XRGB8888:
case SDL_PIXELFORMAT_ARGB8888:
+ case SDL_PIXELFORMAT_XBGR8888:
case SDL_PIXELFORMAT_ABGR8888:
p = (Uint32*)dst->pixels;
for(i = 0; i < dst->n / sizeof(*p); i++)
@@ -491,6 +575,17 @@
return 0;
}
+SDL_Palette*
+SDL_AllocPalette(int ncolors)
+{
+ SDL_Palette *p;
+
+ p = malloc(sizeof(*p));
+ p->ncolors = ncolors;
+ p->colors = mallocz(sizeof(SDL_Color)*ncolors, 1);
+ return p;
+}
+
int
SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Color *colors, int firstcolor, int ncolors)
{
@@ -502,6 +597,13 @@
return 0;
}
+int
+SDL_SetSurfacePalette(SDL_Surface *s, SDL_Palette *palette)
+{
+ s->format->palette = palette;
+ return 0;
+}
+
static void
syncpalette(SDL_Surface *s)
{
@@ -519,6 +621,32 @@
}
}
+static void
+synctopalette(SDL_Surface *s)
+{
+ SDL_Color c, *f;
+ Uint32 *from;
+ int j, k;
+ Memimage *i;
+ SDL_PixelFormat fmt;
+
+ i = s->i;
+ fmt.format = chan2pixel(screen->chan);
+ from = (void*)i->data->bdata;
+ for(j = 0; j < s->n; j++){
+ SDL_GetRGB(from[j], &fmt, &c.r, &c.g, &c.b);
+ for(k = 0; k < s->format->palette->ncolors; k++){
+ f = s->format->palette->colors + k;
+ if(c.r == f->r && c.g == f->g && c.b == f->b)
+ break;
+ }
+ if(k == s->format->palette->ncolors)
+ s->pixels[j] = 0; /* FIXME */
+ else
+ s->pixels[j] = k;
+ }
+}
+
int
SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
{
@@ -530,9 +658,10 @@
if(src->format->format == SDL_PIXELFORMAT_INDEX8)
syncpalette(src);
- /* FIXME */
- assert(dst->format->format != SDL_PIXELFORMAT_INDEX8);
memimagedraw(dst->i, r2, src->i, ZP, nil, ZP, S);
+
+ if(dst->format->format == SDL_PIXELFORMAT_INDEX8)
+ synctopalette(dst);
return 0;
}
@@ -615,10 +744,63 @@
free(surface);
}
+void
+SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r, Uint8 *g, Uint8 *b)
+{
+ SDL_Color *c;
+
+ switch(fmt->format){
+ case SDL_PIXELFORMAT_ARGB8888:
+ case SDL_PIXELFORMAT_XRGB8888:
+ case SDL_PIXELFORMAT_RGB24:
+ *r = pixel>>16;
+ *g = pixel>>8;
+ *b = pixel;
+ break;
+ case SDL_PIXELFORMAT_ABGR8888:
+ case SDL_PIXELFORMAT_XBGR8888:
+ case SDL_PIXELFORMAT_BGR24:
+ *b = pixel>>16;
+ *g = pixel>>8;
+ *r = pixel;
+ break;
+ case SDL_PIXELFORMAT_INDEX8:
+ assert(fmt->palette);
+ assert(pixel < fmt->palette->ncolors);
+ c = fmt->palette->colors + pixel;
+ *r = c->r;
+ *g = c->g;
+ *b = c->b;
+ break;
+ default:
+ assert(0);
+ }
+}
+
Uint32
-SDL_MapRGB(SDL_PixelFormat *, Uint8 r, Uint8 g, Uint8 b)
+SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b)
{
- return r<<24 | g<<16 | b<<8 | 0xff;
+ SDL_Color *c;
+
+ switch(fmt->format){
+ case SDL_PIXELFORMAT_ARGB8888:
+ case SDL_PIXELFORMAT_XRGB8888:
+ case SDL_PIXELFORMAT_RGB24:
+ return 0xff<<24 | r<<16 | g<<8 | b;
+ case SDL_PIXELFORMAT_ABGR8888:
+ case SDL_PIXELFORMAT_XBGR8888:
+ case SDL_PIXELFORMAT_BGR24:
+ return 0xff<<24 | b<<16 | g<<8 | r;
+ case SDL_PIXELFORMAT_INDEX8:
+ assert(fmt->palette);
+ for(c = fmt->palette->colors; c < fmt->palette->colors + fmt->palette->ncolors; c++){
+ if(c->r == r && c->g == g && c->b == b)
+ return c - fmt->palette->colors;
+ }
+ default:
+ assert(0);
+ return 0;
+ }
}
int
@@ -1028,6 +1210,14 @@
}
void
+SDL_RenderGetViewport(SDL_Renderer *r, SDL_Rect *rect)
+{
+ rect->x = rect->y = 0;
+ rect->w = r->logiw;
+ rect->h = r->logih;
+}
+
+void
SDL_SetWindowSize(SDL_Window *, int w, int h)
{
int f, n;
@@ -1095,6 +1285,22 @@
}
int
+SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect *r)
+{
+ if(displayIndex != 0)
+ return -1;
+
+ if(r == nil)
+ return 0;
+
+ r->x = display->image->r.min.x;
+ r->y = display->image->r.min.y;
+ r->w = Dx(display->image->r);
+ r->h = Dy(display->image->r);
+ return 0;
+}
+
+int
SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode)
{
if(displayIndex != 0)
@@ -1203,6 +1409,15 @@
}
int
+SDL_CreateWindowAndRenderer(int w, int h, Uint32, SDL_Window **win, SDL_Renderer **rend)
+{
+ SDL_SetWindowSize(&onewin, w, h);
+ *win = &onewin;
+ *rend = &oneren;
+ return 0;
+}
+
+int
SDL_SetRenderDrawBlendMode(SDL_Renderer *, SDL_BlendMode blendMode)
{
if(blendMode != SDL_BLENDMODE_NONE){
@@ -1533,7 +1748,7 @@
{
SDL_mutex *m;
- m = mallocz(sizeof *m, 1);
+ m = mallocz(sizeof(*m), 1);
return m;
}