| | |
| | | return (pixel); |
| | | } |
| | | |
| | | /* Tell whether palette is opaque, and if it has an alpha_channel */ |
| | | void |
| | | SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel) |
| | | { |
| | | int i; |
| | | |
| | | { |
| | | SDL_bool all_opaque = SDL_TRUE; |
| | | for (i = 0; i < pal->ncolors; i++) { |
| | | Uint8 alpha_value = pal->colors[i].a; |
| | | if (alpha_value != SDL_ALPHA_OPAQUE) { |
| | | all_opaque = SDL_FALSE; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (all_opaque) { |
| | | /* Palette is opaque, with an alpha channel */ |
| | | *is_opaque = SDL_TRUE; |
| | | *has_alpha_channel = SDL_TRUE; |
| | | return; |
| | | } |
| | | } |
| | | |
| | | { |
| | | SDL_bool all_transparent = SDL_TRUE; |
| | | for (i = 0; i < pal->ncolors; i++) { |
| | | Uint8 alpha_value = pal->colors[i].a; |
| | | if (alpha_value != SDL_ALPHA_TRANSPARENT) { |
| | | all_transparent = SDL_FALSE; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (all_transparent) { |
| | | /* Palette is opaque, without an alpha channel */ |
| | | *is_opaque = SDL_TRUE; |
| | | *has_alpha_channel = SDL_FALSE; |
| | | return; |
| | | } |
| | | } |
| | | |
| | | /* Palette has alpha values */ |
| | | *is_opaque = SDL_FALSE; |
| | | *has_alpha_channel = SDL_TRUE; |
| | | } |
| | | |
| | | |
| | | /* Find the opaque pixel value corresponding to an RGB triple */ |
| | | Uint32 |
| | | SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b) |
| | |
| | | return (map); |
| | | } |
| | | |
| | | |
| | | typedef struct SDL_ListNode |
| | | { |
| | | void *entry; |
| | | struct SDL_ListNode *next; |
| | | } SDL_ListNode; |
| | | |
| | | void |
| | | SDL_InvalidateAllBlitMap(SDL_Surface *surface) |
| | | { |
| | | SDL_ListNode *l = surface->list_blitmap; |
| | | |
| | | surface->list_blitmap = NULL; |
| | | |
| | | while (l) { |
| | | SDL_ListNode *tmp = l; |
| | | SDL_InvalidateMap((SDL_BlitMap *)l->entry); |
| | | l = l->next; |
| | | SDL_free(tmp); |
| | | } |
| | | } |
| | | |
| | | static void SDL_ListAdd(SDL_ListNode **head, void *ent); |
| | | static void SDL_ListRemove(SDL_ListNode **head, void *ent); |
| | | |
| | | void |
| | | SDL_ListAdd(SDL_ListNode **head, void *ent) |
| | | { |
| | | SDL_ListNode *node = SDL_malloc(sizeof (*node)); |
| | | |
| | | if (node == NULL) { |
| | | SDL_OutOfMemory(); |
| | | return; |
| | | } |
| | | |
| | | node->entry = ent; |
| | | node->next = *head; |
| | | *head = node; |
| | | } |
| | | |
| | | void |
| | | SDL_ListRemove(SDL_ListNode **head, void *ent) |
| | | { |
| | | SDL_ListNode **ptr = head; |
| | | |
| | | while (*ptr) { |
| | | if ((*ptr)->entry == ent) { |
| | | SDL_ListNode *tmp = *ptr; |
| | | *ptr = (*ptr)->next; |
| | | SDL_free(tmp); |
| | | return; |
| | | } |
| | | ptr = &(*ptr)->next; |
| | | } |
| | | } |
| | | |
| | | void |
| | | SDL_InvalidateMap(SDL_BlitMap * map) |
| | | { |
| | |
| | | return; |
| | | } |
| | | if (map->dst) { |
| | | /* Release our reference to the surface - see the note below */ |
| | | if (--map->dst->refcount <= 0) { |
| | | SDL_FreeSurface(map->dst); |
| | | } |
| | | /* Un-register from the destination surface */ |
| | | SDL_ListRemove((SDL_ListNode **)&(map->dst->list_blitmap), map); |
| | | } |
| | | map->dst = NULL; |
| | | map->src_palette_version = 0; |
| | |
| | | map->dst = dst; |
| | | |
| | | if (map->dst) { |
| | | /* Keep a reference to this surface so it doesn't get deleted |
| | | while we're still pointing at it. |
| | | |
| | | A better method would be for the destination surface to keep |
| | | track of surfaces that are mapped to it and automatically |
| | | invalidate them when it is freed, but this will do for now. |
| | | */ |
| | | ++map->dst->refcount; |
| | | /* Register BlitMap to the destination surface, to be invalidated when needed */ |
| | | SDL_ListAdd((SDL_ListNode **)&(map->dst->list_blitmap), map); |
| | | } |
| | | |
| | | if (dstfmt->palette) { |