Weird (but valid) depths have alpha(and non-alpha) bugs in SDL

per pixel alpha blits result in funky colors in bit depths 17 through 23, fun pseudo colors!

http://jonatkins.org/files/sdl/alphablit.c

output for depth 17:
screen: R:0x0001f000(5) G:0x00000fe0(7) B:0x0000001f(5) A:0x00000000(0) 17bpp
alpha: R:0x00ff0000(8) G:0x0000ff00(8) B:0x000000ff(8) A:0xff000000(8) 32bpp
everything looks ok…but we still get random colors on the alpha blit

output for depth 23:
./alphablit 23
screen: R:0x007f0000(7) G:0x00000000(-247) B:0x0000007f(7) A:0x00000000(0) 23bpp
alpha: R:0x00ff0000(8) G:0x0000ff00(8) B:0x000000ff(8) A:0xff000000(8) 32bpp
the screen->format->Gloss is 255. this is disturbing

the program lets you drag the alpha rectangle around with your mouse.
I suggest trying it for all depths 8-32 on any architecture you can get your hands on.
I only tried it in linux with the x11, dga, and svgalib drivers so far.–
-==-
Jon Atkins
http://jonatkins.org/

/* gcc sdl-config --cflags alphablit.c sdl-config --libs -o alphablit */
#include “stdio.h”
#include “SDL.h”

void sdlerr()
{
if(strlen(SDL_GetError()))
printf(“SDL: %s\n”,SDL_GetError());
}

int main(int argc, char **argv)
{
int done=0,y;
SDL_Surface *s,*bg,*fg;
SDL_Rect mr;

if(argc!=2)
{
	printf("%s depth\n",argv[0]);
	return 1;
}

if(SDL_Init(SDL_INIT_VIDEO)<0) return 1;
atexit(sdlerr);
atexit(SDL_Quit);

s=SDL_SetVideoMode(256,256,strtol(argv[1],0,10),0);
if(!s) return 2;
printf("screen: R:0x%08x(%d) G:0x%08x(%d) B:0x%08x(%d) A:0x%08x(%d) %dbpp\n",
		s->format->Rmask, 8-s->format->Rloss, s->format->Gmask, 8-s->format->Gloss,
		s->format->Bmask, 8-s->format->Bloss, s->format->Amask, 8-s->format->Aloss,
		s->format->BitsPerPixel);

for(y=0;y<s->h;y++)
{
	SDL_Rect r={0,0,s->w,s->h};

	Uint8 c;
	r.y=y;
	c=(Uint8)(255*y/s->h);
	SDL_FillRect(s,&r,SDL_MapRGB(s->format,c,c,c)); /*play with these colors*/
}
bg=SDL_DisplayFormat(s);
if(!bg) return 3;

{
	SDL_Surface *t;
	t=SDL_CreateRGBSurface(SDL_SRCALPHA,100,100,32,0xff,0xff00,0xff0000,0xff000000);
	if(!t) return 4;
	fg=SDL_DisplayFormatAlpha(t);
	if(!fg)
	{ sdlerr(); fg=t; }
	else
		SDL_FreeSurface(t);
	printf("alpha: R:0x%08x(%d) G:0x%08x(%d) B:0x%08x(%d) A:0x%08x(%d) %dbpp\n",
			fg->format->Rmask, 8-fg->format->Rloss, fg->format->Gmask, 8-fg->format->Gloss,
			fg->format->Bmask, 8-fg->format->Bloss, fg->format->Amask, 8-fg->format->Aloss,
			fg->format->BitsPerPixel);
}

SDL_FillRect(fg,0,SDL_MapRGBA(fg->format,0x80,0x80,0xff,0x80)); /*play with these too*/
mr.x=s->w/2-fg->w/2;
mr.y=s->h/2-fg->h/2;
SDL_BlitSurface(fg,0,s,&mr);
SDL_Flip(s);

while(!done)
{
	SDL_Event e;
	int redraw=0;
	
	while(SDL_PollEvent(&e))
		switch(e.type)
		{
			case SDL_QUIT:
				done=1;
				break;
			case SDL_KEYDOWN:
				if(e.key.keysym.sym==SDLK_ESCAPE)
					done=1;
				break;
			case SDL_MOUSEMOTION:
				if(e.motion.state)
				{
					mr.x=e.motion.x-fg->w/2;
					mr.y=e.motion.y-fg->h/2;
					redraw=1;
				}
				break;
		}
	if(redraw)
	{
		SDL_BlitSurface(bg,0,s,0);
		SDL_BlitSurface(fg,0,s,&mr);
		SDL_Flip(s);
	}
}

}