Mercurial > sdl-ios-xcode
changeset 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 | 265bb136af92 |
children | c785543d1843 |
files | include/SDL_compat.h include/SDL_video.h src/SDL_compat.c src/video/SDL_RLEaccel.c src/video/SDL_blit.c src/video/SDL_blit.h src/video/SDL_surface.c src/video/SDL_video.c |
diffstat | 8 files changed, 506 insertions(+), 365 deletions(-) [+] |
line wrap: on
line diff
--- a/include/SDL_compat.h Fri Aug 17 06:58:20 2007 +0000 +++ b/include/SDL_compat.h Sat Aug 18 01:44:21 2007 +0000 @@ -37,6 +37,8 @@ #endif #define SDL_SWSURFACE 0x00000000 /* Not used */ +//#define SDL_SRCALPHA 0x00010000 +//#define SDL_SRCCOLORKEY 0x00020000 #define SDL_ANYFORMAT 0x00100000 #define SDL_HWPALETTE 0x00200000 #define SDL_DOUBLEBUF 0x00400000 @@ -146,6 +148,8 @@ extern DECLSPEC void SDLCALL SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h); extern DECLSPEC int SDLCALL SDL_Flip(SDL_Surface * screen); +extern DECLSPEC int SDLCALL SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, + Uint8 alpha); extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormat(SDL_Surface * surface); extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormatAlpha(SDL_Surface * surface);
--- a/include/SDL_video.h Fri Aug 17 06:58:20 2007 +0000 +++ b/include/SDL_video.h Sat Aug 18 01:44:21 2007 +0000 @@ -265,10 +265,7 @@ /* These are the currently supported flags for the SDL_surface */ /* Used internally (read-only) */ #define SDL_PREALLOC 0x00000001 /* Surface uses preallocated memory */ -#define SDL_SRCALPHA 0x00000004 /* Blit uses source alpha blending */ -#define SDL_SRCCOLORKEY 0x00000008 /* Blit uses a source color key */ -#define SDL_RLEACCELOK 0x00000010 /* Private flag */ -#define SDL_RLEACCEL 0x00000020 /* Surface is RLE encoded */ +#define SDL_RLEACCEL 0x00000001 /* Surface is RLE encoded */ /* Evaluates to true if the surface needs to be locked before access */ #define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0) @@ -1401,34 +1398,157 @@ SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) /* - * Sets the color key (transparent pixel) in a blittable surface. - * If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), - * 'key' will be the transparent pixel in the source image of a blit. - * SDL_RLEACCEL requests RLE acceleration for the surface if present, - * and removes RLE acceleration if absent. - * If 'flag' is 0, this function clears any current color key. - * This function returns 0, or -1 if there was an error. + * \fn int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag) + * + * \brief Sets the RLE acceleration hint for a surface. + * + * \return 0 on success, or -1 if the surface is not valid + * + * \note If RLE is enabled, colorkey and alpha blending blits are much faster, + * but the surface must be locked before directly accessing the pixels. */ -extern DECLSPEC int SDLCALL SDL_SetColorKey - (SDL_Surface * surface, Uint32 flag, Uint32 key); +extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface *surface, int flag); /* - * This function sets the alpha value for the entire surface, as opposed to - * using the alpha component of each pixel. This value measures the range - * of transparency of the surface, 0 being completely transparent to 255 - * being completely opaque. An 'alpha' value of 255 causes blits to be - * opaque, the source pixels copied to the destination (the default). Note - * that per-surface alpha can be combined with colorkey transparency. + * \fn int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key) + * + * \brief Sets the color key (transparent pixel) in a blittable surface. + * + * \param surface The surface to update + * \param flag Non-zero to enable colorkey and 0 to disable colorkey + * \param key The transparent pixel in the native surface format + * + * \return 0 on success, or -1 if the surface is not valid + */ +extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key); + +/** + * \fn int SDL_SetSurfaceColorMod(SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b) + * + * \brief Set an additional color value used in blit operations + * + * \param surface The surface to update + * \param r The red source color value multiplied into blit operations + * \param g The green source color value multiplied into blit operations + * \param b The blue source color value multiplied into blit operations + * + * \return 0 on success, or -1 if the surface is not valid + * + * \sa SDL_GetSurfaceColorMod() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface *surface, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * \fn int SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 *r, Uint8 *g, Uint8 *b) + * + * \brief Get the additional color value used in blit operations + * + * \param surface The surface to query + * \param r A pointer filled in with the source red color value + * \param g A pointer filled in with the source green color value + * \param b A pointer filled in with the source blue color value + * + * \return 0 on success, or -1 if the surface is not valid + * + * \sa SDL_SetSurfaceColorMod() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface *surface, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * \fn int SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Uint8 alpha) + * + * \brief Set an additional alpha value used in blit operations + * + * \param surface The surface to update + * \param alpha The source alpha value multiplied into blit operations. + * + * \return 0 on success, or -1 if the surface is not valid + * + * \sa SDL_GetSurfaceAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface *surface, + Uint8 alpha); + +/** + * \fn int SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 *alpha) + * + * \brief Get the additional alpha value used in blit operations * - * If 'flag' is 0, alpha blending is disabled for the surface. - * If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface. - * OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the - * surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed. + * \param surface The surface to query + * \param alpha A pointer filled in with the source alpha value + * + * \return 0 on success, or -1 if the surface is not valid + * + * \sa SDL_SetSurfaceAlphaMod() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface *surface, + Uint8 * alpha); + +/** + * \fn int SDL_SetSurfaceBlendMode(SDL_Surface *surface, int blendMode) + * + * \brief Set the blend mode used for blit operations + * + * \param surface The surface to update + * \param blendMode SDL_TextureBlendMode to use for blit blending + * + * \return 0 on success, or -1 if the parameters are not valid + * + * \sa SDL_GetSurfaceBlendMode() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface *surface, + int blendMode); + +/** + * \fn int SDL_GetSurfaceBlendMode(SDL_Surface *surface, int *blendMode) + * + * \brief Get the blend mode used for blit operations + * + * \param surface The surface to query + * \param blendMode A pointer filled in with the current blend mode + * + * \return 0 on success, or -1 if the surface is not valid * - * The 'alpha' parameter is ignored for surfaces that have an alpha channel. + * \sa SDL_SetSurfaceBlendMode() */ -extern DECLSPEC int SDLCALL SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, - Uint8 alpha); +extern DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface *surface, + int *blendMode); + +/** + * \fn int SDL_SetSurfaceScaleMode(SDL_Surface *surface, int scaleMode) + * + * \brief Set the scale mode used for blit operations + * + * \param surface The surface to update + * \param scaleMode SDL_TextureScaleMode to use for blit scaling + * + * \return 0 on success, or -1 if the surface is not valid or the scale mode is not supported + * + * \note If the scale mode is not supported, the closest supported mode is chosen. Currently only SDL_TEXTURESCALEMODE_FAST is supported on surfaces. + * + * \sa SDL_GetSurfaceScaleMode() + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceScaleMode(SDL_Surface *surface, + int scaleMode); + +/** + * \fn int SDL_GetSurfaceScaleMode(SDL_Surface *surface, int *scaleMode) + * + * \brief Get the scale mode used for blit operations + * + * \param surface The surface to query + * \param scaleMode A pointer filled in with the current scale mode + * + * \return 0 on success, or -1 if the surface is not valid + * + * \sa SDL_SetSurfaceScaleMode() + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceScaleMode(SDL_Surface *surface, + int *scaleMode); /* * Sets the clipping rectangle for the destination surface in a blit.
--- a/src/SDL_compat.c Fri Aug 17 06:58:20 2007 +0000 +++ b/src/SDL_compat.c Sat Aug 18 01:44:21 2007 +0000 @@ -589,6 +589,22 @@ return SDL_PublicSurface; } +int +SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, Uint8 value) +{ + if (flag & SDL_RLEACCEL) { + SDL_SetSurfaceRLE(surface, 1); + } + if (flag) { + SDL_SetSurfaceAlphaMod(surface, value); + SDL_SetSurfaceBlendMode(surface, SDL_TEXTUREBLENDMODE_BLEND); + } else { + SDL_SetSurfaceAlphaMod(surface, 0xFF); + SDL_SetSurfaceBlendMode(surface, SDL_TEXTUREBLENDMODE_NONE); + } + return 0; +} + SDL_Surface * SDL_DisplayFormat(SDL_Surface * surface) { @@ -600,15 +616,7 @@ } /* Set the flags appropriate for copying to display surface */ - flags = SDL_SWSURFACE; -#ifdef AUTORLE_DISPLAYFORMAT - flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA)); - flags |= SDL_RLEACCELOK; -#else - flags |= - surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK); -#endif - return SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags); + return SDL_ConvertSurface(surface, SDL_PublicSurface->format, SDL_RLEACCELOK); } SDL_Surface * @@ -658,8 +666,7 @@ break; } format = SDL_AllocFormat(32, rmask, gmask, bmask, amask); - flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); - converted = SDL_ConvertSurface(surface, format, flags); + converted = SDL_ConvertSurface(surface, format, SDL_RLEACCELOK); SDL_FreeFormat(format); return converted; }
--- a/src/video/SDL_RLEaccel.c Fri Aug 17 06:58:20 2007 +0000 +++ b/src/video/SDL_RLEaccel.c Sat Aug 18 01:44:21 2007 +0000 @@ -905,8 +905,7 @@ } } - alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA - ? src->map->info.a : 255; + alpha = src->map->info.a; /* if left or right edge clipping needed, call clip blit */ if (srcrect->x || srcrect->w != src->w) { RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha); @@ -1803,7 +1802,7 @@ int SDL_RLESurface(SDL_Surface * surface) { - int retcode; + int flags; /* Clear any previous RLE conversion */ if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { @@ -1812,35 +1811,45 @@ /* We don't support RLE encoding of bitmaps */ if (surface->format->BitsPerPixel < 8) { - return (-1); + return -1; } - /* Lock the surface if it's in hardware */ - if (SDL_MUSTLOCK(surface)) { - if (SDL_LockSurface(surface) < 0) { - return (-1); - } + /* Make sure the pixels are available */ + if (!surface->pixels) { + return -1; + } + + /* If we don't have colorkey or blending, nothing to do... */ + flags = surface->map->info.flags; + if(!(flags & (SDL_COPY_COLORKEY|SDL_COPY_BLEND))) { + return -1; } - /* Encode */ - if ((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { - retcode = RLEColorkeySurface(surface); - } else { - if ((surface->flags & SDL_SRCALPHA) == SDL_SRCALPHA - && surface->format->Amask != 0) - retcode = RLEAlphaSurface(surface); - else - retcode = -1; /* no RLE for per-surface alpha sans ckey */ + /* Pass on combinations not supported */ + if ((flags & SDL_COPY_MODULATE_COLOR) || + (flags & (SDL_COPY_ADD|SDL_COPY_MOD)) || + (flags & SDL_COPY_NEAREST)) { + return -1; } - /* Unlock the surface if it's in hardware */ - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); + /* Encode and set up the blit */ + if (!surface->format->Amask || !(flags & SDL_COPY_BLEND)) { + if (!surface->map->identity) { + return -1; + } + if (RLEColorkeySurface(surface) < 0) { + return -1; + } + surface->map->blit = SDL_RLEBlit; + surface->map->info.flags |= SDL_COPY_RLE_COLORKEY; + } else { + if (RLEAlphaSurface(surface) < 0) { + return -1; + } + surface->map->blit = SDL_RLEAlphaBlit; + surface->map->info.flags |= SDL_COPY_RLE_ALPHAKEY; } - if (retcode < 0) - return -1; - /* The surface is now accelerated */ surface->flags |= SDL_RLEACCEL; @@ -1931,13 +1940,12 @@ void SDL_UnRLESurface(SDL_Surface * surface, int recode) { - if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { + if (surface->flags & SDL_RLEACCEL) { surface->flags &= ~SDL_RLEACCEL; if (recode && !(surface->flags & SDL_PREALLOC)) { - if ((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { + if (surface->map->info.flags & SDL_COPY_RLE_COLORKEY) { SDL_Rect full; - unsigned alpha_flag; /* re-create the original surface */ surface->pixels = SDL_malloc(surface->h * surface->pitch); @@ -1954,10 +1962,7 @@ full.x = full.y = 0; full.w = surface->w; full.h = surface->h; - alpha_flag = surface->flags & SDL_SRCALPHA; - surface->flags &= ~SDL_SRCALPHA; /* opaque blit */ SDL_RLEBlit(surface, &full, surface, &full); - surface->flags |= alpha_flag; } else { if (!UnRLEAlpha(surface)) { /* Oh crap... */ @@ -1966,8 +1971,9 @@ } } } + surface->map->info.flags &= (SDL_COPY_RLE_COLORKEY|SDL_COPY_RLE_ALPHAKEY); - if (surface->map && surface->map->data) { + if (surface->map->data) { SDL_free(surface->map->data); surface->map->data = NULL; }
--- a/src/video/SDL_blit.c Fri Aug 17 06:58:20 2007 +0000 +++ b/src/video/SDL_blit.c Sat Aug 18 01:44:21 2007 +0000 @@ -206,7 +206,8 @@ SDL_CalculateBlit(SDL_Surface * surface) { SDL_BlitFunc blit = NULL; - SDL_Surface *dst = surface->map->dst; + SDL_BlitMap *map = surface->map; + SDL_Surface *dst = map->dst; Uint32 src_format; Uint32 dst_format; @@ -214,67 +215,48 @@ if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { SDL_UnRLESurface(surface, 1); } - surface->map->blit = NULL; - surface->map->info.src_fmt = surface->format; - surface->map->info.src_pitch = surface->pitch; - surface->map->info.dst_fmt = dst->format; - surface->map->info.dst_pitch = dst->pitch; + map->blit = SDL_SoftBlit; + map->info.src_fmt = surface->format; + map->info.src_pitch = surface->pitch; + map->info.dst_fmt = dst->format; + map->info.dst_pitch = dst->pitch; + /* See if we can do RLE acceleration */ + if (surface->flags & SDL_RLEACCELOK) { + if (SDL_RLESurface(surface) == 0) { + return 0; + } + } + + /* Choose a standard blit function */ src_format = SDL_MasksToPixelFormatEnum(surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask); dst_format = SDL_MasksToPixelFormatEnum(dst->format->BitsPerPixel, dst->format->Rmask, dst->format->Gmask, dst->format->Bmask, dst->format->Amask); - /* Check for special "identity" case -- copy blit */ - if (surface->map->identity && !surface->map->info.flags) { + if (map->identity && !map->info.flags) { /* Handle overlapping blits on the same surface */ if (surface == dst) { blit = SDL_BlitCopyOverlap; } else { blit = SDL_BlitCopy; } + } else if (surface->format->BitsPerPixel < 8) { + blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_BlitFuncTable0); + } else if (surface->format->BytesPerPixel == 1) { + blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_BlitFuncTable1); } else { - if (surface->format->BitsPerPixel < 8) { - blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_BlitFuncTable0); - } else { - switch (surface->format->BytesPerPixel) { - case 1: - blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_BlitFuncTable1); - break; - case 2: - case 3: - case 4: - blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_BlitFuncTableN); - break; - } - } + blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_BlitFuncTableN); } if (blit == NULL) { - blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_GeneratedBlitFuncTable); + blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_GeneratedBlitFuncTable); } /* Make sure we have a blit function */ if (blit == NULL) { - SDL_InvalidateMap(surface->map); + SDL_InvalidateMap(map); SDL_SetError("Blit combination not supported"); return (-1); } - /* Choose software blitting function */ - if ((surface->flags & SDL_RLEACCELOK) && !(surface->map->flags & () { - if (surface->map->identity && (surface->map->flags & SDL_COPY_COLORKEY) - && (blit_index == 1 - || (blit_index == 3 && !surface->format->Amask))) { - if (SDL_RLESurface(surface) == 0) - surface->map->blit = SDL_RLEBlit; - } else if (blit_index == 2 && surface->format->Amask) { - if (SDL_RLESurface(surface) == 0) - surface->map->blit = SDL_RLEAlphaBlit; - } - } - - if (surface->map->blit == NULL) { - surface->map->blit = SDL_SoftBlit; - surface->map->data = blit; - } return (0); }
--- a/src/video/SDL_blit.h Fri Aug 17 06:58:20 2007 +0000 +++ b/src/video/SDL_blit.h Sat Aug 18 01:44:21 2007 +0000 @@ -41,23 +41,26 @@ #include "SDL_endian.h" /* SDL blit copy flags */ -#define SDL_COPY_MODULATE_COLOR 0x0001 -#define SDL_COPY_MODULATE_ALPHA 0x0002 -#define SDL_COPY_MASK 0x0010 -#define SDL_COPY_BLEND 0x0020 -#define SDL_COPY_ADD 0x0040 -#define SDL_COPY_MOD 0x0080 -#define SDL_COPY_COLORKEY 0x0100 -#define SDL_COPY_NEAREST 0x0200 +#define SDL_COPY_MODULATE_COLOR 0x00000001 +#define SDL_COPY_MODULATE_ALPHA 0x00000002 +#define SDL_COPY_MASK 0x00000010 +#define SDL_COPY_BLEND 0x00000020 +#define SDL_COPY_ADD 0x00000040 +#define SDL_COPY_MOD 0x00000080 +#define SDL_COPY_COLORKEY 0x00000100 +#define SDL_COPY_NEAREST 0x00000200 +#define SDL_COPY_RLE_DESIRED 0x00001000 +#define SDL_COPY_RLE_COLORKEY 0x00002000 +#define SDL_COPY_RLE_ALPHAKEY 0x00004000 /* SDL blit CPU flags */ -#define SDL_CPU_ANY 0x0000 -#define SDL_CPU_MMX 0x0001 -#define SDL_CPU_3DNOW 0x0002 -#define SDL_CPU_SSE 0x0004 -#define SDL_CPU_SSE2 0x0008 -#define SDL_CPU_ALTIVEC_PREFETCH 0x0010 -#define SDL_CPU_ALTIVEC_NOPREFETCH 0x0020 +#define SDL_CPU_ANY 0x00000000 +#define SDL_CPU_MMX 0x00000001 +#define SDL_CPU_3DNOW 0x00000002 +#define SDL_CPU_SSE 0x00000004 +#define SDL_CPU_SSE2 0x00000008 +#define SDL_CPU_ALTIVEC_PREFETCH 0x00000010 +#define SDL_CPU_ALTIVEC_NOPREFETCH 0x00000020 typedef struct { Uint8 *src;
--- 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! */
--- a/src/video/SDL_video.c Fri Aug 17 06:58:20 2007 +0000 +++ b/src/video/SDL_video.c Sat Aug 18 01:44:21 2007 +0000 @@ -1535,8 +1535,7 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface) { SDL_TextureID textureID; - Uint32 surface_flags = surface->flags; - SDL_PixelFormat *fmt = surface->format; + SDL_PixelFormat *fmt; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; @@ -1544,6 +1543,7 @@ SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface"); return 0; } + fmt = surface->format; if (format) { if (!SDL_PixelFormatEnumToMasks @@ -1552,7 +1552,7 @@ return 0; } } else { - if (fmt->Amask || !(surface_flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA))) { + if (surface->format->Amask || !(flags & (SDL_COPY_COLORKEY|SDL_COPY_MASK|SDL_COPY_BLEND))) { bpp = fmt->BitsPerPixel; Rmask = fmt->Rmask; Gmask = fmt->Gmask; @@ -1595,92 +1595,38 @@ surface->pitch); } } else { - Uint32 cmod; - SDL_Rect bounds; - SDL_Surface dst; + SDL_PixelFormat *dst_fmt; + SDL_Surface *dst = NULL; /* Set up a destination surface for the texture update */ - SDL_zero(dst); - dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); - if (!dst.format) { - SDL_DestroyTexture(textureID); - return 0; - } - dst.w = surface->w; - dst.h = surface->h; - dst.pitch = SDL_CalculatePitch(&dst); - dst.pixels = SDL_malloc(dst.h * dst.pitch); - if (!dst.pixels) { - SDL_DestroyTexture(textureID); - SDL_FreeFormat(dst.format); - SDL_OutOfMemory(); - return 0; - } - - /* Copy the palette if any */ - if (SDL_ISPIXELFORMAT_INDEXED(format)) { - if (fmt->palette) { - SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, - fmt->palette->ncolors); - SDL_SetSurfacePalette(&dst, fmt->palette); - } else { - dst.format->palette = - SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format))); - if (!dst.format->palette) { - SDL_DestroyTexture(textureID); - SDL_FreeFormat(dst.format); - return 0; + dst_fmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); + if (dst_fmt) { + if (SDL_ISPIXELFORMAT_INDEXED(format)) { + dst_fmt->palette = SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format))); + if (dst_fmt->palette) { + if (fmt->palette) { +fixme + } else { + SDL_DitherColors(dst_fmt->palette->colors, SDL_BITSPERPIXEL(format)); + } } - SDL_DitherColors(dst.format->palette->colors, - SDL_BITSPERPIXEL(format)); + if (fmt->palette) { + dst_fmt->palette = fmt->palette; + } else { + } } - } - /* Make the texture transparent if the surface has colorkey */ - if (surface_flags & SDL_SRCCOLORKEY) { - int row; - int length = dst.w * dst.format->BytesPerPixel; - Uint8 *p = (Uint8 *) dst.pixels; - for (row = 0; row < dst.h; ++row) { - SDL_memset(p, 0, length); - p += dst.pitch; + cvt = SDL_ConvertSurface(surface, fmt, 0); + if (cvt) { + SDL_UpdateTexture(textureID, NULL, cvt->pixels, cvt->pitch); + SDL_FreeSurface(cvt); } - } - - /* Copy over the alpha channel */ - cmod = surface->map->cmod; - if (surface_flags & SDL_SRCALPHA) { - if (fmt->Amask) { - surface->flags &= ~SDL_SRCALPHA; - } else { - /* FIXME: Need to make sure the texture has an alpha channel - * and copy 'alpha' into the texture alpha channel. - */ - SDL_SetAlpha(surface, 0, 0); - } + SDL_FreeFormat(fmt); } - - /* Copy over the image data */ - bounds.x = 0; - bounds.y = 0; - bounds.w = surface->w; - bounds.h = surface->h; - SDL_LowerBlit(surface, &bounds, &dst, &bounds); + } - /* Clean up the original surface */ - if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) { - Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK); - if (fmt->Amask) { - surface->flags |= SDL_SRCALPHA; - } else { - SDL_SetAlpha(surface, aflags, (cmod >> 24)); - } - } - - /* Update the texture */ - SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch); - SDL_free(dst.pixels); - SDL_FreeFormat(dst.format); + if (SDL_ISPIXELFORMAT_INDEXED(format) && fmt->palette) { + SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, fmt->palette->ncolors); } return textureID;