--- 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;