Misc gfx fixes: Better .ani transparency spec (bug #128); Reliable surface transparency in OpenGL mode; Colorkey transparency handling in 32bpp trilinear; --meleescale=nearest fixed (bug #126)
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1536 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -50,10 +50,24 @@ process_image (FRAMEPTR FramePtr, SDL_Surface *img[], AniData *ani, int cel_ct)
|
||||
TYPE_SET (FramePtr->TypeIndexAndFlags, ROM_DRAWABLE);
|
||||
INDEX_SET (FramePtr->TypeIndexAndFlags, cel_ct);
|
||||
|
||||
// handle transparency cases
|
||||
if (img[cel_ct]->format->palette)
|
||||
{
|
||||
{ // indexed color image
|
||||
if (ani[cel_ct].transparent_color != -1)
|
||||
SDL_SetColorKey(img[cel_ct], SDL_SRCCOLORKEY, ani[cel_ct].transparent_color);
|
||||
SDL_SetColorKey (img[cel_ct], SDL_SRCCOLORKEY,
|
||||
ani[cel_ct].transparent_color);
|
||||
}
|
||||
else if (img[cel_ct]->format->BitsPerPixel > 8)
|
||||
{ // special transparency cases for truecolor images
|
||||
if (ani[cel_ct].transparent_color == 0)
|
||||
// make RGB=0,0,0 transparent
|
||||
SDL_SetColorKey (img[cel_ct], SDL_SRCCOLORKEY,
|
||||
SDL_MapRGB (img[cel_ct]->format, 0, 0, 0));
|
||||
}
|
||||
if (ani[cel_ct].transparent_color == -1)
|
||||
{ // enforce -1 to mean 'no transparency'
|
||||
SDL_SetColorKey (img[cel_ct], 0, 0);
|
||||
// set transparent_color == -2 to use PNG tRNS transparency
|
||||
}
|
||||
|
||||
hx = ani[cel_ct].hotspot_x;
|
||||
|
||||
@@ -474,13 +474,14 @@ TFB_DrawCanvas_GetExtent (TFB_Canvas canvas, PEXTENT size)
|
||||
void
|
||||
TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, EXTENT size)
|
||||
{
|
||||
#define NNS_MAX_DIMS 600
|
||||
SDL_Surface *src = (SDL_Surface *)src_canvas;
|
||||
SDL_Surface *dst = (SDL_Surface *)dest_canvas;
|
||||
int x, y, sx, sy, *csax, *csay, csx, csy;
|
||||
int saspace[602];
|
||||
int saspace[NNS_MAX_DIMS];
|
||||
int *sax, *say;
|
||||
|
||||
if (size.width + size.height > 600)
|
||||
if (size.width + size.height > NNS_MAX_DIMS)
|
||||
{
|
||||
fprintf (stderr, "TFB_DrawCanvas_Scale: Tried to zoom an image to unreasonable size! Failing.\n");
|
||||
return;
|
||||
@@ -492,25 +493,28 @@ TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, E
|
||||
return;
|
||||
}
|
||||
|
||||
sx = (int) (65536.0 * (float) src->w / (float) size.width);
|
||||
sy = (int) (65536.0 * (float) src->h / (float) size.height);
|
||||
sx = sy = 0;
|
||||
if (size.width > 1)
|
||||
sx = 65536 * (src->w - 1) / (size.width - 1);
|
||||
if (size.height > 1)
|
||||
sy = 65536 * (src->h - 1) / (size.height - 1);
|
||||
|
||||
sax = saspace;
|
||||
say = saspace + size.width + 1;
|
||||
say = saspace + size.width;
|
||||
/*
|
||||
* Precalculate row increments
|
||||
* We start with a value in 0..0.5 range to shift the bigger
|
||||
* jumps towards the center of the image
|
||||
*/
|
||||
csx = 0;
|
||||
csax = sax;
|
||||
for (x = 0; x <= size.width; x++) {
|
||||
for (x = 0, csx = 0x6000; x < size.width; x++) {
|
||||
*csax = csx >> 16;
|
||||
csax++;
|
||||
csx &= 0xffff;
|
||||
csx += sx;
|
||||
}
|
||||
csy = 0;
|
||||
csay = say;
|
||||
for (y = 0; y <= size.height; y++) {
|
||||
for (y = 0, csy = 0x6000; y < size.height; y++) {
|
||||
*csay = csy >> 16;
|
||||
csay++;
|
||||
csy &= 0xffff;
|
||||
@@ -529,17 +533,17 @@ TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, E
|
||||
|
||||
csay = say;
|
||||
for (y = 0; y < size.height; ++y) {
|
||||
csp += (*csay) * src->pitch;
|
||||
sp = csp;
|
||||
dp = cdp;
|
||||
csax = sax;
|
||||
for (x = 0; x < size.width; ++x) {
|
||||
sp += *csax;
|
||||
*dp = *sp;
|
||||
++csax;
|
||||
sp += *csax;
|
||||
++dp;
|
||||
}
|
||||
++csay;
|
||||
csp += (*csay) * src->pitch;
|
||||
cdp += dst->pitch;
|
||||
}
|
||||
}
|
||||
@@ -556,17 +560,17 @@ TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, E
|
||||
|
||||
csay = say;
|
||||
for (y = 0; y < size.height; ++y) {
|
||||
csp += (*csay) * sgap;
|
||||
sp = csp;
|
||||
dp = cdp;
|
||||
csax = sax;
|
||||
for (x = 0; x < size.width; ++x) {
|
||||
sp += *csax;
|
||||
*dp = *sp;
|
||||
++csax;
|
||||
sp += *csax;
|
||||
++dp;
|
||||
}
|
||||
++csay;
|
||||
csp += (*csay) * sgap;
|
||||
cdp += dgap;
|
||||
}
|
||||
}
|
||||
@@ -804,6 +808,14 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
|
||||
int fsy1 = (int)(65536.0f * (float)mipmap->h / h);
|
||||
int sx0 = 0, sy0 = 0, sx1 = 0, sy1 = 0;
|
||||
int x, y;
|
||||
Uint32 ck0 = 0; // 0 means alpha=0 too, so it's safe
|
||||
Uint32 ck1 = 0;
|
||||
|
||||
// use colorkeys where appropriate
|
||||
if (src->flags & SDL_SRCCOLORKEY)
|
||||
ck0 = src->format->colorkey;
|
||||
if (mipmap->flags & SDL_SRCCOLORKEY)
|
||||
ck1 = mipmap->format->colorkey;
|
||||
|
||||
SDL_LockSurface(src);
|
||||
SDL_LockSurface(dst);
|
||||
@@ -839,10 +851,19 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
|
||||
{
|
||||
SDL_GetRGBA (*src_p0, src->format, &r0[0], &g0[0], &b0[0], &a0[0]);
|
||||
SDL_GetRGBA (*(src_p0 + 1), src->format, &r0[1], &g0[1], &b0[1], &a0[1]);
|
||||
if (src_p0[0] == ck0)
|
||||
a0[0] = 0;
|
||||
if (src_p0[1] == ck0)
|
||||
a0[1] = 0;
|
||||
|
||||
if ((sy0 >> 16) <= src->h - 2)
|
||||
{
|
||||
SDL_GetRGBA (*(src_p0 + src->w), src->format, &r0[2], &g0[2], &b0[2], &a0[2]);
|
||||
SDL_GetRGBA (*(src_p0 + src->w + 1), src->format, &r0[3], &g0[3], &b0[3], &a0[3]);
|
||||
if (src_p0[src->w] == ck0)
|
||||
a0[2] = 0;
|
||||
if (src_p0[src->w + 1] == ck0)
|
||||
a0[3] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -859,6 +880,8 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
|
||||
else
|
||||
{
|
||||
SDL_GetRGBA (*src_p0, src->format, &r0[0], &g0[0], &b0[0], &a0[0]);
|
||||
if (src_p0[0] == ck0)
|
||||
a0[0] = 0;
|
||||
r0[1] = r0[0];
|
||||
g0[1] = g0[0];
|
||||
b0[1] = b0[0];
|
||||
@@ -866,6 +889,8 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
|
||||
if ((sy0 >> 16) <= src->h - 2)
|
||||
{
|
||||
SDL_GetRGBA (*(src_p0 + src->w), src->format, &r0[2], &g0[2], &b0[2], &a0[2]);
|
||||
if (src_p0[src->w] == ck0)
|
||||
a0[2] = 0;
|
||||
r0[3] = r0[2];
|
||||
g0[3] = g0[2];
|
||||
b0[3] = b0[2];
|
||||
@@ -884,10 +909,19 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
|
||||
{
|
||||
SDL_GetRGBA (*src_p1, mipmap->format, &r1[0], &g1[0], &b1[0], &a1[0]);
|
||||
SDL_GetRGBA (*(src_p1 + 1), mipmap->format, &r1[1], &g1[1], &b1[1], &a1[1]);
|
||||
if (src_p1[0] == ck1)
|
||||
a1[0] = 0;
|
||||
if (src_p1[1] == ck1)
|
||||
a1[1] = 0;
|
||||
|
||||
if ((sy1 >> 16) <= mipmap->h - 2)
|
||||
{
|
||||
SDL_GetRGBA (*(src_p1 + mipmap->w) , mipmap->format, &r1[2], &g1[2], &b1[2], &a1[2]);
|
||||
SDL_GetRGBA (*(src_p1 + mipmap->w + 1), mipmap->format, &r1[3], &g1[3], &b1[3], &a1[3]);
|
||||
if (src_p1[mipmap->w] == ck1)
|
||||
a1[2] = 0;
|
||||
if (src_p1[mipmap->w + 1] == ck1)
|
||||
a1[3] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -904,6 +938,8 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
|
||||
else
|
||||
{
|
||||
SDL_GetRGBA (*src_p1, mipmap->format, &r1[0], &g1[0], &b1[0], &a1[0]);
|
||||
if (src_p1[0] == ck1)
|
||||
a1[0] = 0;
|
||||
r1[1] = r1[0];
|
||||
g1[1] = g1[0];
|
||||
b1[1] = b1[0];
|
||||
@@ -911,6 +947,8 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
|
||||
if ((sy1 >> 16) <= mipmap->h - 2)
|
||||
{
|
||||
SDL_GetRGBA (*(src_p1 + mipmap->w), mipmap->format, &r1[2], &g1[2], &b1[2], &a1[2]);
|
||||
if (src_p1[mipmap->w] == ck1)
|
||||
a1[2] = 0;
|
||||
r1[3] = r1[2];
|
||||
g1[3] = g1[2];
|
||||
b1[3] = b1[2];
|
||||
|
||||
@@ -443,15 +443,22 @@ TFB_GL_SwapBuffers (int force_full_redraw)
|
||||
TFB_GL_ScanLines ();
|
||||
|
||||
SDL_GL_SwapBuffers ();
|
||||
|
||||
/* remove compiler warning */
|
||||
(void) force_full_redraw;
|
||||
}
|
||||
|
||||
SDL_Surface*
|
||||
TFB_GL_DisplayFormatAlpha (SDL_Surface *surface)
|
||||
{
|
||||
return SDL_ConvertSurface (surface, format_conv_surf->format, surface->flags);
|
||||
SDL_Surface* newsurf;
|
||||
|
||||
newsurf = SDL_ConvertSurface (surface, format_conv_surf->format, surface->flags);
|
||||
// SDL_SRCCOLORKEY and SDL_SRCALPHA cannot work at the same time,
|
||||
// so we need to disable one of them
|
||||
if ((surface->flags & SDL_SRCCOLORKEY) && newsurf
|
||||
&& (newsurf->flags & SDL_SRCCOLORKEY)
|
||||
&& (newsurf->flags & SDL_SRCALPHA))
|
||||
SDL_SetAlpha (newsurf, 0, 255);
|
||||
|
||||
return newsurf;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -331,7 +331,6 @@ TFB_DrawImage_New_Rotated (TFB_Image *img, int angle)
|
||||
TFB_Canvas dst;
|
||||
EXTENT size;
|
||||
TFB_Image* newimg;
|
||||
int r, g, b;
|
||||
|
||||
/* sanity check */
|
||||
if (!img->NormalImg)
|
||||
@@ -352,13 +351,6 @@ TFB_DrawImage_New_Rotated (TFB_Image *img, int angle)
|
||||
TFB_DrawCanvas_Rotate (img->NormalImg, dst, angle, size);
|
||||
|
||||
newimg = TFB_DrawImage_New (dst);
|
||||
if (newimg && TFB_DrawCanvas_GetTransparentColor (
|
||||
newimg->NormalImg, &r, &g, &b))
|
||||
{ /* reset colorkey info to clear potential SRCALPHA */
|
||||
TFB_DrawCanvas_SetTransparentColor (newimg->NormalImg,
|
||||
r, g, b, FALSE);
|
||||
}
|
||||
|
||||
return newimg;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user