More work in progress integrating SDL_Surface and the new SDL_Texture API
authorSam Lantinga <slouken@libsdl.org>
Sat, 18 Aug 2007 01:44:21 +0000
changeset 2266e61ad15a205f
parent 2265 265bb136af92
child 2267 c785543d1843
More work in progress integrating SDL_Surface and the new SDL_Texture API
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
     1.1 --- a/include/SDL_compat.h	Fri Aug 17 06:58:20 2007 +0000
     1.2 +++ b/include/SDL_compat.h	Sat Aug 18 01:44:21 2007 +0000
     1.3 @@ -37,6 +37,8 @@
     1.4  #endif
     1.5  
     1.6  #define SDL_SWSURFACE       0x00000000  /* Not used */
     1.7 +//#define SDL_SRCALPHA        0x00010000
     1.8 +//#define SDL_SRCCOLORKEY     0x00020000
     1.9  #define SDL_ANYFORMAT       0x00100000
    1.10  #define SDL_HWPALETTE       0x00200000
    1.11  #define SDL_DOUBLEBUF       0x00400000
    1.12 @@ -146,6 +148,8 @@
    1.13  extern DECLSPEC void SDLCALL SDL_UpdateRect(SDL_Surface * screen, Sint32 x,
    1.14                                              Sint32 y, Uint32 w, Uint32 h);
    1.15  extern DECLSPEC int SDLCALL SDL_Flip(SDL_Surface * screen);
    1.16 +extern DECLSPEC int SDLCALL SDL_SetAlpha(SDL_Surface * surface, Uint32 flag,
    1.17 +                                         Uint8 alpha);
    1.18  extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormat(SDL_Surface * surface);
    1.19  extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormatAlpha(SDL_Surface *
    1.20                                                              surface);
     2.1 --- a/include/SDL_video.h	Fri Aug 17 06:58:20 2007 +0000
     2.2 +++ b/include/SDL_video.h	Sat Aug 18 01:44:21 2007 +0000
     2.3 @@ -265,10 +265,7 @@
     2.4  /* These are the currently supported flags for the SDL_surface */
     2.5  /* Used internally (read-only) */
     2.6  #define SDL_PREALLOC        0x00000001  /* Surface uses preallocated memory */
     2.7 -#define SDL_SRCALPHA        0x00000004  /* Blit uses source alpha blending */
     2.8 -#define SDL_SRCCOLORKEY     0x00000008  /* Blit uses a source color key */
     2.9 -#define SDL_RLEACCELOK      0x00000010  /* Private flag */
    2.10 -#define SDL_RLEACCEL        0x00000020  /* Surface is RLE encoded */
    2.11 +#define SDL_RLEACCEL        0x00000001  /* Surface is RLE encoded */
    2.12  
    2.13  /* Evaluates to true if the surface needs to be locked before access */
    2.14  #define SDL_MUSTLOCK(S)	(((S)->flags & SDL_RLEACCEL) != 0)
    2.15 @@ -1401,34 +1398,157 @@
    2.16  		SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1)
    2.17  
    2.18  /*
    2.19 - * Sets the color key (transparent pixel) in a blittable surface.
    2.20 - * If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), 
    2.21 - * 'key' will be the transparent pixel in the source image of a blit.
    2.22 - * SDL_RLEACCEL requests RLE acceleration for the surface if present,
    2.23 - * and removes RLE acceleration if absent.
    2.24 - * If 'flag' is 0, this function clears any current color key.
    2.25 - * This function returns 0, or -1 if there was an error.
    2.26 + * \fn int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag)
    2.27 + *
    2.28 + * \brief Sets the RLE acceleration hint for a surface.
    2.29 + *
    2.30 + * \return 0 on success, or -1 if the surface is not valid
    2.31 + *
    2.32 + * \note If RLE is enabled, colorkey and alpha blending blits are much faster,
    2.33 + *       but the surface must be locked before directly accessing the pixels.
    2.34   */
    2.35 -extern DECLSPEC int SDLCALL SDL_SetColorKey
    2.36 -    (SDL_Surface * surface, Uint32 flag, Uint32 key);
    2.37 +extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface *surface, int flag);
    2.38  
    2.39  /*
    2.40 - * This function sets the alpha value for the entire surface, as opposed to
    2.41 - * using the alpha component of each pixel. This value measures the range
    2.42 - * of transparency of the surface, 0 being completely transparent to 255
    2.43 - * being completely opaque. An 'alpha' value of 255 causes blits to be
    2.44 - * opaque, the source pixels copied to the destination (the default). Note
    2.45 - * that per-surface alpha can be combined with colorkey transparency.
    2.46 + * \fn int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key)
    2.47   *
    2.48 - * If 'flag' is 0, alpha blending is disabled for the surface.
    2.49 - * If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface.
    2.50 - * OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the
    2.51 - * surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed.
    2.52 + * \brief Sets the color key (transparent pixel) in a blittable surface.
    2.53   *
    2.54 - * The 'alpha' parameter is ignored for surfaces that have an alpha channel.
    2.55 + * \param surface The surface to update
    2.56 + * \param flag Non-zero to enable colorkey and 0 to disable colorkey 
    2.57 + * \param key The transparent pixel in the native surface format
    2.58 + *
    2.59 + * \return 0 on success, or -1 if the surface is not valid
    2.60   */
    2.61 -extern DECLSPEC int SDLCALL SDL_SetAlpha(SDL_Surface * surface, Uint32 flag,
    2.62 -                                         Uint8 alpha);
    2.63 +extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);
    2.64 +
    2.65 +/**
    2.66 + * \fn int SDL_SetSurfaceColorMod(SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b)
    2.67 + *
    2.68 + * \brief Set an additional color value used in blit operations
    2.69 + *
    2.70 + * \param surface The surface to update
    2.71 + * \param r The red source color value multiplied into blit operations
    2.72 + * \param g The green source color value multiplied into blit operations
    2.73 + * \param b The blue source color value multiplied into blit operations
    2.74 + *
    2.75 + * \return 0 on success, or -1 if the surface is not valid
    2.76 + *
    2.77 + * \sa SDL_GetSurfaceColorMod()
    2.78 + */
    2.79 +extern DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface *surface,
    2.80 +                                                   Uint8 r, Uint8 g, Uint8 b);
    2.81 +
    2.82 +
    2.83 +/**
    2.84 + * \fn int SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 *r, Uint8 *g, Uint8 *b)
    2.85 + *
    2.86 + * \brief Get the additional color value used in blit operations
    2.87 + *
    2.88 + * \param surface The surface to query
    2.89 + * \param r A pointer filled in with the source red color value
    2.90 + * \param g A pointer filled in with the source green color value
    2.91 + * \param b A pointer filled in with the source blue color value
    2.92 + *
    2.93 + * \return 0 on success, or -1 if the surface is not valid
    2.94 + *
    2.95 + * \sa SDL_SetSurfaceColorMod()
    2.96 + */
    2.97 +extern DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface *surface,
    2.98 +                                                   Uint8 * r, Uint8 * g,
    2.99 +                                                   Uint8 * b);
   2.100 +
   2.101 +/**
   2.102 + * \fn int SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Uint8 alpha)
   2.103 + *
   2.104 + * \brief Set an additional alpha value used in blit operations
   2.105 + *
   2.106 + * \param surface The surface to update
   2.107 + * \param alpha The source alpha value multiplied into blit operations.
   2.108 + *
   2.109 + * \return 0 on success, or -1 if the surface is not valid
   2.110 + *
   2.111 + * \sa SDL_GetSurfaceAlphaMod()
   2.112 + */
   2.113 +extern DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface *surface,
   2.114 +                                                   Uint8 alpha);
   2.115 +
   2.116 +/**
   2.117 + * \fn int SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 *alpha)
   2.118 + *
   2.119 + * \brief Get the additional alpha value used in blit operations
   2.120 + *
   2.121 + * \param surface The surface to query
   2.122 + * \param alpha A pointer filled in with the source alpha value
   2.123 + *
   2.124 + * \return 0 on success, or -1 if the surface is not valid
   2.125 + *
   2.126 + * \sa SDL_SetSurfaceAlphaMod()
   2.127 + */
   2.128 +extern DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface *surface,
   2.129 +                                                   Uint8 * alpha);
   2.130 +
   2.131 +/**
   2.132 + * \fn int SDL_SetSurfaceBlendMode(SDL_Surface *surface, int blendMode)
   2.133 + *
   2.134 + * \brief Set the blend mode used for blit operations
   2.135 + *
   2.136 + * \param surface The surface to update
   2.137 + * \param blendMode SDL_TextureBlendMode to use for blit blending
   2.138 + *
   2.139 + * \return 0 on success, or -1 if the parameters are not valid
   2.140 + *
   2.141 + * \sa SDL_GetSurfaceBlendMode()
   2.142 + */
   2.143 +extern DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface *surface,
   2.144 +                                                    int blendMode);
   2.145 +
   2.146 +/**
   2.147 + * \fn int SDL_GetSurfaceBlendMode(SDL_Surface *surface, int *blendMode)
   2.148 + *
   2.149 + * \brief Get the blend mode used for blit operations
   2.150 + *
   2.151 + * \param surface The surface to query
   2.152 + * \param blendMode A pointer filled in with the current blend mode
   2.153 + *
   2.154 + * \return 0 on success, or -1 if the surface is not valid
   2.155 + *
   2.156 + * \sa SDL_SetSurfaceBlendMode()
   2.157 + */
   2.158 +extern DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface *surface,
   2.159 +                                                    int *blendMode);
   2.160 +
   2.161 +/**
   2.162 + * \fn int SDL_SetSurfaceScaleMode(SDL_Surface *surface, int scaleMode)
   2.163 + *
   2.164 + * \brief Set the scale mode used for blit operations
   2.165 + *
   2.166 + * \param surface The surface to update
   2.167 + * \param scaleMode SDL_TextureScaleMode to use for blit scaling
   2.168 + *
   2.169 + * \return 0 on success, or -1 if the surface is not valid or the scale mode is not supported
   2.170 + *
   2.171 + * \note If the scale mode is not supported, the closest supported mode is chosen.  Currently only SDL_TEXTURESCALEMODE_FAST is supported on surfaces.
   2.172 + *
   2.173 + * \sa SDL_GetSurfaceScaleMode()
   2.174 + */
   2.175 +extern DECLSPEC int SDLCALL SDL_SetSurfaceScaleMode(SDL_Surface *surface,
   2.176 +                                                    int scaleMode);
   2.177 +
   2.178 +/**
   2.179 + * \fn int SDL_GetSurfaceScaleMode(SDL_Surface *surface, int *scaleMode)
   2.180 + *
   2.181 + * \brief Get the scale mode used for blit operations
   2.182 + *
   2.183 + * \param surface The surface to query
   2.184 + * \param scaleMode A pointer filled in with the current scale mode
   2.185 + *
   2.186 + * \return 0 on success, or -1 if the surface is not valid
   2.187 + *
   2.188 + * \sa SDL_SetSurfaceScaleMode()
   2.189 + */
   2.190 +extern DECLSPEC int SDLCALL SDL_GetSurfaceScaleMode(SDL_Surface *surface,
   2.191 +                                                    int *scaleMode);
   2.192  
   2.193  /*
   2.194   * Sets the clipping rectangle for the destination surface in a blit.
     3.1 --- a/src/SDL_compat.c	Fri Aug 17 06:58:20 2007 +0000
     3.2 +++ b/src/SDL_compat.c	Sat Aug 18 01:44:21 2007 +0000
     3.3 @@ -589,6 +589,22 @@
     3.4      return SDL_PublicSurface;
     3.5  }
     3.6  
     3.7 +int
     3.8 +SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, Uint8 value)
     3.9 +{
    3.10 +    if (flag & SDL_RLEACCEL) {
    3.11 +        SDL_SetSurfaceRLE(surface, 1);
    3.12 +    }
    3.13 +    if (flag) {
    3.14 +        SDL_SetSurfaceAlphaMod(surface, value);
    3.15 +        SDL_SetSurfaceBlendMode(surface, SDL_TEXTUREBLENDMODE_BLEND);
    3.16 +    } else {
    3.17 +        SDL_SetSurfaceAlphaMod(surface, 0xFF);
    3.18 +        SDL_SetSurfaceBlendMode(surface, SDL_TEXTUREBLENDMODE_NONE);
    3.19 +    }
    3.20 +    return 0;
    3.21 +}
    3.22 +
    3.23  SDL_Surface *
    3.24  SDL_DisplayFormat(SDL_Surface * surface)
    3.25  {
    3.26 @@ -600,15 +616,7 @@
    3.27      }
    3.28  
    3.29      /* Set the flags appropriate for copying to display surface */
    3.30 -    flags = SDL_SWSURFACE;
    3.31 -#ifdef AUTORLE_DISPLAYFORMAT
    3.32 -    flags |= (surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA));
    3.33 -    flags |= SDL_RLEACCELOK;
    3.34 -#else
    3.35 -    flags |=
    3.36 -        surface->flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA | SDL_RLEACCELOK);
    3.37 -#endif
    3.38 -    return SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags);
    3.39 +    return SDL_ConvertSurface(surface, SDL_PublicSurface->format, SDL_RLEACCELOK);
    3.40  }
    3.41  
    3.42  SDL_Surface *
    3.43 @@ -658,8 +666,7 @@
    3.44          break;
    3.45      }
    3.46      format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
    3.47 -    flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
    3.48 -    converted = SDL_ConvertSurface(surface, format, flags);
    3.49 +    converted = SDL_ConvertSurface(surface, format, SDL_RLEACCELOK);
    3.50      SDL_FreeFormat(format);
    3.51      return converted;
    3.52  }
     4.1 --- a/src/video/SDL_RLEaccel.c	Fri Aug 17 06:58:20 2007 +0000
     4.2 +++ b/src/video/SDL_RLEaccel.c	Sat Aug 18 01:44:21 2007 +0000
     4.3 @@ -905,8 +905,7 @@
     4.4          }
     4.5      }
     4.6  
     4.7 -    alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA
     4.8 -        ? src->map->info.a : 255;
     4.9 +    alpha = src->map->info.a;
    4.10      /* if left or right edge clipping needed, call clip blit */
    4.11      if (srcrect->x || srcrect->w != src->w) {
    4.12          RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha);
    4.13 @@ -1803,7 +1802,7 @@
    4.14  int
    4.15  SDL_RLESurface(SDL_Surface * surface)
    4.16  {
    4.17 -    int retcode;
    4.18 +    int flags;
    4.19  
    4.20      /* Clear any previous RLE conversion */
    4.21      if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
    4.22 @@ -1812,34 +1811,44 @@
    4.23  
    4.24      /* We don't support RLE encoding of bitmaps */
    4.25      if (surface->format->BitsPerPixel < 8) {
    4.26 -        return (-1);
    4.27 +        return -1;
    4.28      }
    4.29  
    4.30 -    /* Lock the surface if it's in hardware */
    4.31 -    if (SDL_MUSTLOCK(surface)) {
    4.32 -        if (SDL_LockSurface(surface) < 0) {
    4.33 -            return (-1);
    4.34 -        }
    4.35 +    /* Make sure the pixels are available */
    4.36 +    if (!surface->pixels) {
    4.37 +        return -1;
    4.38      }
    4.39  
    4.40 -    /* Encode */
    4.41 -    if ((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
    4.42 -        retcode = RLEColorkeySurface(surface);
    4.43 -    } else {
    4.44 -        if ((surface->flags & SDL_SRCALPHA) == SDL_SRCALPHA
    4.45 -            && surface->format->Amask != 0)
    4.46 -            retcode = RLEAlphaSurface(surface);
    4.47 -        else
    4.48 -            retcode = -1;       /* no RLE for per-surface alpha sans ckey */
    4.49 +    /* If we don't have colorkey or blending, nothing to do... */
    4.50 +    flags = surface->map->info.flags;
    4.51 +    if(!(flags & (SDL_COPY_COLORKEY|SDL_COPY_BLEND))) {
    4.52 +        return -1;
    4.53      }
    4.54  
    4.55 -    /* Unlock the surface if it's in hardware */
    4.56 -    if (SDL_MUSTLOCK(surface)) {
    4.57 -        SDL_UnlockSurface(surface);
    4.58 +    /* Pass on combinations not supported */
    4.59 +    if ((flags & SDL_COPY_MODULATE_COLOR) ||
    4.60 +        (flags & (SDL_COPY_ADD|SDL_COPY_MOD)) ||
    4.61 +        (flags & SDL_COPY_NEAREST)) {
    4.62 +        return -1;
    4.63      }
    4.64  
    4.65 -    if (retcode < 0)
    4.66 -        return -1;
    4.67 +    /* Encode and set up the blit */
    4.68 +    if (!surface->format->Amask || !(flags & SDL_COPY_BLEND)) {
    4.69 +        if (!surface->map->identity) {
    4.70 +            return -1;
    4.71 +        }
    4.72 +        if (RLEColorkeySurface(surface) < 0) {
    4.73 +            return -1;
    4.74 +        }
    4.75 +        surface->map->blit = SDL_RLEBlit;
    4.76 +        surface->map->info.flags |= SDL_COPY_RLE_COLORKEY;
    4.77 +    } else {
    4.78 +        if (RLEAlphaSurface(surface) < 0) {
    4.79 +            return -1;
    4.80 +        }
    4.81 +        surface->map->blit = SDL_RLEAlphaBlit;
    4.82 +        surface->map->info.flags |= SDL_COPY_RLE_ALPHAKEY;
    4.83 +    }
    4.84  
    4.85      /* The surface is now accelerated */
    4.86      surface->flags |= SDL_RLEACCEL;
    4.87 @@ -1931,13 +1940,12 @@
    4.88  void
    4.89  SDL_UnRLESurface(SDL_Surface * surface, int recode)
    4.90  {
    4.91 -    if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
    4.92 +    if (surface->flags & SDL_RLEACCEL) {
    4.93          surface->flags &= ~SDL_RLEACCEL;
    4.94  
    4.95          if (recode && !(surface->flags & SDL_PREALLOC)) {
    4.96 -            if ((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
    4.97 +            if (surface->map->info.flags & SDL_COPY_RLE_COLORKEY) {
    4.98                  SDL_Rect full;
    4.99 -                unsigned alpha_flag;
   4.100  
   4.101                  /* re-create the original surface */
   4.102                  surface->pixels = SDL_malloc(surface->h * surface->pitch);
   4.103 @@ -1954,10 +1962,7 @@
   4.104                  full.x = full.y = 0;
   4.105                  full.w = surface->w;
   4.106                  full.h = surface->h;
   4.107 -                alpha_flag = surface->flags & SDL_SRCALPHA;
   4.108 -                surface->flags &= ~SDL_SRCALPHA;        /* opaque blit */
   4.109                  SDL_RLEBlit(surface, &full, surface, &full);
   4.110 -                surface->flags |= alpha_flag;
   4.111              } else {
   4.112                  if (!UnRLEAlpha(surface)) {
   4.113                      /* Oh crap... */
   4.114 @@ -1966,8 +1971,9 @@
   4.115                  }
   4.116              }
   4.117          }
   4.118 +        surface->map->info.flags &= (SDL_COPY_RLE_COLORKEY|SDL_COPY_RLE_ALPHAKEY);
   4.119  
   4.120 -        if (surface->map && surface->map->data) {
   4.121 +        if (surface->map->data) {
   4.122              SDL_free(surface->map->data);
   4.123              surface->map->data = NULL;
   4.124          }
     5.1 --- a/src/video/SDL_blit.c	Fri Aug 17 06:58:20 2007 +0000
     5.2 +++ b/src/video/SDL_blit.c	Sat Aug 18 01:44:21 2007 +0000
     5.3 @@ -206,7 +206,8 @@
     5.4  SDL_CalculateBlit(SDL_Surface * surface)
     5.5  {
     5.6      SDL_BlitFunc blit = NULL;
     5.7 -    SDL_Surface *dst = surface->map->dst;
     5.8 +    SDL_BlitMap *map = surface->map;
     5.9 +    SDL_Surface *dst = map->dst;
    5.10      Uint32 src_format;
    5.11      Uint32 dst_format;
    5.12  
    5.13 @@ -214,67 +215,48 @@
    5.14      if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
    5.15          SDL_UnRLESurface(surface, 1);
    5.16      }
    5.17 -    surface->map->blit = NULL;
    5.18 -    surface->map->info.src_fmt = surface->format;
    5.19 -    surface->map->info.src_pitch = surface->pitch;
    5.20 -    surface->map->info.dst_fmt = dst->format;
    5.21 -    surface->map->info.dst_pitch = dst->pitch;
    5.22 +    map->blit = SDL_SoftBlit;
    5.23 +    map->info.src_fmt = surface->format;
    5.24 +    map->info.src_pitch = surface->pitch;
    5.25 +    map->info.dst_fmt = dst->format;
    5.26 +    map->info.dst_pitch = dst->pitch;
    5.27  
    5.28 +    /* See if we can do RLE acceleration */
    5.29 +    if (surface->flags & SDL_RLEACCELOK) {
    5.30 +        if (SDL_RLESurface(surface) == 0) {
    5.31 +            return 0;
    5.32 +        }
    5.33 +    }
    5.34 +
    5.35 +    /* Choose a standard blit function */
    5.36      src_format = SDL_MasksToPixelFormatEnum(surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask);
    5.37      dst_format = SDL_MasksToPixelFormatEnum(dst->format->BitsPerPixel, dst->format->Rmask, dst->format->Gmask, dst->format->Bmask, dst->format->Amask);
    5.38  
    5.39 -    /* Check for special "identity" case -- copy blit */
    5.40 -    if (surface->map->identity && !surface->map->info.flags) {
    5.41 +    if (map->identity && !map->info.flags) {
    5.42          /* Handle overlapping blits on the same surface */
    5.43          if (surface == dst) {
    5.44              blit = SDL_BlitCopyOverlap;
    5.45          } else {
    5.46              blit = SDL_BlitCopy;
    5.47          }
    5.48 +    } else if (surface->format->BitsPerPixel < 8) {
    5.49 +        blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_BlitFuncTable0);
    5.50 +    } else if (surface->format->BytesPerPixel == 1) {
    5.51 +        blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_BlitFuncTable1);
    5.52      } else {
    5.53 -        if (surface->format->BitsPerPixel < 8) {
    5.54 -            blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_BlitFuncTable0);
    5.55 -        } else {
    5.56 -            switch (surface->format->BytesPerPixel) {
    5.57 -            case 1:
    5.58 -                blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_BlitFuncTable1);
    5.59 -                break;
    5.60 -            case 2:
    5.61 -            case 3:
    5.62 -            case 4:
    5.63 -                blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_BlitFuncTableN);
    5.64 -                break;
    5.65 -            }
    5.66 -        }
    5.67 +        blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_BlitFuncTableN);
    5.68      }
    5.69      if (blit == NULL) {
    5.70 -        blit = SDL_ChooseBlitFunc(src_format, dst_format, surface->map->info.flags, SDL_GeneratedBlitFuncTable);
    5.71 +        blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_GeneratedBlitFuncTable);
    5.72      }
    5.73  
    5.74      /* Make sure we have a blit function */
    5.75      if (blit == NULL) {
    5.76 -        SDL_InvalidateMap(surface->map);
    5.77 +        SDL_InvalidateMap(map);
    5.78          SDL_SetError("Blit combination not supported");
    5.79          return (-1);
    5.80      }
    5.81  
    5.82 -    /* Choose software blitting function */
    5.83 -    if ((surface->flags & SDL_RLEACCELOK) && !(surface->map->flags & () {
    5.84 -        if (surface->map->identity && (surface->map->flags & SDL_COPY_COLORKEY)
    5.85 -            && (blit_index == 1
    5.86 -                || (blit_index == 3 && !surface->format->Amask))) {
    5.87 -            if (SDL_RLESurface(surface) == 0)
    5.88 -                surface->map->blit = SDL_RLEBlit;
    5.89 -        } else if (blit_index == 2 && surface->format->Amask) {
    5.90 -            if (SDL_RLESurface(surface) == 0)
    5.91 -                surface->map->blit = SDL_RLEAlphaBlit;
    5.92 -        }
    5.93 -    }
    5.94 -
    5.95 -    if (surface->map->blit == NULL) {
    5.96 -        surface->map->blit = SDL_SoftBlit;
    5.97 -        surface->map->data = blit;
    5.98 -    }
    5.99      return (0);
   5.100  }
   5.101  
     6.1 --- a/src/video/SDL_blit.h	Fri Aug 17 06:58:20 2007 +0000
     6.2 +++ b/src/video/SDL_blit.h	Sat Aug 18 01:44:21 2007 +0000
     6.3 @@ -41,23 +41,26 @@
     6.4  #include "SDL_endian.h"
     6.5  
     6.6  /* SDL blit copy flags */
     6.7 -#define SDL_COPY_MODULATE_COLOR     0x0001
     6.8 -#define SDL_COPY_MODULATE_ALPHA     0x0002
     6.9 -#define SDL_COPY_MASK               0x0010
    6.10 -#define SDL_COPY_BLEND              0x0020
    6.11 -#define SDL_COPY_ADD                0x0040
    6.12 -#define SDL_COPY_MOD                0x0080
    6.13 -#define SDL_COPY_COLORKEY           0x0100
    6.14 -#define SDL_COPY_NEAREST            0x0200
    6.15 +#define SDL_COPY_MODULATE_COLOR     0x00000001
    6.16 +#define SDL_COPY_MODULATE_ALPHA     0x00000002
    6.17 +#define SDL_COPY_MASK               0x00000010
    6.18 +#define SDL_COPY_BLEND              0x00000020
    6.19 +#define SDL_COPY_ADD                0x00000040
    6.20 +#define SDL_COPY_MOD                0x00000080
    6.21 +#define SDL_COPY_COLORKEY           0x00000100
    6.22 +#define SDL_COPY_NEAREST            0x00000200
    6.23 +#define SDL_COPY_RLE_DESIRED        0x00001000
    6.24 +#define SDL_COPY_RLE_COLORKEY       0x00002000
    6.25 +#define SDL_COPY_RLE_ALPHAKEY       0x00004000
    6.26  
    6.27  /* SDL blit CPU flags */
    6.28 -#define SDL_CPU_ANY                 0x0000
    6.29 -#define SDL_CPU_MMX                 0x0001
    6.30 -#define SDL_CPU_3DNOW               0x0002
    6.31 -#define SDL_CPU_SSE                 0x0004
    6.32 -#define SDL_CPU_SSE2                0x0008
    6.33 -#define SDL_CPU_ALTIVEC_PREFETCH    0x0010
    6.34 -#define SDL_CPU_ALTIVEC_NOPREFETCH  0x0020
    6.35 +#define SDL_CPU_ANY                 0x00000000
    6.36 +#define SDL_CPU_MMX                 0x00000001
    6.37 +#define SDL_CPU_3DNOW               0x00000002
    6.38 +#define SDL_CPU_SSE                 0x00000004
    6.39 +#define SDL_CPU_SSE2                0x00000008
    6.40 +#define SDL_CPU_ALTIVEC_PREFETCH    0x00000010
    6.41 +#define SDL_CPU_ALTIVEC_NOPREFETCH  0x00000020
    6.42  
    6.43  typedef struct {
    6.44      Uint8 *src;
     7.1 --- a/src/video/SDL_surface.c	Fri Aug 17 06:58:20 2007 +0000
     7.2 +++ b/src/video/SDL_surface.c	Sat Aug 18 01:44:21 2007 +0000
     7.3 @@ -212,153 +212,251 @@
     7.4      return 0;
     7.5  }
     7.6  
     7.7 -/*
     7.8 - * Set the color key in a blittable surface
     7.9 - */
    7.10 -int
    7.11 -SDL_SetColorKey(SDL_Surface * surface, Uint32 flag, Uint32 key)
    7.12 +int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag)
    7.13  {
    7.14 -    /* Sanity check the flag as it gets passed in */
    7.15 -    if (flag & SDL_SRCCOLORKEY) {
    7.16 -        if (flag & (SDL_RLEACCEL | SDL_RLEACCELOK)) {
    7.17 -            flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
    7.18 -        } else {
    7.19 -            flag = SDL_SRCCOLORKEY;
    7.20 -        }
    7.21 -    } else {
    7.22 -        flag = 0;
    7.23 -    }
    7.24 +    Uint32 flags;
    7.25  
    7.26 -    /* Optimize away operations that don't change anything */
    7.27 -    if ((flag == (surface->flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK))) &&
    7.28 -        (key == surface->map->ckey)) {
    7.29 -        return (0);
    7.30 -    }
    7.31 -
    7.32 -    /* UnRLE surfaces before we change the colorkey */
    7.33 -    if (surface->flags & SDL_RLEACCEL) {
    7.34 -        SDL_UnRLESurface(surface, 1);
    7.35 +    if (!surface) {
    7.36 +        return -1;
    7.37      }
    7.38  
    7.39      if (flag) {
    7.40 -        surface->flags |= SDL_SRCCOLORKEY;
    7.41 -        surface->map->ckey = key;
    7.42 -        if (flag & SDL_RLEACCELOK) {
    7.43 -            surface->flags |= SDL_RLEACCELOK;
    7.44 -        } else {
    7.45 -            surface->flags &= ~SDL_RLEACCELOK;
    7.46 -        }
    7.47 +        surface->flags |= SDL_RLEACCELOK;
    7.48      } else {
    7.49 -        surface->flags &= ~(SDL_SRCCOLORKEY | SDL_RLEACCELOK);
    7.50 -        surface->map->ckey = 0;
    7.51 +        surface->flags &= ~SDL_RLEACCELOK;
    7.52      }
    7.53 -    SDL_InvalidateMap(surface->map);
    7.54 -    return (0);
    7.55 -}
    7.56 -
    7.57 -/* This function sets the alpha channel of a surface */
    7.58 -int
    7.59 -SDL_SetAlpha(SDL_Surface * surface, Uint32 flag, Uint8 value)
    7.60 -{
    7.61 -    Uint32 oldflags = surface->flags;
    7.62 -    Uint32 oldalpha = (surface->map->cmod >> 24);
    7.63 -
    7.64 -    /* Sanity check the flag as it gets passed in */
    7.65 -    if (flag & SDL_SRCALPHA) {
    7.66 -        if (flag & (SDL_RLEACCEL | SDL_RLEACCELOK)) {
    7.67 -            flag = (SDL_SRCALPHA | SDL_RLEACCELOK);
    7.68 -        } else {
    7.69 -            flag = SDL_SRCALPHA;
    7.70 -        }
    7.71 -    } else {
    7.72 -        flag = 0;
    7.73 -    }
    7.74 -
    7.75 -    /* Optimize away operations that don't change anything */
    7.76 -    if ((flag == (surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK))) &&
    7.77 -        (!flag || value == oldalpha)) {
    7.78 -        return (0);
    7.79 -    }
    7.80 -
    7.81 -    if (!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL))
    7.82 -        SDL_UnRLESurface(surface, 1);
    7.83 -
    7.84 -    if (flag) {
    7.85 -        surface->flags |= SDL_SRCALPHA;
    7.86 -        surface->map->cmod &= 0x00FFFFFF;
    7.87 -        surface->map->cmod |= ((Uint32) value << 24);
    7.88 -        if (flag & SDL_RLEACCELOK) {
    7.89 -            surface->flags |= SDL_RLEACCELOK;
    7.90 -        } else {
    7.91 -            surface->flags &= ~SDL_RLEACCELOK;
    7.92 -        }
    7.93 -    } else {
    7.94 -        surface->flags &= ~SDL_SRCALPHA;
    7.95 -        surface->map->cmod |= 0xFF000000;
    7.96 -    }
    7.97 -    /*
    7.98 -     * The representation for software surfaces is independent of
    7.99 -     * per-surface alpha, so no need to invalidate the blit mapping
   7.100 -     * if just the alpha value was changed. (If either is 255, we still
   7.101 -     * need to invalidate.)
   7.102 -     */
   7.103 -    if (oldflags != surface->flags
   7.104 -        || (((oldalpha + 1) ^ (value + 1)) & 0x100)) {
   7.105 +    if (surface->flags != flags) {
   7.106          SDL_InvalidateMap(surface->map);
   7.107      }
   7.108 -    return (0);
   7.109 -}
   7.110 -
   7.111 -int
   7.112 -SDL_SetAlphaChannel(SDL_Surface * surface, Uint8 value)
   7.113 -{
   7.114 -    int row, col;
   7.115 -    int offset;
   7.116 -    Uint8 *buf;
   7.117 -
   7.118 -    if ((surface->format->Amask != 0xFF000000) &&
   7.119 -        (surface->format->Amask != 0x000000FF)) {
   7.120 -        SDL_SetError("Unsupported surface alpha mask format");
   7.121 -        return -1;
   7.122 -    }
   7.123 -#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   7.124 -    if (surface->format->Amask == 0xFF000000) {
   7.125 -        offset = 3;
   7.126 -    } else {
   7.127 -        offset = 0;
   7.128 -    }
   7.129 -#else
   7.130 -    if (surface->format->Amask == 0xFF000000) {
   7.131 -        offset = 0;
   7.132 -    } else {
   7.133 -        offset = 3;
   7.134 -    }
   7.135 -#endif /* Byte ordering */
   7.136 -
   7.137 -    /* Quickly set the alpha channel of an RGBA or ARGB surface */
   7.138 -    if (SDL_MUSTLOCK(surface)) {
   7.139 -        if (SDL_LockSurface(surface) < 0) {
   7.140 -            return -1;
   7.141 -        }
   7.142 -    }
   7.143 -    row = surface->h;
   7.144 -    while (row--) {
   7.145 -        col = surface->w;
   7.146 -        buf = (Uint8 *) surface->pixels + row * surface->pitch + offset;
   7.147 -        while (col--) {
   7.148 -            *buf = value;
   7.149 -            buf += 4;
   7.150 -        }
   7.151 -    }
   7.152 -    if (SDL_MUSTLOCK(surface)) {
   7.153 -        SDL_UnlockSurface(surface);
   7.154 -    }
   7.155      return 0;
   7.156  }
   7.157  
   7.158 -/*
   7.159 - * Set the clipping rectangle for a blittable surface
   7.160 - */
   7.161 +int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key)
   7.162 +{
   7.163 +    int flags;
   7.164 +
   7.165 +    if (!surface) {
   7.166 +        return -1;
   7.167 +    }
   7.168 +
   7.169 +    if (flag & SDL_RLEACCEL) {
   7.170 +        SDL_SetSurfaceRLE(surface, 1);
   7.171 +    }
   7.172 +
   7.173 +    flags = surface->map->info.flags;
   7.174 +    if (flag) {
   7.175 +        surface->map->info.flags |= SDL_COPY_COLORKEY;
   7.176 +        surface->map->info.colorkey = key;
   7.177 +    } else {
   7.178 +        surface->map->info.flags &= ~SDL_COPY_COLORKEY;
   7.179 +    }
   7.180 +    if (surface->map->info.flags != flags) {
   7.181 +        SDL_InvalidateMap(surface->map);
   7.182 +    }
   7.183 +    return 0;
   7.184 +}
   7.185 +
   7.186 +int SDL_SetSurfaceColorMod(SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b)
   7.187 +{
   7.188 +    int flags;
   7.189 +
   7.190 +    if (!surface) {
   7.191 +        return -1;
   7.192 +    }
   7.193 +
   7.194 +    surface->map->info.r = r;
   7.195 +    surface->map->info.g = g;
   7.196 +    surface->map->info.b = b;
   7.197 +
   7.198 +    flags = surface->map->info.flags;
   7.199 +    if (r != 0xFF || g != 0xFF || b != 0xFF) {
   7.200 +        surface->map->info.flags |= SDL_COPY_MODULATE_COLOR;
   7.201 +    } else {
   7.202 +        surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR;
   7.203 +    }
   7.204 +    if (surface->map->info.flags != flags) {
   7.205 +        SDL_InvalidateMap(surface->map);
   7.206 +    }
   7.207 +    return 0;
   7.208 +}
   7.209 +
   7.210 +
   7.211 +int SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 * r, Uint8 * g, Uint8 * b)
   7.212 +{
   7.213 +    if (!surface) {
   7.214 +        return -1;
   7.215 +    }
   7.216 +
   7.217 +    if (r) {
   7.218 +        *r = surface->map->info.r;
   7.219 +    }
   7.220 +    if (g) {
   7.221 +        *g = surface->map->info.g;
   7.222 +    }
   7.223 +    if (b) {
   7.224 +        *b = surface->map->info.b;
   7.225 +    }
   7.226 +    return 0;
   7.227 +}
   7.228 +
   7.229 +int SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Uint8 alpha)
   7.230 +{
   7.231 +    int flags;
   7.232 +
   7.233 +    if (!surface) {
   7.234 +        return -1;
   7.235 +    }
   7.236 +
   7.237 +    surface->map->info.a = alpha;
   7.238 +
   7.239 +    flags = surface->map->info.flags;
   7.240 +    if (alpha != 0xFF) {
   7.241 +        surface->map->info.flags |= SDL_COPY_MODULATE_ALPHA;
   7.242 +    } else {
   7.243 +        surface->map->info.flags &= ~SDL_COPY_MODULATE_ALPHA;
   7.244 +    }
   7.245 +    if (surface->map->info.flags != flags) {
   7.246 +        SDL_InvalidateMap(surface->map);
   7.247 +    }
   7.248 +    return 0;
   7.249 +}
   7.250 +
   7.251 +int SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 * alpha)
   7.252 +{
   7.253 +    if (!surface) {
   7.254 +        return -1;
   7.255 +    }
   7.256 +
   7.257 +    if (alpha) {
   7.258 +        *alpha = surface->map->info.a;
   7.259 +    }
   7.260 +    return 0;
   7.261 +}
   7.262 +
   7.263 +int SDL_SetSurfaceBlendMode(SDL_Surface *surface, int blendMode)
   7.264 +{
   7.265 +    int flags, status;
   7.266 +
   7.267 +    if (!surface) {
   7.268 +        return -1;
   7.269 +    }
   7.270 +
   7.271 +    status = 0;
   7.272 +    flags = surface->map->info.flags;
   7.273 +    surface->map->info.flags &= ~(SDL_COPY_MASK|SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD);
   7.274 +    switch (blendMode) {
   7.275 +    case SDL_TEXTUREBLENDMODE_NONE:
   7.276 +        break;
   7.277 +    case SDL_TEXTUREBLENDMODE_MASK:
   7.278 +        surface->map->info.flags |= SDL_COPY_MASK;
   7.279 +        break;
   7.280 +    case SDL_TEXTUREBLENDMODE_BLEND:
   7.281 +        surface->map->info.flags |= SDL_COPY_BLEND;
   7.282 +        break;
   7.283 +    case SDL_TEXTUREBLENDMODE_ADD:
   7.284 +        surface->map->info.flags |= SDL_COPY_ADD;
   7.285 +        break;
   7.286 +    case SDL_TEXTUREBLENDMODE_MOD:
   7.287 +        surface->map->info.flags |= SDL_COPY_MOD;
   7.288 +        break;
   7.289 +    default:
   7.290 +        SDL_Unsupported();
   7.291 +        status = -1;
   7.292 +        break;
   7.293 +    }
   7.294 +
   7.295 +    if (surface->map->info.flags != flags) {
   7.296 +        SDL_InvalidateMap(surface->map);
   7.297 +    }
   7.298 +    return status;
   7.299 +}
   7.300 +
   7.301 +int SDL_GetSurfaceBlendMode(SDL_Surface *surface, int *blendMode)
   7.302 +{
   7.303 +    if (!surface) {
   7.304 +        return -1;
   7.305 +    }
   7.306 +
   7.307 +    if (!blendMode) {
   7.308 +        return 0;
   7.309 +    }
   7.310 +
   7.311 +    switch(surface->map->info.flags & (SDL_COPY_MASK|SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
   7.312 +    case SDL_COPY_MASK:
   7.313 +        *blendMode = SDL_TEXTUREBLENDMODE_MASK:
   7.314 +        break;
   7.315 +    case SDL_COPY_BLEND:
   7.316 +        *blendMode = SDL_TEXTUREBLENDMODE_BLEND:
   7.317 +        break;
   7.318 +    case SDL_COPY_ADD:
   7.319 +        *blendMode = SDL_TEXTUREBLENDMODE_ADD:
   7.320 +        break;
   7.321 +    case SDL_COPY_MOD:
   7.322 +        *blendMode = SDL_TEXTUREBLENDMODE_MOD:
   7.323 +        break;
   7.324 +    default:
   7.325 +        *blendMode = SDL_TEXTUREBLENDMODE_NONE:
   7.326 +        break;
   7.327 +    }
   7.328 +    return 0;
   7.329 +}
   7.330 +
   7.331 +int SDL_SetSurfaceScaleMode(SDL_Surface *surface, int scaleMode)
   7.332 +{
   7.333 +    int flags, status;
   7.334 +
   7.335 +    if (!surface) {
   7.336 +        return -1;
   7.337 +    }
   7.338 +
   7.339 +    status = 0;
   7.340 +    flags = surface->map->info.flags;
   7.341 +    surface->map->info.flags &= ~(SDL_COPY_NEAREST);
   7.342 +    switch (scaleMode) {
   7.343 +    case SDL_TEXTURESCALEMODE_NONE:
   7.344 +        break;
   7.345 +    case SDL_TEXTURESCALEMODE_FAST:
   7.346 +        surface->map->info.flags |= SDL_COPY_NEAREST;
   7.347 +        break;
   7.348 +    case SDL_TEXTURESCALEMODE_SLOW:
   7.349 +    case SDL_TEXTURESCALEMODE_BEST:
   7.350 +        SDL_Unsupported();
   7.351 +        surface->map->info.flags |= SDL_COPY_NEAREST;
   7.352 +        status = -1;
   7.353 +        break;
   7.354 +    default:
   7.355 +        SDL_Unsupported();
   7.356 +        status = -1;
   7.357 +        break;
   7.358 +    }
   7.359 +
   7.360 +    if (surface->map->info.flags != flags) {
   7.361 +        SDL_InvalidateMap(surface->map);
   7.362 +    }
   7.363 +    return status;
   7.364 +}
   7.365 +
   7.366 +int SDL_GetSurfaceScaleMode(SDL_Surface *surface, int *scaleMode)
   7.367 +{
   7.368 +    if (!surface) {
   7.369 +        return -1;
   7.370 +    }
   7.371 +
   7.372 +    if (!scaleMode) {
   7.373 +        return 0;
   7.374 +    }
   7.375 +
   7.376 +    switch(surface->map->info.flags & (SDL_COPY_LINEAR)) {
   7.377 +    case SDL_COPY_LINEAR:
   7.378 +        *scaleMode = SDL_TEXTURESCALEMODE_FAST:
   7.379 +        break;
   7.380 +    default:
   7.381 +        *scaleMode = SDL_TEXTURESCALEMODE_NONE:
   7.382 +        break;
   7.383 +    }
   7.384 +    return 0;
   7.385 +}
   7.386 +
   7.387  SDL_bool
   7.388  SDL_SetClipRect(SDL_Surface * surface, const SDL_Rect * rect)
   7.389  {
   7.390 @@ -557,9 +655,7 @@
   7.391                     SDL_PixelFormat * format, Uint32 flags)
   7.392  {
   7.393      SDL_Surface *convert;
   7.394 -    Uint32 colorkey = 0;
   7.395 -    Uint8 alpha = 0;
   7.396 -    Uint32 surface_flags;
   7.397 +    Uint32 copy_flags;
   7.398      SDL_Rect bounds;
   7.399  
   7.400      /* Check for empty destination palette! (results in empty image) */
   7.401 @@ -578,8 +674,7 @@
   7.402      }
   7.403  
   7.404      /* Create a new surface with the desired format */
   7.405 -    convert = SDL_CreateRGBSurface(flags,
   7.406 -                                   surface->w, surface->h,
   7.407 +    convert = SDL_CreateRGBSurface(0, surface->w, surface->h,
   7.408                                     format->BitsPerPixel, format->Rmask,
   7.409                                     format->Gmask, format->Bmask,
   7.410                                     format->Amask);
   7.411 @@ -595,26 +690,9 @@
   7.412          convert->format->palette->ncolors = format->palette->ncolors;
   7.413      }
   7.414  
   7.415 -    /* Save the original surface color key and alpha */
   7.416 -    surface_flags = surface->flags;
   7.417 -    if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
   7.418 -        /* Convert colourkeyed surfaces to RGBA if requested */
   7.419 -        if ((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY && format->Amask) {
   7.420 -            surface_flags &= ~SDL_SRCCOLORKEY;
   7.421 -        } else {
   7.422 -            colorkey = surface->map->ckey;
   7.423 -            SDL_SetColorKey(surface, 0, 0);
   7.424 -        }
   7.425 -    }
   7.426 -    if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
   7.427 -        /* Copy over the alpha channel to RGBA if requested */
   7.428 -        if (format->Amask) {
   7.429 -            surface->flags &= ~SDL_SRCALPHA;
   7.430 -        } else {
   7.431 -            alpha = (Uint8) (surface->map->cmod >> 24);
   7.432 -            SDL_SetAlpha(surface, 0, 0);
   7.433 -        }
   7.434 -    }
   7.435 +    /* Save the original copy flags */
   7.436 +    copy_flags = surface->map->info.flags;
   7.437 +    surface->map->info.flags = 0;
   7.438  
   7.439      /* Copy over the image data */
   7.440      bounds.x = 0;
   7.441 @@ -624,30 +702,25 @@
   7.442      SDL_LowerBlit(surface, &bounds, convert, &bounds);
   7.443  
   7.444      /* Clean up the original surface, and update converted surface */
   7.445 -    if (convert != NULL) {
   7.446 -        SDL_SetClipRect(convert, &surface->clip_rect);
   7.447 +    SDL_SetClipRect(convert, &surface->clip_rect);
   7.448 +    if (copy_flags & SDL_COPY_COLORKEY) {
   7.449 +        Uint8 keyR, keyG, keyB, keyA;
   7.450 +
   7.451 +        SDL_GetRGBA(colorkey, surface->format, &keyR, &keyG, &keyB, &keyA);
   7.452 +        SDL_SetColorKey(convert, 1,
   7.453 +                        SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA));
   7.454      }
   7.455 -    if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
   7.456 -        Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
   7.457 -        if (convert != NULL) {
   7.458 -            Uint8 keyR, keyG, keyB;
   7.459 +    convert->map->info.r = surface->map->info.r;
   7.460 +    convert->map->info.g = surface->map->info.g;
   7.461 +    convert->map->info.b = surface->map->info.b;
   7.462 +    convert->map->info.a = surface->map->info.a;
   7.463 +    convert->map->info.flags = copy_flags;
   7.464 +    surface->map->info.flags = copy_flags;
   7.465  
   7.466 -            SDL_GetRGB(colorkey, surface->format, &keyR, &keyG, &keyB);
   7.467 -            SDL_SetColorKey(convert, cflags | (flags & SDL_RLEACCELOK),
   7.468 -                            SDL_MapRGB(convert->format, keyR, keyG, keyB));
   7.469 -        }
   7.470 -        SDL_SetColorKey(surface, cflags, colorkey);
   7.471 -    }
   7.472 -    if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
   7.473 -        Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
   7.474 -        if (convert != NULL) {
   7.475 -            SDL_SetAlpha(convert, aflags | (flags & SDL_RLEACCELOK), alpha);
   7.476 -        }
   7.477 -        if (format->Amask) {
   7.478 -            surface->flags |= SDL_SRCALPHA;
   7.479 -        } else {
   7.480 -            SDL_SetAlpha(surface, aflags, alpha);
   7.481 -        }
   7.482 +    /* Enable alpha blending by default if the new surface has an
   7.483 +     * alpha channel or alpha modulation */
   7.484 +    if (format->Amask || (copy_flags & SDL_COPY_MODULATE_ALPHA)) {
   7.485 +        SDL_SetSurfaceBlendMode(convert, SDL_TEXTUREBLENDMODE_BLEND);
   7.486      }
   7.487  
   7.488      /* We're ready to go! */
     8.1 --- a/src/video/SDL_video.c	Fri Aug 17 06:58:20 2007 +0000
     8.2 +++ b/src/video/SDL_video.c	Sat Aug 18 01:44:21 2007 +0000
     8.3 @@ -1535,8 +1535,7 @@
     8.4  SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
     8.5  {
     8.6      SDL_TextureID textureID;
     8.7 -    Uint32 surface_flags = surface->flags;
     8.8 -    SDL_PixelFormat *fmt = surface->format;
     8.9 +    SDL_PixelFormat *fmt;
    8.10      int bpp;
    8.11      Uint32 Rmask, Gmask, Bmask, Amask;
    8.12  
    8.13 @@ -1544,6 +1543,7 @@
    8.14          SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
    8.15          return 0;
    8.16      }
    8.17 +    fmt = surface->format;
    8.18  
    8.19      if (format) {
    8.20          if (!SDL_PixelFormatEnumToMasks
    8.21 @@ -1552,7 +1552,7 @@
    8.22              return 0;
    8.23          }
    8.24      } else {
    8.25 -        if (fmt->Amask || !(surface_flags & (SDL_SRCCOLORKEY | SDL_SRCALPHA))) {
    8.26 +        if (surface->format->Amask || !(flags & (SDL_COPY_COLORKEY|SDL_COPY_MASK|SDL_COPY_BLEND))) {
    8.27              bpp = fmt->BitsPerPixel;
    8.28              Rmask = fmt->Rmask;
    8.29              Gmask = fmt->Gmask;
    8.30 @@ -1595,92 +1595,38 @@
    8.31                                surface->pitch);
    8.32          }
    8.33      } else {
    8.34 -        Uint32 cmod;
    8.35 -        SDL_Rect bounds;
    8.36 -        SDL_Surface dst;
    8.37 +        SDL_PixelFormat *dst_fmt;
    8.38 +        SDL_Surface *dst = NULL;
    8.39  
    8.40          /* Set up a destination surface for the texture update */
    8.41 -        SDL_zero(dst);
    8.42 -        dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
    8.43 -        if (!dst.format) {
    8.44 -            SDL_DestroyTexture(textureID);
    8.45 -            return 0;
    8.46 +        dst_fmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
    8.47 +        if (dst_fmt) {
    8.48 +            if (SDL_ISPIXELFORMAT_INDEXED(format)) {
    8.49 +                dst_fmt->palette = SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
    8.50 +                if (dst_fmt->palette) {
    8.51 +                    if (fmt->palette) {
    8.52 +fixme
    8.53 +                    } else {
    8.54 +                        SDL_DitherColors(dst_fmt->palette->colors, SDL_BITSPERPIXEL(format));
    8.55 +                    }
    8.56 +                }
    8.57 +                if (fmt->palette) {
    8.58 +                    dst_fmt->palette = fmt->palette;
    8.59 +                } else {
    8.60 +                }
    8.61 +            }
    8.62 +
    8.63 +            cvt = SDL_ConvertSurface(surface, fmt, 0);
    8.64 +            if (cvt) {
    8.65 +                SDL_UpdateTexture(textureID, NULL, cvt->pixels, cvt->pitch);
    8.66 +                SDL_FreeSurface(cvt);
    8.67 +            }
    8.68 +            SDL_FreeFormat(fmt);
    8.69          }
    8.70 -        dst.w = surface->w;
    8.71 -        dst.h = surface->h;
    8.72 -        dst.pitch = SDL_CalculatePitch(&dst);
    8.73 -        dst.pixels = SDL_malloc(dst.h * dst.pitch);
    8.74 -        if (!dst.pixels) {
    8.75 -            SDL_DestroyTexture(textureID);
    8.76 -            SDL_FreeFormat(dst.format);
    8.77 -            SDL_OutOfMemory();
    8.78 -            return 0;
    8.79 -        }
    8.80 +    }
    8.81  
    8.82 -        /* Copy the palette if any */
    8.83 -        if (SDL_ISPIXELFORMAT_INDEXED(format)) {
    8.84 -            if (fmt->palette) {
    8.85 -                SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
    8.86 -                                      fmt->palette->ncolors);
    8.87 -                SDL_SetSurfacePalette(&dst, fmt->palette);
    8.88 -            } else {
    8.89 -                dst.format->palette =
    8.90 -                    SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
    8.91 -                if (!dst.format->palette) {
    8.92 -                    SDL_DestroyTexture(textureID);
    8.93 -                    SDL_FreeFormat(dst.format);
    8.94 -                    return 0;
    8.95 -                }
    8.96 -                SDL_DitherColors(dst.format->palette->colors,
    8.97 -                                 SDL_BITSPERPIXEL(format));
    8.98 -            }
    8.99 -        }
   8.100 -
   8.101 -        /* Make the texture transparent if the surface has colorkey */
   8.102 -        if (surface_flags & SDL_SRCCOLORKEY) {
   8.103 -            int row;
   8.104 -            int length = dst.w * dst.format->BytesPerPixel;
   8.105 -            Uint8 *p = (Uint8 *) dst.pixels;
   8.106 -            for (row = 0; row < dst.h; ++row) {
   8.107 -                SDL_memset(p, 0, length);
   8.108 -                p += dst.pitch;
   8.109 -            }
   8.110 -        }
   8.111 -
   8.112 -        /* Copy over the alpha channel */
   8.113 -        cmod = surface->map->cmod;
   8.114 -        if (surface_flags & SDL_SRCALPHA) {
   8.115 -            if (fmt->Amask) {
   8.116 -                surface->flags &= ~SDL_SRCALPHA;
   8.117 -            } else {
   8.118 -                /* FIXME: Need to make sure the texture has an alpha channel
   8.119 -                 *        and copy 'alpha' into the texture alpha channel.
   8.120 -                 */
   8.121 -                SDL_SetAlpha(surface, 0, 0);
   8.122 -            }
   8.123 -        }
   8.124 -
   8.125 -        /* Copy over the image data */
   8.126 -        bounds.x = 0;
   8.127 -        bounds.y = 0;
   8.128 -        bounds.w = surface->w;
   8.129 -        bounds.h = surface->h;
   8.130 -        SDL_LowerBlit(surface, &bounds, &dst, &bounds);
   8.131 -
   8.132 -        /* Clean up the original surface */
   8.133 -        if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
   8.134 -            Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
   8.135 -            if (fmt->Amask) {
   8.136 -                surface->flags |= SDL_SRCALPHA;
   8.137 -            } else {
   8.138 -                SDL_SetAlpha(surface, aflags, (cmod >> 24));
   8.139 -            }
   8.140 -        }
   8.141 -
   8.142 -        /* Update the texture */
   8.143 -        SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch);
   8.144 -        SDL_free(dst.pixels);
   8.145 -        SDL_FreeFormat(dst.format);
   8.146 +    if (SDL_ISPIXELFORMAT_INDEXED(format) && fmt->palette) {
   8.147 +        SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, fmt->palette->ncolors);
   8.148      }
   8.149  
   8.150      return textureID;