SDL_SetPalette bug with DirectX Fullscreen

Hi,

there seems to be a bug in the logical/physical palette handling. If I
start windowed it works, if I start fullscreen the colors aren’t
correct. They seem to be slightly blue- and greenish. It happens in my
Doom port PrBoom with SDL-1.1.5 and the current CVS. It works with
SDL-1.1.4

Proff–

Florian ‘Proff’ Schulze - @Florian_Schulze
Member: TeamTNT - http://www.teamtnt.com
Homepage: - http://proff.fly.to
ICQ#: - 40510245

there seems to be a bug in the logical/physical palette handling. If I
start windowed it works, if I start fullscreen the colors aren’t
correct. They seem to be slightly blue- and greenish. It happens in my
Doom port PrBoom with SDL-1.1.5 and the current CVS. It works with
SDL-1.1.4

Please find a minimal failing example and I’ll have a look at it

Mattias Engdeg?rd wrote:

there seems to be a bug in the logical/physical palette handling. If I
start windowed it works, if I start fullscreen the colors aren’t
correct. They seem to be slightly blue- and greenish. It happens in my
Doom port PrBoom with SDL-1.1.5 and the current CVS. It works with
SDL-1.1.4

Please find a minimal failing example and I’ll have a look at it

The bitmap loaded is any bitmap with 256 colors. It seems like not all
256 colors are used and the logical colors are mapped to those few
physical colors. Some pictures are affected more than others, you have
to try some.

#include <stdlib.h>
#include “SDL.h”

#ifdef __cplusplus
extern “C”
#endif
int main(int argc, char *argv[])
{
int i;
SDL_Surface *screen_surface;
SDL_Surface *temp;

if (SDL_Init(SDL_INIT_EVERYTHING)<0)
{
fprintf(stderr,“Couldn’t initialize SDL! %s\n”, SDL_GetError());
return 1;
}
atexit(SDL_Quit);

temp=SDL_LoadBMP(“f:\doom\glboom2\doom.bmp”);
if (!temp)
{
fprintf(stderr,“Loading image failed! %s\n”, SDL_GetError());
return 1;
}

screen_surface=SDL_SetVideoMode(640,480,8,SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
if (!screen_surface)
{
fprintf(stderr,“SetVideoMode 640x480x8 failed! %s\n”,
SDL_GetError());
return 1;
}

/* Set the palette, if one exists */
if ( temp->format->palette ) {
	SDL_SetColors(screen_surface, temp->format->palette->colors,
			0, temp->format->palette->ncolors);
}

/* Display the image */
SDL_BlitSurface(temp, NULL, screen_surface, NULL);
SDL_Flip(screen_surface);

/* Wait for any keyboard or mouse input */
for ( i=SDL_NOEVENT; i<SDL_NUMEVENTS; ++i ) {
	switch (i) {
	    case SDL_KEYDOWN:
	    case SDL_MOUSEBUTTONDOWN:
	    case SDL_QUIT:
		/* Valid event, keep it */
		break;
	    default:
		/* We don't want this event */
		SDL_EventState(i, SDL_IGNORE);
		break;
	}
}
SDL_WaitEvent(NULL);

return 0;
}

Proff–

Florian ‘Proff’ Schulze - @Florian_Schulze
Member: TeamTNT - http://www.teamtnt.com
Homepage: - http://proff.fly.to
ICQ#: - 40510245

Sorry, I didn’t read the subject line. I don’t have a windows machine to
test on.

Can someone who knows Windows code better than I do have a look at SetColors
in the dx5 driver?

Since I recently fiddled with SetColors() code of all video drivers it would
be nice to have their correctness verified

I have found out that DX5_SetColors is not correct and fixed it, but it
doesn’t solve the problem:

/* Set the system colormap in both fullscreen and windowed modes */
int DX5_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
int i;
int alloct_all;

/* Copy palette colors into display palette */
if ( SDL_palette != NULL ) {
	if ( (this->screen->flags&SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
		/* We can set all entries explicitly */
		for ( i=0; i< ncolors; ++i ) {
		        int j=firstcolor+i;
			SDL_colors[j].peRed = colors[i].r;
			SDL_colors[j].peGreen = colors[i].g;
			SDL_colors[j].peBlue = colors[i].b;
		}
		IDirectDrawPalette_SetEntries(SDL_palette, 0,
			firstcolor, ncolors, &SDL_colors[firstcolor]);
		alloct_all = 1;
	} else {
		/* Grab the 236 most diverse colors in the palette */
		DX5_CompressPalette(this,
		              colors, ncolors, 236);
		/* This sends an WM_PALETTECHANGED message to us */
		colorchange_expected = 1;
		IDirectDrawPalette_SetEntries(SDL_palette, 0,
						0, 256, SDL_colors);
		alloct_all = 0;
	}
}
return(alloct_all);

}

I have put a screenshot of the wrong colors on my website:
http://prboom.sourceforge.net/doom03.png

Proff–
Florian ‘Proff’ Schulze - @Florian_Schulze
Homepage: - http://proff.fly.to
PGP-Key available from - http://www.keyserver.net/en/

I have found out that DX5_SetColors is not correct and fixed it, but it
doesn’t solve the problem:

/* Set the system colormap in both fullscreen and windowed modes */
int DX5_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
int i;
int alloct_all;

    /* Copy palette colors into display palette */
    if ( SDL_palette != NULL ) {
            if ( (this->screen->flags&SDL_FULLSCREEN) ==

SDL_FULLSCREEN ) {
/* We can set all entries explicitly /
for ( i=0; i< ncolors; ++i ) {
int j=firstcolor+i;
SDL_colors[j].peRed = colors[i].r;
SDL_colors[j].peGreen = colors[i].g;
SDL_colors[j].peBlue = colors[i].b;
}
IDirectDrawPalette_SetEntries(SDL_palette, 0,
firstcolor, ncolors,
&SDL_colors[firstcolor]);
alloct_all = 1;
} else {
/
Grab the 236 most diverse colors in the
palette /
DX5_CompressPalette(this,
colors, ncolors, 236);
/
This sends an WM_PALETTECHANGED message to us
*/
colorchange_expected = 1;
IDirectDrawPalette_SetEntries(SDL_palette, 0,
0, 256,
SDL_colors);
alloct_all = 0;
}
}
return(alloct_all);
}

I have put a screenshot of the wrong colors on my website:

Proff–
Florian ‘Proff’ Schulze - @Florian_Schulze
Homepage: - http://proff.fly.to
PGP-Key available from - http://www.keyserver.net/en/