Mercurial > sdl-ios-xcode
comparison 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 |
comparison
equal
deleted
inserted
replaced
476:a7129c0083f4 | 477:22581630aab7 |
---|---|
156 DFBDisplayLayerConfig dlc; | 156 DFBDisplayLayerConfig dlc; |
157 int bytes = (bpp + 7) / 8; | 157 int bytes = (bpp + 7) / 8; |
158 | 158 |
159 layer->GetConfiguration (layer, &dlc); | 159 layer->GetConfiguration (layer, &dlc); |
160 | 160 |
161 if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat)) | 161 if (bytes == DFB_BYTES_PER_PIXEL(dlc.pixelformat) && bytes > 1) |
162 return dlc.pixelformat; | 162 return dlc.pixelformat; |
163 | 163 |
164 switch (bytes) | 164 switch (bytes) |
165 { | 165 { |
166 case 1: | 166 case 1: |
167 return DSPF_RGB332; | 167 return DSPF_LUT8; |
168 case 2: | 168 case 2: |
169 return DSPF_RGB16; | 169 return DSPF_RGB16; |
170 case 3: | 170 case 3: |
171 return DSPF_RGB24; | 171 return DSPF_RGB24; |
172 case 4: | 172 case 4: |
202 return DFENUM_OK; | 202 return DFENUM_OK; |
203 } | 203 } |
204 | 204 |
205 struct private_hwdata { | 205 struct private_hwdata { |
206 IDirectFBSurface *surface; | 206 IDirectFBSurface *surface; |
207 IDirectFBPalette *palette; | |
207 }; | 208 }; |
208 | 209 |
209 void SetDirectFBerror (const char *function, DFBResult code) | 210 void SetDirectFBerror (const char *function, DFBResult code) |
210 { | 211 { |
211 const char *error = DirectFBErrorString (code); | 212 const char *error = DirectFBErrorString (code); |
220 { | 221 { |
221 if (format->Rmask && format->Gmask && format->Bmask) | 222 if (format->Rmask && format->Gmask && format->Bmask) |
222 { | 223 { |
223 switch (format->BitsPerPixel) | 224 switch (format->BitsPerPixel) |
224 { | 225 { |
226 case 8: | |
227 return DSPF_LUT8; | |
228 | |
225 case 16: | 229 case 16: |
226 if (format->Rmask == 0xF800 && | 230 if (format->Rmask == 0xF800 && |
227 format->Gmask == 0x07E0 && | 231 format->Gmask == 0x07E0 && |
228 format->Bmask == 0x001F) | 232 format->Bmask == 0x001F) |
229 return DSPF_RGB16; | 233 return DSPF_RGB16; |
234 format->Gmask == 0x03E0 && | 238 format->Gmask == 0x03E0 && |
235 format->Bmask == 0x001F) | 239 format->Bmask == 0x001F) |
236 return DSPF_RGB15; | 240 return DSPF_RGB15; |
237 break; | 241 break; |
238 | 242 |
239 case 8: | |
240 if (format->Rmask == 0xE0 && | |
241 format->Gmask == 0x1C && | |
242 format->Bmask == 0x03) | |
243 return DSPF_RGB332; | |
244 break; | |
245 | |
246 case 24: | 243 case 24: |
247 if (format->Rmask == 0xFF0000 && | 244 if (format->Rmask == 0xFF0000 && |
248 format->Gmask == 0x00FF00 && | 245 format->Gmask == 0x00FF00 && |
249 format->Bmask == 0x0000FF) | 246 format->Bmask == 0x0000FF) |
250 return DSPF_RGB24; | 247 return DSPF_RGB24; |
266 else | 263 else |
267 { | 264 { |
268 switch (format->BitsPerPixel) | 265 switch (format->BitsPerPixel) |
269 { | 266 { |
270 case 8: | 267 case 8: |
271 return DSPF_RGB332; | 268 return DSPF_LUT8; |
272 case 15: | 269 case 15: |
273 return DSPF_RGB15; | 270 return DSPF_RGB15; |
274 case 16: | 271 case 16: |
275 return DSPF_RGB16; | 272 return DSPF_RGB16; |
276 case 24: | 273 case 24: |
281 } | 278 } |
282 | 279 |
283 return DSPF_UNKNOWN; | 280 return DSPF_UNKNOWN; |
284 } | 281 } |
285 | 282 |
286 static const __u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff }; | 283 static SDL_Palette *AllocatePalette(int size) |
287 static const __u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff }; | 284 { |
288 | |
289 static SDL_Palette *GenerateRGB332Palette() | |
290 { | |
291 int i; | |
292 SDL_Palette *palette; | 285 SDL_Palette *palette; |
293 SDL_Color *colors; | 286 SDL_Color *colors; |
294 | 287 |
295 palette = calloc (1, sizeof(SDL_Palette)); | 288 palette = calloc (1, sizeof(SDL_Palette)); |
296 if (!palette) | 289 if (!palette) |
297 { | 290 { |
298 SDL_OutOfMemory(); | 291 SDL_OutOfMemory(); |
299 return NULL; | 292 return NULL; |
300 } | 293 } |
301 | 294 |
302 colors = calloc (256, sizeof(SDL_Color)); | 295 colors = calloc (size, sizeof(SDL_Color)); |
303 if (!colors) | 296 if (!colors) |
304 { | 297 { |
305 SDL_OutOfMemory(); | 298 SDL_OutOfMemory(); |
306 return NULL; | 299 return NULL; |
307 } | 300 } |
308 | 301 |
309 for (i=0; i<256; i++) | 302 palette->ncolors = size; |
310 { | |
311 colors[i].r = lookup3to8[ i >> 5 ]; | |
312 colors[i].g = lookup3to8[ (i >> 2) & 7 ]; | |
313 colors[i].g = lookup2to8[ i & 3 ]; | |
314 } | |
315 | |
316 palette->ncolors = 256; | |
317 palette->colors = colors; | 303 palette->colors = colors; |
318 | 304 |
319 return palette; | 305 return palette; |
320 } | 306 } |
321 | 307 |
350 format->Rmask = 0x00FF0000; | 336 format->Rmask = 0x00FF0000; |
351 format->Gmask = 0x0000FF00; | 337 format->Gmask = 0x0000FF00; |
352 format->Bmask = 0x000000FF; | 338 format->Bmask = 0x000000FF; |
353 break; | 339 break; |
354 | 340 |
355 case DSPF_RGB332: | 341 case DSPF_LUT8: |
356 format->Rmask = 0x000000E0; | 342 format->Rmask = 0x000000FF; |
357 format->Gmask = 0x0000001C; | 343 format->Gmask = 0x000000FF; |
358 format->Bmask = 0x00000003; | 344 format->Bmask = 0x000000FF; |
359 | 345 |
360 format->palette = GenerateRGB332Palette(); | 346 if (!format->palette) |
347 format->palette = AllocatePalette(256); | |
361 break; | 348 break; |
362 | 349 |
363 default: | 350 default: |
351 fprintf (stderr, "SDL_DirectFB: Unsupported pixelformat (0x%08x)!\n", pixelformat); | |
364 return -1; | 352 return -1; |
365 } | 353 } |
366 | 354 |
367 format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8; | 355 format->BitsPerPixel = DFB_BYTES_PER_PIXEL(pixelformat) * 8; |
368 format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat); | 356 format->BytesPerPixel = DFB_BYTES_PER_PIXEL(pixelformat); |
375 { | 363 { |
376 int i; | 364 int i; |
377 DFBResult ret; | 365 DFBResult ret; |
378 DFBCardCapabilities caps; | 366 DFBCardCapabilities caps; |
379 DFBDisplayLayerConfig dlc; | 367 DFBDisplayLayerConfig dlc; |
380 DFBSurfacePixelFormat format; | |
381 struct DirectFBEnumRect *rect; | 368 struct DirectFBEnumRect *rect; |
382 IDirectFB *dfb = NULL; | 369 IDirectFB *dfb = NULL; |
383 IDirectFBDisplayLayer *layer = NULL; | 370 IDirectFBDisplayLayer *layer = NULL; |
384 IDirectFBEventBuffer *events = NULL; | 371 IDirectFBEventBuffer *events = NULL; |
385 | 372 |
415 layer->EnableCursor (layer, 1); | 402 layer->EnableCursor (layer, 1); |
416 | 403 |
417 /* Query layer configuration to determine the current mode and pixelformat */ | 404 /* Query layer configuration to determine the current mode and pixelformat */ |
418 layer->GetConfiguration (layer, &dlc); | 405 layer->GetConfiguration (layer, &dlc); |
419 | 406 |
420 /* FIXME: Returning RGB332 as the default mode doesn't work (everything is black) */ | 407 /* If current format is not supported use LUT8 as the default */ |
421 if ((format = dlc.pixelformat) == DSPF_RGB332) | 408 if (DFBToSDLPixelFormat (dlc.pixelformat, vformat)) |
422 format = DSPF_RGB16; | 409 DFBToSDLPixelFormat (DSPF_LUT8, vformat); |
423 | |
424 if (DFBToSDLPixelFormat (format, vformat)) | |
425 { | |
426 SDL_SetError ("Unsupported pixelformat"); | |
427 goto error; | |
428 } | |
429 | 410 |
430 /* Enumerate the available fullscreen modes */ | 411 /* Enumerate the available fullscreen modes */ |
431 ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this); | 412 ret = dfb->EnumVideoModes (dfb, EnumModesCallback, this); |
432 if (ret) | 413 if (ret) |
433 { | 414 { |
492 return NULL; | 473 return NULL; |
493 } | 474 } |
494 | 475 |
495 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) | 476 static SDL_Surface *DirectFB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) |
496 { | 477 { |
497 DFBResult ret; | 478 DFBResult ret; |
498 DFBSurfaceDescription dsc; | 479 DFBSurfaceDescription dsc; |
499 DFBSurfacePixelFormat pixelformat; | 480 DFBSurfacePixelFormat pixelformat; |
481 IDirectFBSurface *surface; | |
500 | 482 |
501 fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n", | 483 fprintf (stderr, "SDL DirectFB_SetVideoMode: %dx%d@%d, flags: 0x%08x\n", |
502 width, height, bpp, flags); | 484 width, height, bpp, flags); |
503 | 485 |
504 flags |= SDL_FULLSCREEN; | 486 flags |= SDL_FULLSCREEN; |
506 /* Release previous primary surface */ | 488 /* Release previous primary surface */ |
507 if (current->hwdata && current->hwdata->surface) | 489 if (current->hwdata && current->hwdata->surface) |
508 { | 490 { |
509 current->hwdata->surface->Release (current->hwdata->surface); | 491 current->hwdata->surface->Release (current->hwdata->surface); |
510 current->hwdata->surface = NULL; | 492 current->hwdata->surface = NULL; |
493 | |
494 /* And its palette if present */ | |
495 if (current->hwdata->palette) | |
496 { | |
497 current->hwdata->palette->Release (current->hwdata->palette); | |
498 current->hwdata->palette = NULL; | |
499 } | |
511 } | 500 } |
512 else if (!current->hwdata) | 501 else if (!current->hwdata) |
513 { | 502 { |
514 /* Allocate the hardware acceleration data */ | 503 /* Allocate the hardware acceleration data */ |
515 current->hwdata = (struct private_hwdata *) calloc (1, sizeof(*current->hwdata)); | 504 current->hwdata = (struct private_hwdata *) calloc (1, sizeof(*current->hwdata)); |
554 /* Create primary surface */ | 543 /* Create primary surface */ |
555 dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT; | 544 dsc.flags = DSDESC_CAPS | DSDESC_PIXELFORMAT; |
556 dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0); | 545 dsc.caps = DSCAPS_PRIMARY | ((flags & SDL_DOUBLEBUF) ? DSCAPS_FLIPPING : 0); |
557 dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer); | 546 dsc.pixelformat = GetFormatForBpp (bpp, HIDDEN->layer); |
558 | 547 |
559 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, ¤t->hwdata->surface); | 548 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface); |
560 if (ret && (flags & SDL_DOUBLEBUF)) | 549 if (ret && (flags & SDL_DOUBLEBUF)) |
561 { | 550 { |
562 /* Try without double buffering */ | 551 /* Try without double buffering */ |
563 dsc.caps &= ~DSCAPS_FLIPPING; | 552 dsc.caps &= ~DSCAPS_FLIPPING; |
564 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, ¤t->hwdata->surface); | 553 ret = HIDDEN->dfb->CreateSurface (HIDDEN->dfb, &dsc, &surface); |
565 } | 554 } |
566 if (ret) | 555 if (ret) |
567 { | 556 { |
568 SetDirectFBerror ("dfb->CreateSurface", ret); | 557 SetDirectFBerror ("dfb->CreateSurface", ret); |
569 current->hwdata->surface = NULL; | |
570 return NULL; | 558 return NULL; |
571 } | 559 } |
572 | 560 |
573 current->w = width; | 561 current->w = width; |
574 current->h = height; | 562 current->h = height; |
583 this->UpdateRects = DirectFB_WindowedUpdate; | 571 this->UpdateRects = DirectFB_WindowedUpdate; |
584 | 572 |
585 if (dsc.caps & DSCAPS_FLIPPING) | 573 if (dsc.caps & DSCAPS_FLIPPING) |
586 current->flags |= SDL_DOUBLEBUF; | 574 current->flags |= SDL_DOUBLEBUF; |
587 | 575 |
588 current->hwdata->surface->GetPixelFormat (current->hwdata->surface, &pixelformat); | 576 surface->GetPixelFormat (surface, &pixelformat); |
577 | |
589 DFBToSDLPixelFormat (pixelformat, current->format); | 578 DFBToSDLPixelFormat (pixelformat, current->format); |
579 | |
580 /* Get the surface palette (if supported) */ | |
581 if (DFB_PIXELFORMAT_IS_INDEXED( pixelformat )) | |
582 { | |
583 surface->GetPalette (surface, ¤t->hwdata->palette); | |
584 | |
585 current->flags |= SDL_HWPALETTE; | |
586 } | |
587 | |
588 current->hwdata->surface = surface; | |
590 | 589 |
591 return current; | 590 return current; |
592 } | 591 } |
593 | 592 |
594 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface) | 593 static int DirectFB_AllocHWSurface(_THIS, SDL_Surface *surface) |
710 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *src, Uint32 key) | 709 static int DirectFB_SetHWColorKey(_THIS, SDL_Surface *src, Uint32 key) |
711 { | 710 { |
712 SDL_PixelFormat *fmt = src->format; | 711 SDL_PixelFormat *fmt = src->format; |
713 IDirectFBSurface *surface = src->hwdata->surface; | 712 IDirectFBSurface *surface = src->hwdata->surface; |
714 | 713 |
715 /* ugly */ | 714 if (fmt->BitsPerPixel == 8) |
716 surface->SetSrcColorKey (surface, | 715 surface->SetSrcColorKeyIndex (surface, key); |
717 (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss), | 716 else |
718 (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss), | 717 /* ugly */ |
719 (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift)); | 718 surface->SetSrcColorKey (surface, |
719 (key & fmt->Rmask) >> (fmt->Rshift - fmt->Rloss), | |
720 (key & fmt->Gmask) >> (fmt->Gshift - fmt->Gloss), | |
721 (key & fmt->Bmask) << (fmt->Bloss - fmt->Bshift)); | |
720 | 722 |
721 return 0; | 723 return 0; |
722 } | 724 } |
723 | 725 |
724 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha) | 726 static int DirectFB_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha) |
807 surface->Flip (surface, ®ion, DSFLIP_WAITFORSYNC); | 809 surface->Flip (surface, ®ion, DSFLIP_WAITFORSYNC); |
808 } | 810 } |
809 | 811 |
810 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | 812 int DirectFB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) |
811 { | 813 { |
812 fprintf(stderr, "SDL: Unimplemented DirectFB_SetColors!\n"); | 814 IDirectFBPalette *palette = this->screen->hwdata->palette; |
813 return -1; | 815 |
816 if (!palette) | |
817 return 0; | |
818 | |
819 if (firstcolor > 255) | |
820 return 0; | |
821 | |
822 if (firstcolor + ncolors > 256) | |
823 ncolors = 256 - firstcolor; | |
824 | |
825 if (ncolors > 0) | |
826 { | |
827 int i; | |
828 DFBColor entries[ncolors]; | |
829 | |
830 for (i=0; i<ncolors; i++) | |
831 { | |
832 entries[i].a = 0xff; | |
833 entries[i].r = colors[i].r; | |
834 entries[i].g = colors[i].g; | |
835 entries[i].b = colors[i].b; | |
836 } | |
837 | |
838 palette->SetEntries (palette, entries, ncolors, firstcolor); | |
839 } | |
840 | |
841 return 1; | |
814 } | 842 } |
815 | 843 |
816 void DirectFB_VideoQuit(_THIS) | 844 void DirectFB_VideoQuit(_THIS) |
817 { | 845 { |
818 struct DirectFBEnumRect *rect = enumlist; | 846 struct DirectFBEnumRect *rect = enumlist; |
847 IDirectFBSurface *surface = this->screen->hwdata->surface; | |
848 IDirectFBPalette *palette = this->screen->hwdata->palette; | |
849 | |
850 if (palette) | |
851 palette->Release (palette); | |
852 | |
853 if (surface) | |
854 surface->Release (surface); | |
855 | |
856 this->screen->hwdata->surface = NULL; | |
857 this->screen->hwdata->palette = NULL; | |
819 | 858 |
820 if (HIDDEN->eventbuffer) | 859 if (HIDDEN->eventbuffer) |
821 { | 860 { |
822 HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer); | 861 HIDDEN->eventbuffer->Release (HIDDEN->eventbuffer); |
823 HIDDEN->eventbuffer = NULL; | 862 HIDDEN->eventbuffer = NULL; |