Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Finished palettized display handling.
Added support for surface palette sharing.
  • Loading branch information
slouken committed Jun 17, 2006
1 parent e05df70 commit 5d97336
Show file tree
Hide file tree
Showing 13 changed files with 458 additions and 339 deletions.
6 changes: 3 additions & 3 deletions include/SDL_compat.h
Expand Up @@ -148,9 +148,9 @@ extern DECLSPEC SDL_GrabMode SDLCALL SDL_WM_GrabInput(SDL_GrabMode mode);
extern DECLSPEC int SDLCALL SDL_SetPalette(SDL_Surface * surface, int flags,
const SDL_Color * colors,
int firstcolor, int ncolors);
extern DECLSPEC int SDLCALL SDL_SetScreenColors(SDL_Surface * screen,
const SDL_Color * colors,
int firstcolor, int ncolors);
extern DECLSPEC int SDLCALL SDL_SetColors(SDL_Surface * surface,
const SDL_Color * colors,
int firstcolor, int ncolors);
extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo * info);
extern DECLSPEC Uint8 SDLCALL SDL_GetAppState(void);
extern DECLSPEC void SDLCALL SDL_WarpMouse(Uint16 x, Uint16 y);
Expand Down
118 changes: 102 additions & 16 deletions include/SDL_pixels.h
Expand Up @@ -195,11 +195,24 @@ typedef struct SDL_Color
} SDL_Color;
#define SDL_Colour SDL_Color

typedef struct SDL_Palette
typedef struct SDL_Palette SDL_Palette;
typedef int (*SDL_PaletteChangedFunc) (void *userdata, SDL_Palette * palette);

typedef struct SDL_PaletteWatch
{
SDL_PaletteChangedFunc callback;
void *userdata;
struct SDL_PaletteWatch *next;
} SDL_PaletteWatch;

struct SDL_Palette
{
int ncolors;
SDL_Color *colors;
} SDL_Palette;

int refcount;
SDL_PaletteWatch *watch;
};

/* Everything in the pixel format structure is read-only */
typedef struct SDL_PixelFormat
Expand All @@ -226,23 +239,96 @@ typedef struct SDL_PixelFormat
Uint8 alpha;
} SDL_PixelFormat;

/*
* Convert one of the enumerated formats above to a bpp and RGBA masks.
* Returns SDL_TRUE, or SDL_FALSE if the conversion wasn't possible.
/**
* \fn SDL_bool SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 * Rmask, Uint32 * Gmask, Uint32 * Bmask, Uint32 * Amask)
*
* \brief Convert one of the enumerated pixel formats to a bpp and RGBA masks.
*
* \return SDL_TRUE, or SDL_FALSE if the conversion wasn't possible.
*
* \sa SDL_MasksToPixelFormatEnum()
*/
extern DECLSPEC SDL_bool SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp,
Uint32 * Rmask,
Uint32 * Gmask,
Uint32 * Bmask,
Uint32 * Amask);
extern DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format,
int *bpp,
Uint32 * Rmask,
Uint32 * Gmask,
Uint32 * Bmask,
Uint32 * Amask);

/*
* Convert a bpp and RGBA masks to one of the enumerated formats above.
* Returns SDL_PixelFormat_Unknown if the conversion wasn't possible.
/**
* \fn Uint32 SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
*
* \brief Convert a bpp and RGBA masks to an enumerated pixel format.
*
* \return The pixel format, or SDL_PixelFormat_Unknown if the conversion wasn't possible.
*
* \sa SDL_PixelFormatEnumToMasks()
*/
extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp,
Uint32 Rmask,
Uint32 Gmask,
Uint32 Bmask,
Uint32 Amask);

/**
* \fn SDL_Palette *SDL_AllocPalette(int ncolors)
*
* \brief Create a palette structure with the specified number of color entries.
*
* \return A new palette, or NULL if there wasn't enough memory
*
* \note The palette entries are initialized to white.
*
* \sa SDL_FreePalette()
*/
extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors);

/**
* \fn int SDL_AddPaletteWatch(SDL_Palette *palette, SDL_PaletteChangedFunc callback, void *userdata)
*
* \brief Add a callback function which is called when the palette changes.
*
* \sa SDL_DelPaletteWatch()
*/
extern DECLSPEC int SDLCALL SDL_AddPaletteWatch(SDL_Palette * palette,
SDL_PaletteChangedFunc
callback, void *userdata);

/**
* \fn void SDL_DelPaletteWatch(SDL_Palette *palette, SDL_PaletteChangedFunc callback, void *userdata)
*
* \brief Remove a callback function previously added with SDL_AddPaletteWatch()
*
* \sa SDL_AddPaletteWatch()
*/
extern DECLSPEC void SDLCALL SDL_DelPaletteWatch(SDL_Palette * palette,
SDL_PaletteChangedFunc
callback, void *userdata);

/**
* \fn int SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Colors *colors, int firstcolor, int numcolors)
*
* \brief Set a range of colors in a palette.
*
* \param palette The palette to modify
* \param colors An array of colors to copy into the palette
* \param firstcolor The index of the first palette entry to modify
* \param ncolors The number of entries to modify
*
* \return 0 on success, or -1 if not all of the colors could be set
*/
extern DECLSPEC int SDLCALL SDL_SetPaletteColors(SDL_Palette * palette,
const SDL_Color * colors,
int firstcolor, int ncolors);

/**
* \fn void SDL_FreePalette(SDL_Palette *palette)
*
* \brief Free a palette created with SDL_AllocPalette()
*
* \sa SDL_AllocPalette()
*/
extern DECLSPEC Uint32 SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask,
Uint32 Gmask, Uint32 Bmask,
Uint32 Amask);
extern DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette * palette);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
Expand Down
34 changes: 15 additions & 19 deletions include/SDL_video.h
Expand Up @@ -252,6 +252,9 @@ typedef struct SDL_Surface
int pitch; /* Read-only */
void *pixels; /* Read-write */

/* texture associated with the surface, if any */
SDL_TextureID textureID;

/* information needed for surfaces requiring locks */
int locked;
void *lock_data;
Expand Down Expand Up @@ -1066,25 +1069,6 @@ extern DECLSPEC int SDLCALL SDL_SetGammaRamp(const Uint16 * red,
extern DECLSPEC int SDLCALL SDL_GetGammaRamp(Uint16 * red, Uint16 * green,
Uint16 * blue);

/*
* Sets a portion of the colormap for the given 8-bit surface. If 'surface'
* is not a palettized surface, this function does nothing, returning 0.
* If all of the colors were set as passed to SDL_SetColors(), it will
* return 1. If not all the color entries were set exactly as given,
* it will return 0, and you should look at the surface palette to
* determine the actual color palette.
*
* When 'surface' is the surface associated with the current display, the
* display colormap will be updated with the requested colors. If
* SDL_HWPALETTE was set in SDL_SetVideoMode() flags, SDL_SetColors()
* will always return 1, and the palette is guaranteed to be set the way
* you desire, even if the window colormap has to be warped or run under
* emulation.
*/
extern DECLSPEC int SDLCALL SDL_SetColors(SDL_Surface * surface,
const SDL_Color * colors,
int firstcolor, int ncolors);

/*
* Maps an RGB triple to an opaque pixel value for a given pixel format
*/
Expand Down Expand Up @@ -1138,6 +1122,18 @@ extern DECLSPEC SDL_Surface *SDLCALL
SDL_CreateRGBSurfaceFromTexture(SDL_TextureID textureID);
extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface);

/**
* \fn int SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette)
*
* \brief Set the palette used by a surface.
*
* \return 0, or -1 if the surface format doesn't use a palette.
*
* \note A single palette can be shared with many surfaces.
*/
extern DECLSPEC int SDLCALL SDL_SetSurfacePalette(SDL_Surface * surface,
SDL_Palette * palette);

/*
* SDL_LockSurface() sets up a surface for directly accessing the pixels.
* Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write
Expand Down
97 changes: 41 additions & 56 deletions src/SDL_compat.c
Expand Up @@ -204,7 +204,25 @@ SDL_CompatEventFilter(const SDL_Event * event)
break;
}
}
return orig_eventfilter(event);
if (orig_eventfilter) {
return orig_eventfilter(event);
} else {
return 1;
}
}

static int
SDL_VideoPaletteChanged(void *userdata, SDL_Palette * palette)
{
if (userdata == SDL_ShadowSurface) {
/* If the shadow palette changed, make the changes visible */
if (!SDL_VideoSurface->format->palette) {
SDL_UpdateRect(SDL_ShadowSurface, 0, 0, 0, 0);
}
}
if (userdata == SDL_VideoSurface) {
return SDL_SetDisplayPalette(palette->colors, 0, palette->ncolors);
}
}

SDL_Surface *
Expand Down Expand Up @@ -233,7 +251,9 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_ShadowSurface = NULL;
}
if (SDL_VideoSurface) {
SDL_FreeSurface(SDL_ShadowSurface);
SDL_DelPaletteWatch(SDL_VideoSurface->format->palette,
SDL_VideoPaletteChanged, NULL);
SDL_FreeSurface(SDL_VideoSurface);
SDL_VideoSurface = NULL;
}
SDL_DestroyWindow(SDL_VideoWindow);
Expand Down Expand Up @@ -380,11 +400,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_VideoSurface->flags |= SDL_HWPALETTE;
SDL_DitherColors(SDL_VideoSurface->format->palette->colors,
SDL_VideoSurface->format->BitsPerPixel);
SDL_SetTexturePalette(SDL_VideoTexture,
SDL_VideoSurface->format->palette->colors, 0,
SDL_VideoSurface->format->palette->ncolors);
SDL_SetDisplayPalette(SDL_VideoSurface->format->palette->colors, 0,
SDL_VideoSurface->format->palette->ncolors);
SDL_AddPaletteWatch(SDL_VideoSurface->format->palette,
SDL_VideoPaletteChanged, NULL);
SDL_SetPaletteColors(SDL_VideoSurface->format->palette,
SDL_VideoSurface->format->palette->colors, 0,
SDL_VideoSurface->format->palette->ncolors);
}

