More work in progress integrating SDL_Surface and the new SDL_Texture API
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%402628
This commit is contained in:
parent
8379dac1e0
commit
2e91636dda
8 changed files with 536 additions and 395 deletions
|
@ -37,6 +37,8 @@ extern "C" {
|
|||
#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_UpdateRects(SDL_Surface * screen,
|
|||
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);
|
||||
|
|
|
@ -265,10 +265,7 @@ typedef void *SDL_GLContext;
|
|||
/* 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,35 +1398,158 @@ extern DECLSPEC int SDLCALL SDL_SaveBMP_RW
|
|||
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)
|
||||
*
|
||||
* 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.
|
||||
* \brief Sets the color key (transparent pixel) in a blittable surface.
|
||||
*
|
||||
* The 'alpha' parameter is ignored for surfaces that have an alpha channel.
|
||||
* \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_SetAlpha(SDL_Surface * surface, Uint32 flag,
|
||||
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
|
||||
*
|
||||
* \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
|
||||
*
|
||||
* \sa SDL_SetSurfaceBlendMode()
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -589,6 +589,22 @@ SDL_GetVideoSurface(void)
|
|||
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 @@ SDL_DisplayFormat(SDL_Surface * surface)
|
|||
}
|
||||
|
||||
/* 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 @@ SDL_DisplayFormatAlpha(SDL_Surface * surface)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -905,8 +905,7 @@ SDL_RLEBlit(SDL_Surface * src, SDL_Rect * srcrect,
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ RLEColorkeySurface(SDL_Surface * surface)
|
|||
int
|
||||
SDL_RLESurface(SDL_Surface * surface)
|
||||
{
|
||||
int retcode;
|
||||
int flags;
|
||||
|
||||
/* Clear any previous RLE conversion */
|
||||
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
|
||||
|
@ -1812,34 +1811,44 @@ SDL_RLESurface(SDL_Surface * surface)
|
|||
|
||||
/* We don't support RLE encoding of bitmaps */
|
||||
if (surface->format->BitsPerPixel < 8) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Lock the surface if it's in hardware */
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
if (SDL_LockSurface(surface) < 0) {
|
||||
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 */
|
||||
}
|
||||
|
||||
/* Unlock the surface if it's in hardware */
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
|
||||
if (retcode < 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;
|
||||
}
|
||||
|
||||
/* Pass on combinations not supported */
|
||||
if ((flags & SDL_COPY_MODULATE_COLOR) ||
|
||||
(flags & (SDL_COPY_ADD|SDL_COPY_MOD)) ||
|
||||
(flags & SDL_COPY_NEAREST)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* The surface is now accelerated */
|
||||
surface->flags |= SDL_RLEACCEL;
|
||||
|
@ -1931,13 +1940,12 @@ UnRLEAlpha(SDL_Surface * surface)
|
|||
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 @@ SDL_UnRLESurface(SDL_Surface * surface, int recode)
|
|||
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 @@ SDL_UnRLESurface(SDL_Surface * surface, int recode)
|
|||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -206,7 +206,8 @@ int
|
|||
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 @@ SDL_CalculateBlit(SDL_Surface * surface)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -212,153 +212,251 @@ SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette)
|
|||
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;
|
||||
}
|
||||
} else {
|
||||
surface->flags &= ~(SDL_SRCCOLORKEY | SDL_RLEACCELOK);
|
||||
surface->map->ckey = 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)
|
||||
{
|
||||
Uint32 oldflags = surface->flags;
|
||||
Uint32 oldalpha = (surface->map->cmod >> 24);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Optimize away operations that don't change anything */
|
||||
if ((flag == (surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK))) &&
|
||||
(!flag || value == oldalpha)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL))
|
||||
SDL_UnRLESurface(surface, 1);
|
||||
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
surface->flags &= ~SDL_SRCALPHA;
|
||||
surface->map->cmod |= 0xFF000000;
|
||||
}
|
||||
/*
|
||||
* 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)) {
|
||||
SDL_InvalidateMap(surface->map);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SetAlphaChannel(SDL_Surface * surface, Uint8 value)
|
||||
{
|
||||
int row, col;
|
||||
int offset;
|
||||
Uint8 *buf;
|
||||
|
||||
if ((surface->format->Amask != 0xFF000000) &&
|
||||
(surface->format->Amask != 0x000000FF)) {
|
||||
SDL_SetError("Unsupported surface alpha mask format");
|
||||
return -1;
|
||||
}
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
if (surface->format->Amask == 0xFF000000) {
|
||||
offset = 3;
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
#else
|
||||
if (surface->format->Amask == 0xFF000000) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = 3;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
}
|
||||
row = surface->h;
|
||||
while (row--) {
|
||||
col = surface->w;
|
||||
buf = (Uint8 *) surface->pixels + row * surface->pitch + offset;
|
||||
while (col--) {
|
||||
*buf = value;
|
||||
buf += 4;
|
||||
}
|
||||
}
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the clipping rectangle for a blittable surface
|
||||
*/
|
||||
int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key)
|
||||
{
|
||||
int flags;
|
||||
|
||||
if (!surface) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flag & SDL_RLEACCEL) {
|
||||
SDL_SetSurfaceRLE(surface, 1);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
surface->map->info.r = r;
|
||||
surface->map->info.g = g;
|
||||
surface->map->info.b = b;
|
||||
|
||||
flags = surface->map->info.flags;
|
||||
if (r != 0xFF || g != 0xFF || b != 0xFF) {
|
||||
surface->map->info.flags |= SDL_COPY_MODULATE_COLOR;
|
||||
} else {
|
||||
surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR;
|
||||
}
|
||||
if (surface->map->info.flags != flags) {
|
||||
SDL_InvalidateMap(surface->map);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 * r, Uint8 * g, Uint8 * b)
|
||||
{
|
||||
if (!surface) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (r) {
|
||||
*r = surface->map->info.r;
|
||||
}
|
||||
if (g) {
|
||||
*g = surface->map->info.g;
|
||||
}
|
||||
if (b) {
|
||||
*b = surface->map->info.b;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Uint8 alpha)
|
||||
{
|
||||
int flags;
|
||||
|
||||
if (!surface) {
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 * alpha)
|
||||
{
|
||||
if (!surface) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (alpha) {
|
||||
*alpha = surface->map->info.a;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_ConvertSurface(SDL_Surface * surface,
|
|||
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 @@ SDL_ConvertSurface(SDL_Surface * surface,
|
|||
}
|
||||
|
||||
/* 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 @@ SDL_ConvertSurface(SDL_Surface * surface,
|
|||
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_ConvertSurface(SDL_Surface * surface,
|
|||
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;
|
||||
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);
|
||||
}
|
||||
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);
|
||||
SDL_GetRGBA(colorkey, surface->format, &keyR, &keyG, &keyB, &keyA);
|
||||
SDL_SetColorKey(convert, 1,
|
||||
SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA));
|
||||
}
|
||||
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! */
|
||||
|
|
|
@ -1535,8 +1535,7 @@ SDL_TextureID
|
|||
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_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
|
|||
SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
|
||||
return 0;
|
||||
}
|
||||
fmt = surface->format;
|
||||
|
||||
if (format) {
|
||||
if (!SDL_PixelFormatEnumToMasks
|
||||
|
@ -1552,7 +1552,7 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
|
|||
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 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
|
|||
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 */
|
||||
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) {
|
||||
SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
|
||||
fmt->palette->ncolors);
|
||||
SDL_SetSurfacePalette(&dst, fmt->palette);
|
||||
fixme
|
||||
} else {
|
||||
dst.format->palette =
|
||||
SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
|
||||
if (!dst.format->palette) {
|
||||
SDL_DestroyTexture(textureID);
|
||||
SDL_FreeFormat(dst.format);
|
||||
return 0;
|
||||
}
|
||||
SDL_DitherColors(dst.format->palette->colors,
|
||||
SDL_BITSPERPIXEL(format));
|
||||
SDL_DitherColors(dst_fmt->palette->colors, SDL_BITSPERPIXEL(format));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy over the alpha channel */
|
||||
cmod = surface->map->cmod;
|
||||
if (surface_flags & SDL_SRCALPHA) {
|
||||
if (fmt->Amask) {
|
||||
surface->flags &= ~SDL_SRCALPHA;
|
||||
if (fmt->palette) {
|
||||
dst_fmt->palette = fmt->palette;
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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));
|
||||
cvt = SDL_ConvertSurface(surface, fmt, 0);
|
||||
if (cvt) {
|
||||
SDL_UpdateTexture(textureID, NULL, cvt->pixels, cvt->pitch);
|
||||
SDL_FreeSurface(cvt);
|
||||
}
|
||||
SDL_FreeFormat(fmt);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue