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, &current->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, &current->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, &current->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)
     {