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
|
#endif
|
||||||
|
|
||||||
#define SDL_SWSURFACE 0x00000000 /* Not used */
|
#define SDL_SWSURFACE 0x00000000 /* Not used */
|
||||||
|
//#define SDL_SRCALPHA 0x00010000
|
||||||
|
//#define SDL_SRCCOLORKEY 0x00020000
|
||||||
#define SDL_ANYFORMAT 0x00100000
|
#define SDL_ANYFORMAT 0x00100000
|
||||||
#define SDL_HWPALETTE 0x00200000
|
#define SDL_HWPALETTE 0x00200000
|
||||||
#define SDL_DOUBLEBUF 0x00400000
|
#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,
|
extern DECLSPEC void SDLCALL SDL_UpdateRect(SDL_Surface * screen, Sint32 x,
|
||||||
Sint32 y, Uint32 w, Uint32 h);
|
Sint32 y, Uint32 w, Uint32 h);
|
||||||
extern DECLSPEC int SDLCALL SDL_Flip(SDL_Surface * screen);
|
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_DisplayFormat(SDL_Surface * surface);
|
||||||
extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormatAlpha(SDL_Surface *
|
extern DECLSPEC SDL_Surface *SDLCALL SDL_DisplayFormatAlpha(SDL_Surface *
|
||||||
surface);
|
surface);
|
||||||
|
|
|
@ -265,10 +265,7 @@ typedef void *SDL_GLContext;
|
||||||
/* These are the currently supported flags for the SDL_surface */
|
/* These are the currently supported flags for the SDL_surface */
|
||||||
/* Used internally (read-only) */
|
/* Used internally (read-only) */
|
||||||
#define SDL_PREALLOC 0x00000001 /* Surface uses preallocated memory */
|
#define SDL_PREALLOC 0x00000001 /* Surface uses preallocated memory */
|
||||||
#define SDL_SRCALPHA 0x00000004 /* Blit uses source alpha blending */
|
#define SDL_RLEACCEL 0x00000001 /* Surface is RLE encoded */
|
||||||
#define SDL_SRCCOLORKEY 0x00000008 /* Blit uses a source color key */
|
|
||||||
#define SDL_RLEACCELOK 0x00000010 /* Private flag */
|
|
||||||
#define SDL_RLEACCEL 0x00000020 /* Surface is RLE encoded */
|
|
||||||
|
|
||||||
/* Evaluates to true if the surface needs to be locked before access */
|
/* Evaluates to true if the surface needs to be locked before access */
|
||||||
#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0)
|
#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)
|
SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the color key (transparent pixel) in a blittable surface.
|
* \fn int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag)
|
||||||
* If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL),
|
*
|
||||||
* 'key' will be the transparent pixel in the source image of a blit.
|
* \brief Sets the RLE acceleration hint for a surface.
|
||||||
* SDL_RLEACCEL requests RLE acceleration for the surface if present,
|
*
|
||||||
* and removes RLE acceleration if absent.
|
* \return 0 on success, or -1 if the surface is not valid
|
||||||
* If 'flag' is 0, this function clears any current color key.
|
*
|
||||||
* This function returns 0, or -1 if there was an error.
|
* \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
|
extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface *surface, int flag);
|
||||||
(SDL_Surface * surface, Uint32 flag, Uint32 key);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function sets the alpha value for the entire surface, as opposed to
|
* \fn int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key)
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* If 'flag' is 0, alpha blending is disabled for the surface.
|
* \brief Sets the color key (transparent pixel) in a blittable 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.
|
|
||||||
*
|
*
|
||||||
* 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);
|
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.
|
* Sets the clipping rectangle for the destination surface in a blit.
|
||||||
*
|
*
|
||||||
|
|
|
@ -589,6 +589,22 @@ SDL_GetVideoSurface(void)
|
||||||
return SDL_PublicSurface;
|
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_Surface *
|
||||||
SDL_DisplayFormat(SDL_Surface * surface)
|
SDL_DisplayFormat(SDL_Surface * surface)
|
||||||
{
|
{
|
||||||
|
@ -600,15 +616,7 @@ SDL_DisplayFormat(SDL_Surface * surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the flags appropriate for copying to display surface */
|
/* Set the flags appropriate for copying to display surface */
|
||||||
flags = SDL_SWSURFACE;
|
return SDL_ConvertSurface(surface, SDL_PublicSurface->format, SDL_RLEACCELOK);
|
||||||
#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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Surface *
|
SDL_Surface *
|
||||||
|
@ -658,8 +666,7 @@ SDL_DisplayFormatAlpha(SDL_Surface * surface)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
|
format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);
|
||||||
flags = surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
|
converted = SDL_ConvertSurface(surface, format, SDL_RLEACCELOK);
|
||||||
converted = SDL_ConvertSurface(surface, format, flags);
|
|
||||||
SDL_FreeFormat(format);
|
SDL_FreeFormat(format);
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
|
|
|
@ -905,8 +905,7 @@ SDL_RLEBlit(SDL_Surface * src, SDL_Rect * srcrect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA
|
alpha = src->map->info.a;
|
||||||
? src->map->info.a : 255;
|
|
||||||
/* if left or right edge clipping needed, call clip blit */
|
/* if left or right edge clipping needed, call clip blit */
|
||||||
if (srcrect->x || srcrect->w != src->w) {
|
if (srcrect->x || srcrect->w != src->w) {
|
||||||
RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha);
|
RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha);
|
||||||
|
@ -1803,7 +1802,7 @@ RLEColorkeySurface(SDL_Surface * surface)
|
||||||
int
|
int
|
||||||
SDL_RLESurface(SDL_Surface * surface)
|
SDL_RLESurface(SDL_Surface * surface)
|
||||||
{
|
{
|
||||||
int retcode;
|
int flags;
|
||||||
|
|
||||||
/* Clear any previous RLE conversion */
|
/* Clear any previous RLE conversion */
|
||||||
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
|
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
|
||||||
|
@ -1812,34 +1811,44 @@ SDL_RLESurface(SDL_Surface * surface)
|
||||||
|
|
||||||
/* We don't support RLE encoding of bitmaps */
|
/* We don't support RLE encoding of bitmaps */
|
||||||
if (surface->format->BitsPerPixel < 8) {
|
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;
|
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 */
|
/* The surface is now accelerated */
|
||||||
surface->flags |= SDL_RLEACCEL;
|
surface->flags |= SDL_RLEACCEL;
|
||||||
|
@ -1931,13 +1940,12 @@ UnRLEAlpha(SDL_Surface * surface)
|
||||||
void
|
void
|
||||||
SDL_UnRLESurface(SDL_Surface * surface, int recode)
|
SDL_UnRLESurface(SDL_Surface * surface, int recode)
|
||||||
{
|
{
|
||||||
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
|
if (surface->flags & SDL_RLEACCEL) {
|
||||||
surface->flags &= ~SDL_RLEACCEL;
|
surface->flags &= ~SDL_RLEACCEL;
|
||||||
|
|
||||||
if (recode && !(surface->flags & SDL_PREALLOC)) {
|
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;
|
SDL_Rect full;
|
||||||
unsigned alpha_flag;
|
|
||||||
|
|
||||||
/* re-create the original surface */
|
/* re-create the original surface */
|
||||||
surface->pixels = SDL_malloc(surface->h * surface->pitch);
|
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.x = full.y = 0;
|
||||||
full.w = surface->w;
|
full.w = surface->w;
|
||||||
full.h = surface->h;
|
full.h = surface->h;
|
||||||
alpha_flag = surface->flags & SDL_SRCALPHA;
|
|
||||||
surface->flags &= ~SDL_SRCALPHA; /* opaque blit */
|
|
||||||
SDL_RLEBlit(surface, &full, surface, &full);
|
SDL_RLEBlit(surface, &full, surface, &full);
|
||||||
surface->flags |= alpha_flag;
|
|
||||||
} else {
|
} else {
|
||||||
if (!UnRLEAlpha(surface)) {
|
if (!UnRLEAlpha(surface)) {
|
||||||
/* Oh crap... */
|
/* 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);
|
SDL_free(surface->map->data);
|
||||||
surface->map->data = NULL;
|
surface->map->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,7 +206,8 @@ int
|
||||||
SDL_CalculateBlit(SDL_Surface * surface)
|
SDL_CalculateBlit(SDL_Surface * surface)
|
||||||
{
|
{
|
||||||
SDL_BlitFunc blit = NULL;
|
SDL_BlitFunc blit = NULL;
|
||||||
SDL_Surface *dst = surface->map->dst;
|
SDL_BlitMap *map = surface->map;
|
||||||
|
SDL_Surface *dst = map->dst;
|
||||||
Uint32 src_format;
|
Uint32 src_format;
|
||||||
Uint32 dst_format;
|
Uint32 dst_format;
|
||||||
|
|
||||||
|
@ -214,67 +215,48 @@ SDL_CalculateBlit(SDL_Surface * surface)
|
||||||
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
|
if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
|
||||||
SDL_UnRLESurface(surface, 1);
|
SDL_UnRLESurface(surface, 1);
|
||||||
}
|
}
|
||||||
surface->map->blit = NULL;
|
map->blit = SDL_SoftBlit;
|
||||||
surface->map->info.src_fmt = surface->format;
|
map->info.src_fmt = surface->format;
|
||||||
surface->map->info.src_pitch = surface->pitch;
|
map->info.src_pitch = surface->pitch;
|
||||||
surface->map->info.dst_fmt = dst->format;
|
map->info.dst_fmt = dst->format;
|
||||||
surface->map->info.dst_pitch = dst->pitch;
|
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);
|
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);
|
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 (map->identity && !map->info.flags) {
|
||||||
if (surface->map->identity && !surface->map->info.flags) {
|
|
||||||
/* Handle overlapping blits on the same surface */
|
/* Handle overlapping blits on the same surface */
|
||||||
if (surface == dst) {
|
if (surface == dst) {
|
||||||
blit = SDL_BlitCopyOverlap;
|
blit = SDL_BlitCopyOverlap;
|
||||||
} else {
|
} else {
|
||||||
blit = SDL_BlitCopy;
|
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 {
|
} else {
|
||||||
if (surface->format->BitsPerPixel < 8) {
|
blit = SDL_ChooseBlitFunc(src_format, dst_format, map->info.flags, SDL_BlitFuncTableN);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (blit == NULL) {
|
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 */
|
/* Make sure we have a blit function */
|
||||||
if (blit == NULL) {
|
if (blit == NULL) {
|
||||||
SDL_InvalidateMap(surface->map);
|
SDL_InvalidateMap(map);
|
||||||
SDL_SetError("Blit combination not supported");
|
SDL_SetError("Blit combination not supported");
|
||||||
return (-1);
|
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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,23 +41,26 @@
|
||||||
#include "SDL_endian.h"
|
#include "SDL_endian.h"
|
||||||
|
|
||||||
/* SDL blit copy flags */
|
/* SDL blit copy flags */
|
||||||
#define SDL_COPY_MODULATE_COLOR 0x0001
|
#define SDL_COPY_MODULATE_COLOR 0x00000001
|
||||||
#define SDL_COPY_MODULATE_ALPHA 0x0002
|
#define SDL_COPY_MODULATE_ALPHA 0x00000002
|
||||||
#define SDL_COPY_MASK 0x0010
|
#define SDL_COPY_MASK 0x00000010
|
||||||
#define SDL_COPY_BLEND 0x0020
|
#define SDL_COPY_BLEND 0x00000020
|
||||||
#define SDL_COPY_ADD 0x0040
|
#define SDL_COPY_ADD 0x00000040
|
||||||
#define SDL_COPY_MOD 0x0080
|
#define SDL_COPY_MOD 0x00000080
|
||||||
#define SDL_COPY_COLORKEY 0x0100
|
#define SDL_COPY_COLORKEY 0x00000100
|
||||||
#define SDL_COPY_NEAREST 0x0200
|
#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 */
|
/* SDL blit CPU flags */
|
||||||
#define SDL_CPU_ANY 0x0000
|
#define SDL_CPU_ANY 0x00000000
|
||||||
#define SDL_CPU_MMX 0x0001
|
#define SDL_CPU_MMX 0x00000001
|
||||||
#define SDL_CPU_3DNOW 0x0002
|
#define SDL_CPU_3DNOW 0x00000002
|
||||||
#define SDL_CPU_SSE 0x0004
|
#define SDL_CPU_SSE 0x00000004
|
||||||
#define SDL_CPU_SSE2 0x0008
|
#define SDL_CPU_SSE2 0x00000008
|
||||||
#define SDL_CPU_ALTIVEC_PREFETCH 0x0010
|
#define SDL_CPU_ALTIVEC_PREFETCH 0x00000010
|
||||||
#define SDL_CPU_ALTIVEC_NOPREFETCH 0x0020
|
#define SDL_CPU_ALTIVEC_NOPREFETCH 0x00000020
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Uint8 *src;
|
Uint8 *src;
|
||||||
|
|
|
@ -212,153 +212,251 @@ SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag)
|
||||||
* Set the color key in a blittable surface
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
SDL_SetColorKey(SDL_Surface * surface, Uint32 flag, Uint32 key)
|
|
||||||
{
|
{
|
||||||
/* Sanity check the flag as it gets passed in */
|
Uint32 flags;
|
||||||
if (flag & SDL_SRCCOLORKEY) {
|
|
||||||
if (flag & (SDL_RLEACCEL | SDL_RLEACCELOK)) {
|
|
||||||
flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
|
|
||||||
} else {
|
|
||||||
flag = SDL_SRCCOLORKEY;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
flag = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Optimize away operations that don't change anything */
|
if (!surface) {
|
||||||
if ((flag == (surface->flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK))) &&
|
return -1;
|
||||||
(key == surface->map->ckey)) {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UnRLE surfaces before we change the colorkey */
|
|
||||||
if (surface->flags & SDL_RLEACCEL) {
|
|
||||||
SDL_UnRLESurface(surface, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag) {
|
if (flag) {
|
||||||
surface->flags |= SDL_SRCCOLORKEY;
|
|
||||||
surface->map->ckey = key;
|
|
||||||
if (flag & SDL_RLEACCELOK) {
|
|
||||||
surface->flags |= SDL_RLEACCELOK;
|
surface->flags |= SDL_RLEACCELOK;
|
||||||
} else {
|
} else {
|
||||||
surface->flags &= ~SDL_RLEACCELOK;
|
surface->flags &= ~SDL_RLEACCELOK;
|
||||||
}
|
}
|
||||||
} else {
|
if (surface->flags != flags) {
|
||||||
surface->flags &= ~(SDL_SRCCOLORKEY | SDL_RLEACCELOK);
|
|
||||||
surface->map->ckey = 0;
|
|
||||||
}
|
|
||||||
SDL_InvalidateMap(surface->map);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key)
|
||||||
* Set the clipping rectangle for a blittable surface
|
{
|
||||||
*/
|
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_bool
|
||||||
SDL_SetClipRect(SDL_Surface * surface, const SDL_Rect * rect)
|
SDL_SetClipRect(SDL_Surface * surface, const SDL_Rect * rect)
|
||||||
{
|
{
|
||||||
|
@ -557,9 +655,7 @@ SDL_ConvertSurface(SDL_Surface * surface,
|
||||||
SDL_PixelFormat * format, Uint32 flags)
|
SDL_PixelFormat * format, Uint32 flags)
|
||||||
{
|
{
|
||||||
SDL_Surface *convert;
|
SDL_Surface *convert;
|
||||||
Uint32 colorkey = 0;
|
Uint32 copy_flags;
|
||||||
Uint8 alpha = 0;
|
|
||||||
Uint32 surface_flags;
|
|
||||||
SDL_Rect bounds;
|
SDL_Rect bounds;
|
||||||
|
|
||||||
/* Check for empty destination palette! (results in empty image) */
|
/* 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 */
|
/* Create a new surface with the desired format */
|
||||||
convert = SDL_CreateRGBSurface(flags,
|
convert = SDL_CreateRGBSurface(0, surface->w, surface->h,
|
||||||
surface->w, surface->h,
|
|
||||||
format->BitsPerPixel, format->Rmask,
|
format->BitsPerPixel, format->Rmask,
|
||||||
format->Gmask, format->Bmask,
|
format->Gmask, format->Bmask,
|
||||||
format->Amask);
|
format->Amask);
|
||||||
|
@ -595,26 +690,9 @@ SDL_ConvertSurface(SDL_Surface * surface,
|
||||||
convert->format->palette->ncolors = format->palette->ncolors;
|
convert->format->palette->ncolors = format->palette->ncolors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the original surface color key and alpha */
|
/* Save the original copy flags */
|
||||||
surface_flags = surface->flags;
|
copy_flags = surface->map->info.flags;
|
||||||
if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
|
surface->map->info.flags = 0;
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy over the image data */
|
/* Copy over the image data */
|
||||||
bounds.x = 0;
|
bounds.x = 0;
|
||||||
|
@ -624,30 +702,25 @@ SDL_ConvertSurface(SDL_Surface * surface,
|
||||||
SDL_LowerBlit(surface, &bounds, convert, &bounds);
|
SDL_LowerBlit(surface, &bounds, convert, &bounds);
|
||||||
|
|
||||||
/* Clean up the original surface, and update converted surface */
|
/* Clean up the original surface, and update converted surface */
|
||||||
if (convert != NULL) {
|
|
||||||
SDL_SetClipRect(convert, &surface->clip_rect);
|
SDL_SetClipRect(convert, &surface->clip_rect);
|
||||||
}
|
if (copy_flags & SDL_COPY_COLORKEY) {
|
||||||
if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
|
Uint8 keyR, keyG, keyB, keyA;
|
||||||
Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
|
|
||||||
if (convert != NULL) {
|
|
||||||
Uint8 keyR, keyG, keyB;
|
|
||||||
|
|
||||||
SDL_GetRGB(colorkey, surface->format, &keyR, &keyG, &keyB);
|
SDL_GetRGBA(colorkey, surface->format, &keyR, &keyG, &keyB, &keyA);
|
||||||
SDL_SetColorKey(convert, cflags | (flags & SDL_RLEACCELOK),
|
SDL_SetColorKey(convert, 1,
|
||||||
SDL_MapRGB(convert->format, keyR, keyG, keyB));
|
SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA));
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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! */
|
/* We're ready to go! */
|
||||||
|
|
|
@ -1535,8 +1535,7 @@ SDL_TextureID
|
||||||
SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
|
SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
|
||||||
{
|
{
|
||||||
SDL_TextureID textureID;
|
SDL_TextureID textureID;
|
||||||
Uint32 surface_flags = surface->flags;
|
SDL_PixelFormat *fmt;
|
||||||
SDL_PixelFormat *fmt = surface->format;
|
|
||||||
int bpp;
|
int bpp;
|
||||||
Uint32 Rmask, Gmask, Bmask, Amask;
|
Uint32 Rmask, Gmask, Bmask, Amask;
|
||||||
|
|
||||||
|
@ -1544,6 +1543,7 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
|
||||||
SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
|
SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
fmt = surface->format;
|
||||||
|
|
||||||
if (format) {
|
if (format) {
|
||||||
if (!SDL_PixelFormatEnumToMasks
|
if (!SDL_PixelFormatEnumToMasks
|
||||||
|
@ -1552,7 +1552,7 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
bpp = fmt->BitsPerPixel;
|
||||||
Rmask = fmt->Rmask;
|
Rmask = fmt->Rmask;
|
||||||
Gmask = fmt->Gmask;
|
Gmask = fmt->Gmask;
|
||||||
|
@ -1595,92 +1595,38 @@ SDL_CreateTextureFromSurface(Uint32 format, SDL_Surface * surface)
|
||||||
surface->pitch);
|
surface->pitch);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Uint32 cmod;
|
SDL_PixelFormat *dst_fmt;
|
||||||
SDL_Rect bounds;
|
SDL_Surface *dst = NULL;
|
||||||
SDL_Surface dst;
|
|
||||||
|
|
||||||
/* Set up a destination surface for the texture update */
|
/* Set up a destination surface for the texture update */
|
||||||
SDL_zero(dst);
|
dst_fmt = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
|
||||||
dst.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
|
if (dst_fmt) {
|
||||||
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 (SDL_ISPIXELFORMAT_INDEXED(format)) {
|
||||||
|
dst_fmt->palette = SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format)));
|
||||||
|
if (dst_fmt->palette) {
|
||||||
if (fmt->palette) {
|
if (fmt->palette) {
|
||||||
SDL_SetTexturePalette(textureID, fmt->palette->colors, 0,
|
fixme
|
||||||
fmt->palette->ncolors);
|
|
||||||
SDL_SetSurfacePalette(&dst, fmt->palette);
|
|
||||||
} else {
|
} else {
|
||||||
dst.format->palette =
|
SDL_DitherColors(dst_fmt->palette->colors, SDL_BITSPERPIXEL(format));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fmt->palette) {
|
||||||
/* Make the texture transparent if the surface has colorkey */
|
dst_fmt->palette = fmt->palette;
|
||||||
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;
|
|
||||||
} else {
|
} 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 */
|
cvt = SDL_ConvertSurface(surface, fmt, 0);
|
||||||
bounds.x = 0;
|
if (cvt) {
|
||||||
bounds.y = 0;
|
SDL_UpdateTexture(textureID, NULL, cvt->pixels, cvt->pitch);
|
||||||
bounds.w = surface->w;
|
SDL_FreeSurface(cvt);
|
||||||
bounds.h = surface->h;
|
}
|
||||||
SDL_LowerBlit(surface, &bounds, &dst, &bounds);
|
SDL_FreeFormat(fmt);
|
||||||
|
|
||||||
/* 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 */
|
if (SDL_ISPIXELFORMAT_INDEXED(format) && fmt->palette) {
|
||||||
SDL_UpdateTexture(textureID, NULL, dst.pixels, dst.pitch);
|
SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, fmt->palette->ncolors);
|
||||||
SDL_free(dst.pixels);
|
|
||||||
SDL_FreeFormat(dst.format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return textureID;
|
return textureID;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue