Mercurial > sdl-ios-xcode
diff src/video/SDL_surface.c @ 2266:e61ad15a205f
More work in progress integrating SDL_Surface and the new SDL_Texture API
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 18 Aug 2007 01:44:21 +0000 |
parents | 202ddfd1cfb1 |
children | c785543d1843 |
line wrap: on
line diff
--- a/src/video/SDL_surface.c Fri Aug 17 06:58:20 2007 +0000 +++ b/src/video/SDL_surface.c Sat Aug 18 01:44:21 2007 +0000 @@ -212,153 +212,251 @@ return 0; } -/* - * Set the color key in a blittable surface - */ -int -SDL_SetColorKey(SDL_Surface * surface, Uint32 flag, Uint32 key) +int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag) { - /* Sanity check the flag as it gets passed in */ - if (flag & SDL_SRCCOLORKEY) { - if (flag & (SDL_RLEACCEL | SDL_RLEACCELOK)) { - flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK); - } else { - flag = SDL_SRCCOLORKEY; - } - } else { - flag = 0; - } + Uint32 flags; - /* Optimize away operations that don't change anything */ - if ((flag == (surface->flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK))) && - (key == surface->map->ckey)) { - return (0); - } - - /* UnRLE surfaces before we change the colorkey */ - if (surface->flags & SDL_RLEACCEL) { - SDL_UnRLESurface(surface, 1); + if (!surface) { + return -1; } if (flag) { - surface->flags |= SDL_SRCCOLORKEY; - surface->map->ckey = key; - if (flag & SDL_RLEACCELOK) { - surface->flags |= SDL_RLEACCELOK; - } else { - surface->flags &= ~SDL_RLEACCELOK; - } + surface->flags |= SDL_RLEACCELOK; } else { - surface->flags &= ~(SDL_SRCCOLORKEY | SDL_RLEACCELOK); - surface->map->ckey = 0; + surface->flags &= ~SDL_RLEACCELOK; } - SDL_InvalidateMap(surface->map); - return (0); + if (surface->flags != flags) { + SDL_InvalidateMap(surface->map); + } + return 0; } -/* This function sets the alpha channel of a surface */ -int -SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, Uint8 value) +int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key) { - Uint32 oldflags = surface->flags; - Uint32 oldalpha = (surface->map->cmod >> 24); + int flags; - /* Sanity check the flag as it gets passed in */ - if (flag & SDL_SRCALPHA) { - if (flag & (SDL_RLEACCEL | SDL_RLEACCELOK)) { - flag = (SDL_SRCALPHA | SDL_RLEACCELOK); - } else { - flag = SDL_SRCALPHA; - } - } else { - flag = 0; + if (!surface) { + return -1; + } + + if (flag & SDL_RLEACCEL) { + SDL_SetSurfaceRLE(surface, 1); } - /* Optimize away operations that don't change anything */ - if ((flag == (surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK))) && - (!flag || value == oldalpha)) { - return (0); + flags = surface->map->info.flags; + if (flag) { + surface->map->info.flags |= SDL_COPY_COLORKEY; + surface->map->info.colorkey = key; + } else { + surface->map->info.flags &= ~SDL_COPY_COLORKEY; + } + if (surface->map->info.flags != flags) { + SDL_InvalidateMap(surface->map); + } + return 0; +} + +int SDL_SetSurfaceColorMod(SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b) +{ + int flags; + + if (!surface) { + return -1; } - if (!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL)) - SDL_UnRLESurface(surface, 1); + surface->map->info.r = r; + surface->map->info.g = g; + surface->map->info.b = b; - if (flag) { - surface->flags |= SDL_SRCALPHA; - surface->map->cmod &= 0x00FFFFFF; - surface->map->cmod |= ((Uint32) value << 24); - if (flag & SDL_RLEACCELOK) { - surface->flags |= SDL_RLEACCELOK; - } else { - surface->flags &= ~SDL_RLEACCELOK; - } + flags = surface->map->info.flags; + if (r != 0xFF || g != 0xFF || b != 0xFF) { + surface->map->info.flags |= SDL_COPY_MODULATE_COLOR; } else { - surface->flags &= ~SDL_SRCALPHA; - surface->map->cmod |= 0xFF000000; + surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR; } - /* - * The representation for software surfaces is independent of - * per-surface alpha, so no need to invalidate the blit mapping - * if just the alpha value was changed. (If either is 255, we still - * need to invalidate.) - */ - if (oldflags != surface->flags - || (((oldalpha + 1) ^ (value + 1)) & 0x100)) { + if (surface->map->info.flags != flags) { SDL_InvalidateMap(surface->map); } - return (0); + return 0; } -int -SDL_SetAlphaChannel(SDL_Surface * surface, Uint8 value) + +int SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 * r, Uint8 * g, Uint8 * b) { - int row, col; - int offset; - Uint8 *buf; - - if ((surface->format->Amask != 0xFF000000) && - (surface->format->Amask != 0x000000FF)) { - SDL_SetError("Unsupported surface alpha mask format"); + if (!surface) { return -1; } -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - if (surface->format->Amask == 0xFF000000) { - offset = 3; - } else { - offset = 0; + + if (r) { + *r = surface->map->info.r; + } + if (g) { + *g = surface->map->info.g; + } + if (b) { + *b = surface->map->info.b; } -#else - if (surface->format->Amask == 0xFF000000) { - offset = 0; - } else { - offset = 3; + return 0; +} + +int SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Uint8 alpha) +{ + int flags; + + if (!surface) { + return -1; } -#endif /* Byte ordering */ - /* Quickly set the alpha channel of an RGBA or ARGB surface */ - if (SDL_MUSTLOCK(surface)) { - if (SDL_LockSurface(surface) < 0) { - return -1; - } + surface->map->info.a = alpha; + + flags = surface->map->info.flags; + if (alpha != 0xFF) { + surface->map->info.flags |= SDL_COPY_MODULATE_ALPHA; + } else { + surface->map->info.flags &= ~SDL_COPY_MODULATE_ALPHA; + } + if (surface->map->info.flags != flags) { + SDL_InvalidateMap(surface->map); } - row = surface->h; - while (row--) { - col = surface->w; - buf = (Uint8 *) surface->pixels + row * surface->pitch + offset; - while (col--) { - *buf = value; - buf += 4; - } + return 0; +} + +int SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 * alpha) +{ + if (!surface) { + return -1; } - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); + + if (alpha) { + *alpha = surface->map->info.a; } return 0; } -/* - * Set the clipping rectangle for a blittable surface - */ +int SDL_SetSurfaceBlendMode(SDL_Surface *surface, int blendMode) +{ + int flags, status; + + if (!surface) { + return -1; + } + + status = 0; + flags = surface->map->info.flags; + surface->map->info.flags &= ~(SDL_COPY_MASK|SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD); + switch (blendMode) { + case SDL_TEXTUREBLENDMODE_NONE: + break; + case SDL_TEXTUREBLENDMODE_MASK: + surface->map->info.flags |= SDL_COPY_MASK; + break; + case SDL_TEXTUREBLENDMODE_BLEND: + surface->map->info.flags |= SDL_COPY_BLEND; + break; + case SDL_TEXTUREBLENDMODE_ADD: + surface->map->info.flags |= SDL_COPY_ADD; + break; + case SDL_TEXTUREBLENDMODE_MOD: + surface->map->info.flags |= SDL_COPY_MOD; + break; + default: + SDL_Unsupported(); + status = -1; + break; + } + + if (surface->map->info.flags != flags) { + SDL_InvalidateMap(surface->map); + } + return status; +} + +int SDL_GetSurfaceBlendMode(SDL_Surface *surface, int *blendMode) +{ + if (!surface) { + return -1; + } + + if (!blendMode) { + return 0; + } + + switch(surface->map->info.flags & (SDL_COPY_MASK|SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) { + case SDL_COPY_MASK: + *blendMode = SDL_TEXTUREBLENDMODE_MASK: + break; + case SDL_COPY_BLEND: + *blendMode = SDL_TEXTUREBLENDMODE_BLEND: + break; + case SDL_COPY_ADD: + *blendMode = SDL_TEXTUREBLENDMODE_ADD: + break; + case SDL_COPY_MOD: + *blendMode = SDL_TEXTUREBLENDMODE_MOD: + break; + default: + *blendMode = SDL_TEXTUREBLENDMODE_NONE: + break; + } + return 0; +} + +int SDL_SetSurfaceScaleMode(SDL_Surface *surface, int scaleMode) +{ + int flags, status; + + if (!surface) { + return -1; + } + + status = 0; + flags = surface->map->info.flags; + surface->map->info.flags &= ~(SDL_COPY_NEAREST); + switch (scaleMode) { + case SDL_TEXTURESCALEMODE_NONE: + break; + case SDL_TEXTURESCALEMODE_FAST: + surface->map->info.flags |= SDL_COPY_NEAREST; + break; + case SDL_TEXTURESCALEMODE_SLOW: + case SDL_TEXTURESCALEMODE_BEST: + SDL_Unsupported(); + surface->map->info.flags |= SDL_COPY_NEAREST; + status = -1; + break; + default: + SDL_Unsupported(); + status = -1; + break; + } + + if (surface->map->info.flags != flags) { + SDL_InvalidateMap(surface->map); + } + return status; +} + +int SDL_GetSurfaceScaleMode(SDL_Surface *surface, int *scaleMode) +{ + if (!surface) { + return -1; + } + + if (!scaleMode) { + return 0; + } + + switch(surface->map->info.flags & (SDL_COPY_LINEAR)) { + case SDL_COPY_LINEAR: + *scaleMode = SDL_TEXTURESCALEMODE_FAST: + break; + default: + *scaleMode = SDL_TEXTURESCALEMODE_NONE: + break; + } + return 0; +} + SDL_bool SDL_SetClipRect(SDL_Surface * surface, const SDL_Rect * rect) { @@ -557,9 +655,7 @@ SDL_PixelFormat * format, Uint32 flags) { SDL_Surface *convert; - Uint32 colorkey = 0; - Uint8 alpha = 0; - Uint32 surface_flags; + Uint32 copy_flags; SDL_Rect bounds; /* Check for empty destination palette! (results in empty image) */ @@ -578,8 +674,7 @@ } /* Create a new surface with the desired format */ - convert = SDL_CreateRGBSurface(flags, - surface->w, surface->h, + convert = SDL_CreateRGBSurface(0, surface->w, surface->h, format->BitsPerPixel, format->Rmask, format->Gmask, format->Bmask, format->Amask); @@ -595,26 +690,9 @@ convert->format->palette->ncolors = format->palette->ncolors; } - /* Save the original surface color key and alpha */ - surface_flags = surface->flags; - if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { - /* Convert colourkeyed surfaces to RGBA if requested */ - if ((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY && format->Amask) { - surface_flags &= ~SDL_SRCCOLORKEY; - } else { - colorkey = surface->map->ckey; - SDL_SetColorKey(surface, 0, 0); - } - } - if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { - /* Copy over the alpha channel to RGBA if requested */ - if (format->Amask) { - surface->flags &= ~SDL_SRCALPHA; - } else { - alpha = (Uint8) (surface->map->cmod >> 24); - SDL_SetAlpha(surface, 0, 0); - } - } + /* Save the original copy flags */ + copy_flags = surface->map->info.flags; + surface->map->info.flags = 0; /* Copy over the image data */ bounds.x = 0; @@ -624,30 +702,25 @@ SDL_LowerBlit(surface, &bounds, convert, &bounds); /* Clean up the original surface, and update converted surface */ - if (convert != NULL) { - SDL_SetClipRect(convert, &surface->clip_rect); - } - if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { - Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK); - if (convert != NULL) { - Uint8 keyR, keyG, keyB; + SDL_SetClipRect(convert, &surface->clip_rect); + if (copy_flags & SDL_COPY_COLORKEY) { + Uint8 keyR, keyG, keyB, keyA; - SDL_GetRGB(colorkey, surface->format, &keyR, &keyG, &keyB); - SDL_SetColorKey(convert, cflags | (flags & SDL_RLEACCELOK), - SDL_MapRGB(convert->format, keyR, keyG, keyB)); - } - SDL_SetColorKey(surface, cflags, colorkey); + SDL_GetRGBA(colorkey, surface->format, &keyR, &keyG, &keyB, &keyA); + SDL_SetColorKey(convert, 1, + SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA)); } - if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { - Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK); - if (convert != NULL) { - SDL_SetAlpha(convert, aflags | (flags & SDL_RLEACCELOK), alpha); - } - if (format->Amask) { - surface->flags |= SDL_SRCALPHA; - } else { - SDL_SetAlpha(surface, aflags, alpha); - } + convert->map->info.r = surface->map->info.r; + convert->map->info.g = surface->map->info.g; + convert->map->info.b = surface->map->info.b; + convert->map->info.a = surface->map->info.a; + convert->map->info.flags = copy_flags; + surface->map->info.flags = copy_flags; + + /* Enable alpha blending by default if the new surface has an + * alpha channel or alpha modulation */ + if (format->Amask || (copy_flags & SDL_COPY_MODULATE_ALPHA)) { + SDL_SetSurfaceBlendMode(convert, SDL_TEXTUREBLENDMODE_BLEND); } /* We're ready to go! */