shithub: npe

ref: 979ae53cfee913c2d303ab0f95aaa65dace1c7b5
dir: /libnpe_sdl3/pixels.c/

View raw version
#include "_sdl.h"

int
chan2mask(Uint32 chan, int *bpp, Uint32 *rm, Uint32 *gm, Uint32 *bm, Uint32 *am)
{
	switch(chan){
	case ARGB32:
		*am = 0xFF000000;
		*rm = 0x00FF0000;
		*gm = 0x0000FF00;
		*bm = 0x000000FF;
		*bpp = 32;
		break;
	case XRGB32:
		*am = 0x00000000;
		*rm = 0x00FF0000;
		*gm = 0x0000FF00;
		*bm = 0x000000FF;
		*bpp = 32;
		break;
	case ABGR32:
		*am = 0xFF000000;
		*rm = 0x000000FF;
		*gm = 0x0000FF00;
		*bm = 0x00FF0000;
		*bpp = 32;
	case XBGR32:
		*am = 0x00000000;
		*rm = 0x000000FF;
		*gm = 0x0000FF00;
		*bm = 0x00FF0000;
		*bpp = 32;
		break;
	case RGB24:
		*am = 0x00000000;
		*rm = 0x00FF0000;
		*gm = 0x0000FF00;
		*bm = 0x000000FF;
		*bpp = 24;
		break;
	case BGR24:
		*am = 0x00000000;
		*rm = 0x000000FF;
		*gm = 0x0000FF00;
		*bm = 0x00FF0000;
		*bpp = 24;
		break;
	case CMAP8:
		*am = *rm = *gm = *bm = 0x00000000;
		*bpp = 8;
		break;
	default:
		assert(0);
	}
	return 0;
}

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 ABGR32;
		}
	}
	assert(0);
	return 0;
}

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

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

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

SDL_bool
SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 *Rmask, Uint32 *Gmask, Uint32 *Bmask, Uint32 *Amask)
{
	ulong c;

	if(bpp == nil || Rmask == nil || Gmask == nil || Bmask == nil || Amask == nil)
		return SDL_FALSE;
	c = pixel2chan(format);
	chan2mask(c, bpp, Rmask, Gmask, Bmask, Amask);
	return SDL_TRUE;
}

Uint32
SDL_MapRGB(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:
		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;
	}
}

void
npe_sdl_kill_draw(void)
{
}

int
npe_sdl_init_draw(void)
{
	int bpp;

	if(screen != nil)
		return 0;
	if(memimageinit() < 0 || initdraw(nil, nil, argv0) < 0)
		return -1;
	draw(screen, screen->r, display->black, nil, ZP);
	if(flushimage(display, 1) < 0)
		fprint(2, "npe_sdl_init_draw: %r\n");
	npe_sdl.physw = Dx(screen->r);
	npe_sdl.physh = Dy(screen->r);
	npe_sdl.scale = 1;
	if(npe_sdl_init_tex() < 0)
		return -1;
	if(chan2mask(screen->chan, &bpp, &npe_sdl.defmask.r, &npe_sdl.defmask.g, &npe_sdl.defmask.b, &npe_sdl.defmask.a) < 0){
		werrstr("unsupported screen channel");
		return -1;
	}
	return 0;
}