Mercurial > sdl-ios-xcode
diff src/video/SDL_pixels.c @ 1683:396a35389351 SDL-1.3
Finished palettized display handling.
Added support for surface palette sharing.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 17 Jun 2006 06:45:14 +0000 |
parents | 7ae8018b2e5d |
children | 1577404809f0 |
line wrap: on
line diff
--- 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);