Mercurial > sdl-ios-xcode
diff src/video/directfb/SDL_DirectFB_video.c @ 477:22581630aab7
Date: Tue, 27 Aug 2002 16:14:11 +0200
From: Denis Oliver Kropp
Subject: Palette support and 8bit color keying fix
This patch adds support for 8bit palette modes dropping
the RGB332 stuff. It also fixes color keying for 8bit.
testsprite (without -bpp >8) looks correct again.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 31 Aug 2002 04:06:37 +0000 |
parents | 1c4be4a16410 |
children | f8482d7c9595 |
line wrap: on
line diff
--- a/src/video/directfb/SDL_DirectFB_video.c Sat Aug 31 04:01:19 2002 +0000 +++ b/src/video/directfb/SDL_DirectFB_video.c Sat Aug 31 04:06:37 2002 +0000 @@ -158,13 +158,13 @@ layer->GetConfiguration (layer, &dlc); - if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat)) + if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1) return dlc.pixelformat; switch (bytes) { case 1: - return DSPF_RGB332; + return DSPF_LUT8; case 2: return DSPF_RGB16; case 3: @@ -204,6 +204,7 @@ struct private_hwdata { IDirectFBSurface *surface; + IDirectFBPalette *palette; }; void SetDirectFBerror (const char *function, DFBResult code) @@ -222,6 +223,9 @@ { switch (format->BitsPerPixel) { + case 8: + return DSPF_LUT8; + case 16: if (format->Rmask == 0xF800 && format->Gmask == 0x07E0 && @@ -236,13 +240,6 @@ return DSPF_RGB15; break; - case 8: - if (format->Rmask == 0xE0 && - format->Gmask == 0x1C && - format->Bmask == 0x03) - return DSPF_RGB332; - break; - case 24: if (format->Rmask == 0xFF0000 && format->Gmask == 0x00FF00 && @@ -268,7 +265,7 @@ switch (format->BitsPerPixel) { case 8: - return DSPF_RGB332; + return DSPF_LUT8; case 15: return DSPF_RGB15; case 16: @@ -283,12 +280,8 @@ return DSPF_UNKNOWN; } -static const __u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff }; -static const __u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff }; - -static SDL_Palette *GenerateRGB332Palette() +static SDL_Palette *AllocatePalette(int size) { - int i; SDL_Palette *palette; SDL_Color *colors; @@ -299,21 +292,14 @@ return NULL; } - colors = calloc (256, sizeof(SDL_Color)); + colors = calloc (size, sizeof(SDL_Color)); if (!colors) { SDL_OutOfMemory(); return NULL; } - for (i=0; i<256; i++) - { - colors[i].r = lookup3to8[ i >> 5 ]; - colors[i].g = lookup3to8[ (i >> 2) & 7 ]; - colors[i].g = lookup2to8[ i & 3 ]; - } - - palette->ncolors = 256; + palette->ncolors = size; palette->colors = colors; return palette; @@ -352,15 +338,17 @@ format->Bmask = 0x000000FF; break; - case DSPF_RGB332: - format->Rmask = 0x000000E0; - format->Gmask = 0x0000001C; - format->Bmask = 0x00000003; + case DSPF_LUT8: + format->Rmask = 0x000000FF; + format->Gmask = 0x000000FF; + format->Bmask = 0x000000FF; - format->palette = GenerateRGB332Palette(); + if (!format->palette) + format->palette = AllocatePalette(256); break; default: + fprintf (stderr, "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n", pixelformat); return -1; } @@ -377,7 +365,6 @@ DFBResult ret; DFBCardCapabilities caps; DFBDisplayLayerConfig dlc; - DFBSurfacePixelFormat format; struct DirectFBEnumRect *rect; IDirectFB *dfb = NULL; IDirectFBDisplayLayer *layer = NULL; @@ -417,15 +404,9 @@ /* Query layer configuration to determine the current mode and pixelformat */ layer->GetConfiguration (layer, &dlc); - /* FIXME: Returning RGB332 as the default mode doesn't work (everything is black) */ - if ((format = dlc.pixelformat) == DSPF_RGB332) - format = DSPF_RGB16; - - if (DFBToSDLPixelFormat (format, vformat)) - { - SDL_SetError ("Unsupported pixelformat"); - goto error; - } + /* If current format is not supported use LUT8 as the default */ + if (DFBToSDLPixelFormat (dlc.pixelformat, vformat)) + DFBToSDLPixelFormat (DSPF_LUT8, vformat); /* Enumerate the available fullscreen modes */ ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this); @@ -494,9 +475,10 @@ static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { - DFBResult ret; - DFBSurfaceDescription dsc; - DFBSurfacePixelFormat pixelformat; + DFBResult ret; + DFBSurfaceDescription dsc; + DFBSurfacePixelFormat pixelformat; + IDirectFBSurface *surface; fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n", width, height, bpp, flags); @@ -508,6 +490,13 @@ { current->hwdata->surface->Release (current->hwdata->surface); current->hwdata->surface = NULL; + + /* And its palette if present */ + if (current->hwdata->palette) + { + current->hwdata->palette->Release (current->hwdata->palette); + current->hwdata->palette = NULL; + } } else if (!current->hwdata) { @@ -556,17 +545,16 @@ dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0); dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer); - ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, ¤t->hwdata->surface); + ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface); if (ret && (flags & SDL_DOUBLEBUF)) { /* Try without double buffering */ dsc.caps &= ~DSCAPS_FLIPPING; - ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, ¤t->hwdata->surface); + ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface); } if (ret) { SetDirectFBerror ("dfb->CreateSurface", ret); - current->hwdata->surface = NULL; return NULL; } @@ -585,9 +573,20 @@ if (dsc.caps & DSCAPS_FLIPPING) current->flags |= SDL_DOUBLEBUF; - current->hwdata->surface->GetPixelFormat (current->hwdata->surface, &pixelformat); + surface->GetPixelFormat (surface, &pixelformat); + DFBToSDLPixelFormat (pixelformat, current->format); + /* Get the surface palette (if supported) */ + if (DFB_PIXELFORMAT_IS_INDEXED( pixelformat )) + { + surface->GetPalette (surface, ¤t->hwdata->palette); + + current->flags |= SDL_HWPALETTE; + } + + current->hwdata->surface = surface; + return current; } @@ -712,11 +711,14 @@ SDL_PixelFormat *fmt = src->format; IDirectFBSurface *surface = src->hwdata->surface; - /* ugly */ - surface->SetSrcColorKey (surface, - (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss), - (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss), - (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift)); + if (fmt->BitsPerPixel == 8) + surface->SetSrcColorKeyIndex (surface, key); + else + /* ugly */ + surface->SetSrcColorKey (surface, + (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss), + (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss), + (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift)); return 0; } @@ -809,13 +811,50 @@ int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) { - fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n"); - return -1; + IDirectFBPalette *palette = this->screen->hwdata->palette; + + if (!palette) + return 0; + + if (firstcolor > 255) + return 0; + + if (firstcolor + ncolors > 256) + ncolors = 256 - firstcolor; + + if (ncolors > 0) + { + int i; + DFBColor entries[ncolors]; + + for (i=0; i<ncolors; i++) + { + entries[i].a = 0xff; + entries[i].r = colors[i].r; + entries[i].g = colors[i].g; + entries[i].b = colors[i].b; + } + + palette->SetEntries (palette, entries, ncolors, firstcolor); + } + + return 1; } void DirectFB_VideoQuit(_THIS) { - struct DirectFBEnumRect *rect = enumlist; + struct DirectFBEnumRect *rect = enumlist; + IDirectFBSurface *surface = this->screen->hwdata->surface; + IDirectFBPalette *palette = this->screen->hwdata->palette; + + if (palette) + palette->Release (palette); + + if (surface) + surface->Release (surface); + + this->screen->hwdata->surface = NULL; + this->screen->hwdata->palette = NULL; if (HIDDEN->eventbuffer) {