/* Create a shadow surface if necessary */
Expand Down Expand Up @@ -415,8 +435,13 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
/* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */
if (SDL_ShadowSurface->format->palette) {
SDL_ShadowSurface->flags |= SDL_HWPALETTE;
SDL_DitherColors(SDL_ShadowSurface->format->palette->colors,
SDL_ShadowSurface->format->BitsPerPixel);
if (SDL_VideoSurface->format->palette) {
SDL_SetSurfacePalette(SDL_ShadowSurface,
SDL_VideoSurface->format->palette);
} else {
SDL_DitherColors(SDL_ShadowSurface->format->palette->colors,
SDL_ShadowSurface->format->BitsPerPixel);
}
}
}
SDL_PublicSurface =
Expand Down Expand Up @@ -656,55 +681,15 @@ SDL_SetPalette(SDL_Surface * surface, int flags, const SDL_Color * colors,
}

int
SDL_SetScreenColors(SDL_Surface * screen, const SDL_Color * colors,
int firstcolor, int ncolors)
SDL_SetColors(SDL_Surface * surface, const SDL_Color * colors, int firstcolor,
int ncolors)
{
SDL_Palette *pal;
int gotall;
int palsize;

/* Verify the parameters */
pal = screen->format->palette;
if (!pal) {
return 0; /* not a palettized surface */
}
gotall = 1;
palsize = 1 << screen->format->BitsPerPixel;
if (ncolors > (palsize - firstcolor)) {
ncolors = (palsize - firstcolor);
gotall = 0;
}

if (screen == SDL_ShadowSurface) {
SDL_Palette *vidpal;

vidpal = SDL_VideoSurface->format->palette;
if (vidpal && vidpal->ncolors == pal->ncolors) {
/* This is a shadow surface, and the physical
* framebuffer is also indexed. Propagate the
* changes to its logical palette so that
* updates are always identity blits
*/
SDL_memcpy(vidpal->colors + firstcolor, colors,
ncolors * sizeof(*colors));
}
if (SDL_VideoSurface->flags & SDL_HWPALETTE) {
/* Set the physical palette */
screen = SDL_VideoSurface;
} else {
SDL_UpdateRect(screen, 0, 0, 0, 0);
}
}

if (screen == SDL_VideoSurface) {
SDL_SetTexturePalette(SDL_VideoTexture,
SDL_VideoSurface->format->palette->colors, 0,
SDL_VideoSurface->format->palette->ncolors);
SDL_SetDisplayPalette(SDL_VideoSurface->format->palette->colors, 0,
SDL_VideoSurface->format->palette->ncolors);
if (SDL_SetPaletteColors
(surface->format->palette, colors, firstcolor, ncolors) == 0) {
return 1;
} else {
return 0;
}

return gotall;
}

int
Expand Down
10 changes: 4 additions & 6 deletions src/video/SDL_RLEaccel.c
Expand Up @@ -1618,8 +1618,7 @@ RLEAlphaSurface(SDL_Surface * surface)
#undef ADD_TRANSL_COUNTS

/* Now that we have it encoded, release the original pixels */
if ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC
&& (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) {
if (!(surface->flags & SDL_PREALLOC) && !(surface->flags & SDL_HWSURFACE)) {
SDL_free(surface->pixels);
surface->pixels = NULL;
}
Expand Down Expand Up @@ -1784,8 +1783,7 @@ RLEColorkeySurface(SDL_Surface * surface)
#undef ADD_COUNTS

/* Now that we have it encoded, release the original pixels */
if ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC
&& (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) {
if (!(surface->flags & SDL_PREALLOC) && !(surface->flags & SDL_HWSURFACE)) {
SDL_free(surface->pixels);
surface->pixels = NULL;
}
Expand Down Expand Up @@ -1936,8 +1934,8 @@ SDL_UnRLESurface(SDL_Surface * surface, int recode)
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
surface->flags &= ~SDL_RLEACCEL;

if (recode && (surface->flags & SDL_PREALLOC) != SDL_PREALLOC
&& (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) {
if (recode && !(surface->flags & SDL_PREALLOC)
&& !(surface->flags & SDL_HWSURFACE)) {
if ((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
SDL_Rect full;
unsigned alpha_flag;
Expand Down
2 changes: 1 addition & 1 deletion src/video/SDL_bmp.c
Expand Up @@ -222,7 +222,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
SDL_RWread(src, &palette->colors[i].b, 1, 1);
SDL_RWread(src, &palette->colors[i].g, 1, 1);
SDL_RWread(src, &palette->colors[i].r, 1, 1);
palette->colors[i].unused = 0;
palette->colors[i].unused = SDL_ALPHA_OPAQUE;
}
} else {
for (i = 0; i < (int) biClrUsed; ++i) {
Expand Down

0 comments on commit 5d97336

Please sign in to comment.