Finished palettized display handling.
Added support for surface palette sharing.
--- a/include/SDL_compat.h Fri Jun 16 06:00:31 2006 +0000
+++ b/include/SDL_compat.h Sat Jun 17 06:45:14 2006 +0000
@@ -148,9 +148,9 @@
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);
--- a/include/SDL_pixels.h Fri Jun 16 06:00:31 2006 +0000
+++ b/include/SDL_pixels.h Sat Jun 17 06:45:14 2006 +0000
@@ -195,11 +195,24 @@
} 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
@@ -226,23 +239,96 @@
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 SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format,
+ int *bpp,
+ Uint32 * Rmask,
+ Uint32 * Gmask,
+ Uint32 * Bmask,
+ Uint32 * Amask);
+
+/**
+ * \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_bool SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp,
- Uint32 * Rmask,
- Uint32 * Gmask,
- Uint32 * Bmask,
- Uint32 * Amask);
+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);
-/*
- * Convert a bpp and RGBA masks to one of the enumerated formats above.
- * Returns SDL_PixelFormat_Unknown if the conversion wasn't possible.
+/**
+ * \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 Uint32 SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask,
- Uint32 Gmask, Uint32 Bmask,
- Uint32 Amask);
+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 void SDLCALL SDL_FreePalette(SDL_Palette * palette);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
--- a/include/SDL_video.h Fri Jun 16 06:00:31 2006 +0000
+++ b/include/SDL_video.h Sat Jun 17 06:45:14 2006 +0000
@@ -252,6 +252,9 @@
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;
@@ -1067,25 +1070,6 @@
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
*/
extern DECLSPEC Uint32 SDLCALL SDL_MapRGB
@@ -1138,6 +1122,18 @@
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
--- a/src/SDL_compat.c Fri Jun 16 06:00:31 2006 +0000
+++ b/src/SDL_compat.c Sat Jun 17 06:45:14 2006 +0000
@@ -204,7 +204,25 @@
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 *
@@ -233,7 +251,9 @@
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);
@@ -380,11 +400,11 @@
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 */
@@ -415,8 +435,13 @@
/* 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 =
@@ -656,55 +681,15 @@
}
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 (SDL_SetPaletteColors
+ (surface->format->palette, colors, firstcolor, ncolors) == 0) {
+ return 1;
+ } else {
+ return 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);
- }
-
- return gotall;
}
int
--- a/src/video/SDL_RLEaccel.c Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_RLEaccel.c Sat Jun 17 06:45:14 2006 +0000
@@ -1618,8 +1618,7 @@
#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;
}
@@ -1784,8 +1783,7 @@
#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;
}
@@ -1936,8 +1934,8 @@
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;
--- a/src/video/SDL_bmp.c Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_bmp.c Sat Jun 17 06:45:14 2006 +0000
@@ -222,7 +222,7 @@
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) {
--- a/src/video/SDL_pixels.c Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_pixels.c Sat Jun 17 06:45:14 2006 +0000
@@ -215,6 +215,126 @@
return SDL_PixelFormat_Unknown;
}
+
+SDL_Palette *
+SDL_AllocPalette(int ncolors)
+{
+ SDL_Palette *palette;
+
+ palette = (SDL_Palette *) SDL_malloc(sizeof(*palette));
+ if (!palette) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ palette->colors =
+ (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors));
+ if (!palette->colors) {
+ SDL_free(palette);
+ return NULL;
+ }
+ palette->ncolors = ncolors;
+ palette->watch = NULL;
+ palette->refcount = 1;
+
+ SDL_memset(palette->colors, 0xFF, ncolors * sizeof(*palette->colors));
+
+ return palette;
+}
+
+int
+SDL_AddPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback,
+ void *userdata)
+{
+ SDL_PaletteWatch *watch;
+
+ if (!palette) {
+ return -1;
+ }
+
+ watch = (SDL_PaletteWatch *) SDL_malloc(sizeof(*watch));
+ if (!watch) {
+ SDL_OutOfMemory();
+ return -1;
+ }
+
+ watch->callback = callback;
+ watch->userdata = userdata;
+ watch->next = palette->watch;
+ palette->watch = watch;
+ ++palette->refcount;
+ return 0;
+}
+
+void
+SDL_DelPaletteWatch(SDL_Palette * palette, SDL_PaletteChangedFunc callback,
+ void *userdata)
+{
+ SDL_PaletteWatch *prev, *watch;
+
+ if (!palette) {
+ return;
+ }
+
+ for (prev = NULL, watch = palette->watch; watch;
+ prev = watch, watch = watch->next) {
+ if (watch->callback == callback && watch->userdata == userdata) {
+ if (prev) {
+ prev->next = watch->next;
+ } else {
+ palette->watch = watch->next;
+ }
+ SDL_free(watch);
+ SDL_FreePalette(palette);
+ return;
+ }
+ }
+}
+
+int
+SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors,
+ int firstcolor, int ncolors)
+{
+ SDL_PaletteWatch *watch;
+ int status = 0;
+
+ /* Verify the parameters */
+ if (!palette) {
+ return -1;
+ }
+ if (ncolors > (palette->ncolors - firstcolor)) {
+ ncolors = (palette->ncolors - firstcolor);
+ status = -1;
+ }
+
+ if (colors != (palette->colors + firstcolor)) {
+ SDL_memcpy(palette->colors + firstcolor, colors,
+ ncolors * sizeof(*colors));
+ }
+
+ for (watch = palette->watch; watch; watch = watch->next) {
+ if (watch->callback(watch->userdata, palette) < 0) {
+ status = -1;
+ }
+ }
+
+ return status;
+}
+
+void
+SDL_FreePalette(SDL_Palette * palette)
+{
+ if (!palette) {
+ return;
+ }
+ if (--palette->refcount > 0) {
+ return;
+ }
+ if (palette->colors) {
+ SDL_free(palette->colors);
+ }
+ SDL_free(palette);
+}
+
/*
* Allocate a pixel format structure and fill it according to the given info.
*/
@@ -238,7 +358,6 @@
format->BitsPerPixel = bpp;
format->BytesPerPixel = (bpp + 7) / 8;
if (Rmask || Bmask || Gmask) { /* Packed pixels with custom mask */
- format->palette = NULL;
format->Rshift = 0;
format->Rloss = 8;
if (Rmask) {
@@ -303,121 +422,11 @@
format->Bmask = 0;
format->Amask = 0;
}
- if (bpp <= 8) { /* Palettized mode */
- int ncolors = 1 << bpp;
-#ifdef DEBUG_PALETTE
- fprintf(stderr, "bpp=%d ncolors=%d\n", bpp, ncolors);
-#endif
- format->palette = (SDL_Palette *) SDL_malloc(sizeof(SDL_Palette));
- if (format->palette == NULL) {
- SDL_FreeFormat(format);
- SDL_OutOfMemory();
- return (NULL);
- }
- (format->palette)->ncolors = ncolors;
- (format->palette)->colors = (SDL_Color *) SDL_malloc((format->
- palette)->
- ncolors *
- sizeof
- (SDL_Color));
- if ((format->palette)->colors == NULL) {
- SDL_FreeFormat(format);
- SDL_OutOfMemory();
- return (NULL);
- }
- if (Rmask || Bmask || Gmask) {
- /* create palette according to masks */
- int i;
- int Rm = 0, Gm = 0, Bm = 0;
- int Rw = 0, Gw = 0, Bw = 0;
-#ifdef ENABLE_PALETTE_ALPHA
- int Am = 0, Aw = 0;
-#endif
- if (Rmask) {
- Rw = 8 - format->Rloss;
- for (i = format->Rloss; i > 0; i -= Rw)
- Rm |= 1 << i;
- }
-#ifdef DEBUG_PALETTE
- fprintf(stderr, "Rw=%d Rm=0x%02X\n", Rw, Rm);
-#endif
- if (Gmask) {
- Gw = 8 - format->Gloss;
- for (i = format->Gloss; i > 0; i -= Gw)
- Gm |= 1 << i;
- }
-#ifdef DEBUG_PALETTE
- fprintf(stderr, "Gw=%d Gm=0x%02X\n", Gw, Gm);
-#endif
- if (Bmask) {
- Bw = 8 - format->Bloss;
- for (i = format->Bloss; i > 0; i -= Bw)
- Bm |= 1 << i;
- }
-#ifdef DEBUG_PALETTE
- fprintf(stderr, "Bw=%d Bm=0x%02X\n", Bw, Bm);
-#endif
-#ifdef ENABLE_PALETTE_ALPHA
- if (Amask) {
- Aw = 8 - format->Aloss;
- for (i = format->Aloss; i > 0; i -= Aw)
- Am |= 1 << i;
- }
-# ifdef DEBUG_PALETTE
- fprintf(stderr, "Aw=%d Am=0x%02X\n", Aw, Am);
-# endif
-#endif
- for (i = 0; i < ncolors; ++i) {
- int r, g, b;
- r = (i & Rmask) >> format->Rshift;
- r = (r << format->Rloss) | ((r * Rm) >> Rw);
- format->palette->colors[i].r = r;
+ format->palette = NULL;
- g = (i & Gmask) >> format->Gshift;
- g = (g << format->Gloss) | ((g * Gm) >> Gw);
- format->palette->colors[i].g = g;
-
- b = (i & Bmask) >> format->Bshift;
- b = (b << format->Bloss) | ((b * Bm) >> Bw);
- format->palette->colors[i].b = b;
-
-#ifdef ENABLE_PALETTE_ALPHA
- a = (i & Amask) >> format->Ashift;
- a = (a << format->Aloss) | ((a * Am) >> Aw);
- format->palette->colors[i].unused = a;
-#else
- format->palette->colors[i].unused = SDL_ALPHA_OPAQUE;
-#endif
- }
- } else if (ncolors == 2) {
- /* Create a black and white bitmap palette */
- format->palette->colors[0].r = 0xFF;
- format->palette->colors[0].g = 0xFF;
- format->palette->colors[0].b = 0xFF;
- format->palette->colors[1].r = 0x00;
- format->palette->colors[1].g = 0x00;
- format->palette->colors[1].b = 0x00;
- } else {
- /* Create an empty palette */
- SDL_memset((format->palette)->colors, 0xFF,
- (format->palette)->ncolors * sizeof(SDL_Color));
- }
- }
return (format);
}
-SDL_PixelFormat *
-SDL_ReallocFormat(SDL_Surface * surface, int bpp,
- Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
-{
- if (surface->format) {
- SDL_FreeFormat(surface->format);
- SDL_FormatChanged(surface);
- }
- surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
- return surface->format;
-}
-
/*
* Change any previous mappings from/to the new surface format
*/
@@ -439,15 +448,10 @@
void
SDL_FreeFormat(SDL_PixelFormat * format)
{
- if (format) {
- if (format->palette) {
- if (format->palette->colors) {
- SDL_free(format->palette->colors);
- }
- SDL_free(format->palette);
- }
- SDL_free(format);
+ if (!format) {
+ return;
}
+ SDL_free(format);
}
/*
@@ -695,10 +699,6 @@
SDL_Color colors[256];
SDL_Palette *pal = dst->palette;
- /* SDL_DitherColors does not initialize the 'unused' component of colors,
- but Map1to1 compares it against pal, so we should initialize it. */
- SDL_memset(colors, 0xFF, sizeof(colors));
-
dithered.ncolors = 256;
SDL_DitherColors(colors, 8);
dithered.colors = colors;
@@ -768,14 +768,8 @@
switch (dstfmt->BytesPerPixel) {
case 1:
/* Palette --> Palette */
- /* If both SDL_HWSURFACE, assume have same palette */
- if (((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) &&
- ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE)) {
- map->identity = 1;
- } else {
- map->table = Map1to1(srcfmt->palette,
- dstfmt->palette, &map->identity);
- }
+ map->table =
+ Map1to1(srcfmt->palette, dstfmt->palette, &map->identity);
if (!map->identity) {
if (map->table == NULL) {
return (-1);
--- a/src/video/SDL_pixels_c.h Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_pixels_c.h Sat Jun 17 06:45:14 2006 +0000
@@ -29,9 +29,6 @@
extern SDL_PixelFormat *SDL_AllocFormat(int bpp,
Uint32 Rmask, Uint32 Gmask,
Uint32 Bmask, Uint32 Amask);
-extern SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface * surface, int bpp,
- Uint32 Rmask, Uint32 Gmask,
- Uint32 Bmask, Uint32 Amask);
extern void SDL_FormatChanged(SDL_Surface * surface);
extern void SDL_FreeFormat(SDL_PixelFormat * format);
--- a/src/video/SDL_renderer_sw.c Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_renderer_sw.c Sat Jun 17 06:45:14 2006 +0000
@@ -178,6 +178,7 @@
SDL_SW_DestroyRenderer(renderer);
return NULL;
}
+ SDL_SetSurfacePalette(data->screens[i], window->display->palette);
}
data->current_screen = 0;
data->target = data->screens[0];
@@ -248,8 +249,8 @@
{
SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
- SDL_SetColors(surface, colors, firstcolor, ncolors);
- return 0;
+ return SDL_SetPaletteColors(surface->format->palette, colors, firstcolor,
+ ncolors);
}
static int
@@ -314,7 +315,12 @@
SDL_SW_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
- data->target = (SDL_Surface *) texture->driverdata;
+
+ if (texture) {
+ data->target = (SDL_Surface *) texture->driverdata;
+ } else {
+ data->target = data->screens[data->current_screen];
+ }
}
static void
--- a/src/video/SDL_surface.c Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_surface.c Sat Jun 17 06:45:14 2006 +0000
@@ -47,20 +47,21 @@
/* Next time I write a library like SDL, I'll use int for size. :) */
if (width >= 16384 || height >= 65536) {
SDL_SetError("Width or height is too large");
- return (NULL);
+ return NULL;
}
/* Allocate the surface */
surface = (SDL_Surface *) SDL_malloc(sizeof(*surface));
if (surface == NULL) {
SDL_OutOfMemory();
- return (NULL);
+ return NULL;
}
- surface->flags = 0;
+ SDL_zerop(surface);
+
surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
- if (surface->format == NULL) {
- SDL_free(surface);
- return (NULL);
+ if (!surface->format) {
+ SDL_FreeSurface(surface);
+ return NULL;
}
if (Amask) {
surface->flags |= SDL_SRCALPHA;
@@ -68,16 +69,69 @@
surface->w = width;
surface->h = height;
surface->pitch = SDL_CalculatePitch(surface);
- surface->pixels = NULL;
- surface->locked = 0;
- surface->map = NULL;
SDL_SetClipRect(surface, NULL);
- SDL_FormatChanged(surface);
+
+ if (surface->format->BitsPerPixel <= 8) {
+ SDL_Palette *palette =
+ SDL_AllocPalette((1 << surface->format->BitsPerPixel));
+ if (!palette) {
+ SDL_FreeSurface(surface);
+ return NULL;
+ }
+ if (Rmask || Bmask || Gmask) {
+ const SDL_PixelFormat *format = surface->format;
+
+ /* create palette according to masks */
+ int i;
+ int Rm = 0, Gm = 0, Bm = 0;
+ int Rw = 0, Gw = 0, Bw = 0;
+
+ if (Rmask) {
+ Rw = 8 - format->Rloss;
+ for (i = format->Rloss; i > 0; i -= Rw)
+ Rm |= 1 << i;
+ }
+ if (Gmask) {
+ Gw = 8 - format->Gloss;
+ for (i = format->Gloss; i > 0; i -= Gw)
+ Gm |= 1 << i;
+ }
+ if (Bmask) {
+ Bw = 8 - format->Bloss;
+ for (i = format->Bloss; i > 0; i -= Bw)
+ Bm |= 1 << i;
+ }
+ for (i = 0; i < palette->ncolors; ++i) {
+ int r, g, b;
+ r = (i & Rmask) >> format->Rshift;
+ r = (r << format->Rloss) | ((r * Rm) >> Rw);
+ palette->colors[i].r = r;
+
+ g = (i & Gmask) >> format->Gshift;
+ g = (g << format->Gloss) | ((g * Gm) >> Gw);
+ palette->colors[i].g = g;
+
+ b = (i & Bmask) >> format->Bshift;
+ b = (b << format->Bloss) | ((b * Bm) >> Bw);
+ palette->colors[i].b = b;
+ }
+ } else if (palette->ncolors == 2) {
+ /* Create a black and white bitmap palette */
+ palette->colors[0].r = 0xFF;
+ palette->colors[0].g = 0xFF;
+ palette->colors[0].b = 0xFF;
+ palette->colors[1].r = 0x00;
+ palette->colors[1].g = 0x00;
+ palette->colors[1].b = 0x00;
+ }
+ SDL_SetSurfacePalette(surface, palette);
+ SDL_FreePalette(palette);
+ }
/* Get the pixels */
if (surface->w && surface->h) {
surface->pixels = SDL_malloc(surface->h * surface->pitch);
- if (surface->pixels == NULL) {
+ if (!surface->pixels) {
SDL_FreeSurface(surface);
SDL_OutOfMemory();
return NULL;
@@ -88,17 +142,18 @@
/* Allocate an empty mapping */
surface->map = SDL_AllocBlitMap();
- if (surface->map == NULL) {
+ if (!surface->map) {
SDL_FreeSurface(surface);
- return (NULL);
+ return NULL;
}
+ SDL_FormatChanged(surface);
/* The surface is ready to go */
surface->refcount = 1;
#ifdef CHECK_LEAKS
++surfaces_allocated;
#endif
- return (surface);
+ return surface;
}
/*
@@ -157,47 +212,64 @@
surface->flags |= SDL_HWSURFACE;
surface->w = w;
surface->h = h;
- surface->lock_data = (void *) textureID;
SDL_SetClipRect(surface, NULL);
}
}
+ if (surface) {
+ surface->textureID = textureID;
+ }
return surface;
}
-/*
- * Set the palette in a blittable surface
- */
-int
-SDL_SetColors(SDL_Surface * surface, const SDL_Color * colors, int firstcolor,
- int ncolors)
+static int
+SDL_SurfacePaletteChanged(void *userdata, SDL_Palette * palette)
{
- SDL_Palette *pal;
- int gotall;
- int palsize;
+ SDL_Surface *surface = (SDL_Surface *) userdata;
- /* Verify the parameters */
- pal = surface->format->palette;
- if (!pal) {
- return 0; /* not a palettized surface */
- }
- gotall = 1;
- palsize = 1 << surface->format->BitsPerPixel;
- if (ncolors > (palsize - firstcolor)) {
- ncolors = (palsize - firstcolor);
- gotall = 0;
- }
-
- if (colors != (pal->colors + firstcolor)) {
- SDL_memcpy(pal->colors + firstcolor, colors,
- ncolors * sizeof(*colors));
+ if (surface->textureID) {
+ if (SDL_SetTexturePalette
+ (surface->textureID, palette->colors, 0, palette->ncolors) < 0) {
+ SDL_GetTexturePalette(surface->textureID, palette->colors, 0,
+ palette->ncolors);
+ return -1;
+ }
}
SDL_FormatChanged(surface);
- if (surface->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) {
- gotall &= SDL_SetScreenColors(surface, colors, firstcolor, ncolors);
+ return 0;
+}
+
+int
+SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette)
+{
+ if (!surface || !surface->format) {
+ SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
+ return -1;
+ }
+
+ if (palette && palette->ncolors != (1 << surface->format->BitsPerPixel)) {
+ SDL_SetError
+ ("SDL_SetSurfacePalette() passed a palette that doesn't match the surface format");
+ return -1;
}
- return gotall;
+
+ if (surface->format->palette == palette) {
+ return 0;
+ }
+
+ if (surface->format->palette) {
+ SDL_DelPaletteWatch(surface->format->palette,
+ SDL_SurfacePaletteChanged, surface);
+ }
+
+ surface->format->palette = palette;
+
+ if (surface->format->palette) {
+ SDL_AddPaletteWatch(surface->format->palette,
+ SDL_SurfacePaletteChanged, surface);
+ }
+ return 0;
}
/*
@@ -729,8 +801,8 @@
/* Perform the lock */
if (surface->flags & SDL_HWSURFACE) {
if (SDL_LockTexture
- ((SDL_TextureID) surface->lock_data, NULL, 1,
- &surface->pixels, &surface->pitch) < 0) {
+ (surface->textureID, NULL, 1, &surface->pixels,
+ &surface->pitch) < 0) {
return (-1);
}
}
@@ -760,13 +832,13 @@
/* Unlock hardware or accelerated surfaces */
if (surface->flags & SDL_HWSURFACE) {
- SDL_UnlockTexture((SDL_TextureID) surface->lock_data);
- } else {
- /* Update RLE encoded surface with new data */
- if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
- surface->flags &= ~SDL_RLEACCEL; /* stop lying */
- SDL_RLESurface(surface);
- }
+ SDL_UnlockTexture(surface->textureID);
+ }
+
+ /* Update RLE encoded surface with new data */
+ if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
+ surface->flags &= ~SDL_RLEACCEL; /* stop lying */
+ SDL_RLESurface(surface);
}
}
@@ -894,6 +966,7 @@
SDL_UnRLESurface(surface, 0);
}
if (surface->format) {
+ SDL_SetSurfacePalette(surface, NULL);
SDL_FreeFormat(surface->format);
surface->format = NULL;
}
@@ -902,8 +975,8 @@
surface->map = NULL;
}
/* Should we destroy the texture too?
- if (surface->flags & SDL_HWSURFACE) {
- SDL_DestroyTexture((SDL_TextureID)surface->lock_data);
+ if (surface->textureID) {
+ SDL_DestroyTexture(surface->textureID);
}
*/
if (surface->pixels && ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC)) {
--- a/src/video/SDL_sysvideo.h Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_sysvideo.h Sat Jun 17 06:45:14 2006 +0000
@@ -146,7 +146,7 @@
SDL_DisplayMode *display_modes;
SDL_DisplayMode desktop_mode;
SDL_DisplayMode current_mode;
- SDL_Palette palette;
+ SDL_Palette *palette;
int num_render_drivers;
SDL_RenderDriver *render_drivers;
--- a/src/video/SDL_video.c Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/SDL_video.c Sat Jun 17 06:45:14 2006 +0000
@@ -517,7 +517,7 @@
{
SDL_VideoDisplay *display;
SDL_DisplayMode display_mode;
- int i;
+ int i, ncolors;
if (!_this) {
SDL_SetError("Video subsystem has not been initialized");
@@ -560,26 +560,24 @@
return 0;
}
+ /* Set up a palette, if necessary */
if (SDL_ISPIXELFORMAT_INDEXED(display_mode.format)) {
- display->palette.ncolors =
- (1 << SDL_BITSPERPIXEL(display_mode.format));
- display->palette.colors =
- (SDL_Color *) SDL_realloc(display->palette.colors,
- display->palette.ncolors *
- sizeof(*display->palette.colors));
- if (!display->palette.colors) {
- SDL_OutOfMemory();
- return -1;
+ ncolors = (1 << SDL_BITSPERPIXEL(display_mode.format));
+ } else {
+ ncolors = 0;
+ }
+ if ((!ncolors && display->palette) || (ncolors && !display->palette)
+ || (ncolors != display->palette->ncolors)) {
+ if (display->palette) {
+ SDL_FreePalette(display->palette);
+ display->palette = NULL;
}
- SDL_memset(display->palette.colors, 0xff,
- display->palette.ncolors *
- sizeof(*display->palette.colors));
- } else {
- if (display->palette.colors) {
- SDL_free(display->palette.colors);
+ if (ncolors) {
+ display->palette = SDL_AllocPalette(ncolors);
+ if (!display->palette) {
+ return -1;
+ }
}
- display->palette.colors = NULL;
- display->palette.ncolors = 0;
}
return _this->SetDisplayMode(_this, &display_mode);
@@ -589,31 +587,27 @@
SDL_SetDisplayPalette(const SDL_Color * colors, int firstcolor, int ncolors)
{
SDL_Palette *palette;
+ int status = 0;
if (!_this) {
SDL_SetError("Video subsystem has not been initialized");
return -1;
}
-
- palette = &SDL_CurrentDisplay.palette;
- if (!palette->ncolors) {
+ if (!SDL_CurrentDisplay.palette) {
SDL_SetError("Display mode does not have a palette");
return -1;
}
- if (firstcolor < 0 || (firstcolor + ncolors) > palette->ncolors) {
- SDL_SetError("Palette indices are out of range");
- return -1;
- }
-
- SDL_memcpy(&palette->colors[firstcolor], colors,
- ncolors * sizeof(*colors));
+ status =
+ SDL_SetPaletteColors(SDL_CurrentDisplay.palette, colors, firstcolor,
+ ncolors);
if (_this->SetDisplayPalette) {
- return _this->SetDisplayPalette(_this, palette);
- } else {
- return 0;
+ if (_this->SetDisplayPalette(_this, palette) < 0) {
+ status = -1;
+ }
}
+ return status;
}
int
@@ -626,7 +620,7 @@
return -1;
}
- palette = &SDL_CurrentDisplay.palette;
+ palette = SDL_CurrentDisplay.palette;
if (!palette->ncolors) {
SDL_SetError("Display mode does not have a palette");
return -1;
@@ -1717,10 +1711,9 @@
SDL_free(display->windows);
display->windows = NULL;
}
- if (display->palette.colors) {
- SDL_free(display->palette.colors);
- display->palette.colors = NULL;
- display->palette.ncolors = 0;
+ if (display->palette) {
+ SDL_FreePalette(display->palette);
+ display->palette = NULL;
}
}
_this->VideoQuit(_this);
--- a/src/video/dummy/SDL_nullrender.c Fri Jun 16 06:00:31 2006 +0000
+++ b/src/video/dummy/SDL_nullrender.c Sat Jun 17 06:45:14 2006 +0000
@@ -106,16 +106,7 @@
SDL_DUMMY_DestroyRenderer(renderer);
return NULL;
}
-
- /* If the display has a palette, use it for the window surfaces */
- if (window->display->palette.ncolors) {
- SDL_PixelFormat *format = data->surface->format;
- if (format->palette->colors) {
- SDL_free(format->palette->colors);
- }
- SDL_free(format->palette);
- format->palette = &window->display->palette;
- }
+ SDL_SetSurfacePalette(data->surface, window->display->palette);
return renderer;
}
@@ -178,8 +169,8 @@
if (SDL_getenv("SDL_VIDEO_DUMMY_SAVE_FRAMES")) {
char file[128];
- SDL_snprintf(file, sizeof(file), "SDL_frame-%8.8d.bmp",
- ++frame_number);
+ SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
+ renderer->window->id, ++frame_number);
SDL_SaveBMP(surface, file);
}
}