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:
avolkov
2005-02-14 10:27:12 +00:00
parent 2d10c1c0e6
commit 49f8e058bd
4 changed files with 78 additions and 27 deletions
@@ -50,10 +50,24 @@ process_image (FRAMEPTR FramePtr, SDL_Surface *img[], AniData *ani, int cel_ct)
TYPE_SET (FramePtr->TypeIndexAndFlags, ROM_DRAWABLE); TYPE_SET (FramePtr->TypeIndexAndFlags, ROM_DRAWABLE);
INDEX_SET (FramePtr->TypeIndexAndFlags, cel_ct); INDEX_SET (FramePtr->TypeIndexAndFlags, cel_ct);
// handle transparency cases
if (img[cel_ct]->format->palette) if (img[cel_ct]->format->palette)
{ { // indexed color image
if (ani[cel_ct].transparent_color != -1) 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; hx = ani[cel_ct].hotspot_x;
+51 -13
View File
@@ -474,13 +474,14 @@ TFB_DrawCanvas_GetExtent (TFB_Canvas canvas, PEXTENT size)
void void
TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, EXTENT size) 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 *src = (SDL_Surface *)src_canvas;
SDL_Surface *dst = (SDL_Surface *)dest_canvas; SDL_Surface *dst = (SDL_Surface *)dest_canvas;
int x, y, sx, sy, *csax, *csay, csx, csy; int x, y, sx, sy, *csax, *csay, csx, csy;
int saspace[602]; int saspace[NNS_MAX_DIMS];
int *sax, *say; 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"); fprintf (stderr, "TFB_DrawCanvas_Scale: Tried to zoom an image to unreasonable size! Failing.\n");
return; return;
@@ -492,25 +493,28 @@ TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, E
return; return;
} }
sx = (int) (65536.0 * (float) src->w / (float) size.width); sx = sy = 0;
sy = (int) (65536.0 * (float) src->h / (float) size.height); 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; sax = saspace;
say = saspace + size.width + 1; say = saspace + size.width;
/* /*
* Precalculate row increments * 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; csax = sax;
for (x = 0; x <= size.width; x++) { for (x = 0, csx = 0x6000; x < size.width; x++) {
*csax = csx >> 16; *csax = csx >> 16;
csax++; csax++;
csx &= 0xffff; csx &= 0xffff;
csx += sx; csx += sx;
} }
csy = 0;
csay = say; csay = say;
for (y = 0; y <= size.height; y++) { for (y = 0, csy = 0x6000; y < size.height; y++) {
*csay = csy >> 16; *csay = csy >> 16;
csay++; csay++;
csy &= 0xffff; csy &= 0xffff;
@@ -529,17 +533,17 @@ TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, E
csay = say; csay = say;
for (y = 0; y < size.height; ++y) { for (y = 0; y < size.height; ++y) {
csp += (*csay) * src->pitch;
sp = csp; sp = csp;
dp = cdp; dp = cdp;
csax = sax; csax = sax;
for (x = 0; x < size.width; ++x) { for (x = 0; x < size.width; ++x) {
sp += *csax;
*dp = *sp; *dp = *sp;
++csax; ++csax;
sp += *csax;
++dp; ++dp;
} }
++csay; ++csay;
csp += (*csay) * src->pitch;
cdp += dst->pitch; cdp += dst->pitch;
} }
} }
@@ -556,17 +560,17 @@ TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, E
csay = say; csay = say;
for (y = 0; y < size.height; ++y) { for (y = 0; y < size.height; ++y) {
csp += (*csay) * sgap;
sp = csp; sp = csp;
dp = cdp; dp = cdp;
csax = sax; csax = sax;
for (x = 0; x < size.width; ++x) { for (x = 0; x < size.width; ++x) {
sp += *csax;
*dp = *sp; *dp = *sp;
++csax; ++csax;
sp += *csax;
++dp; ++dp;
} }
++csay; ++csay;
csp += (*csay) * sgap;
cdp += dgap; 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 fsy1 = (int)(65536.0f * (float)mipmap->h / h);
int sx0 = 0, sy0 = 0, sx1 = 0, sy1 = 0; int sx0 = 0, sy0 = 0, sx1 = 0, sy1 = 0;
int x, y; 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(src);
SDL_LockSurface(dst); 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, 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]); 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) 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), 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]); 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 else
{ {
@@ -859,6 +880,8 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
else else
{ {
SDL_GetRGBA (*src_p0, src->format, &r0[0], &g0[0], &b0[0], &a0[0]); 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]; r0[1] = r0[0];
g0[1] = g0[0]; g0[1] = g0[0];
b0[1] = b0[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) 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), src->format, &r0[2], &g0[2], &b0[2], &a0[2]);
if (src_p0[src->w] == ck0)
a0[2] = 0;
r0[3] = r0[2]; r0[3] = r0[2];
g0[3] = g0[2]; g0[3] = g0[2];
b0[3] = b0[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, 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]); 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) 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) , 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]); 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 else
{ {
@@ -904,6 +938,8 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas,
else else
{ {
SDL_GetRGBA (*src_p1, mipmap->format, &r1[0], &g1[0], &b1[0], &a1[0]); 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]; r1[1] = r1[0];
g1[1] = g1[0]; g1[1] = g1[0];
b1[1] = b1[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) 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), mipmap->format, &r1[2], &g1[2], &b1[2], &a1[2]);
if (src_p1[mipmap->w] == ck1)
a1[2] = 0;
r1[3] = r1[2]; r1[3] = r1[2];
g1[3] = g1[2]; g1[3] = g1[2];
b1[3] = b1[2]; b1[3] = b1[2];
+11 -4
View File
@@ -443,15 +443,22 @@ TFB_GL_SwapBuffers (int force_full_redraw)
TFB_GL_ScanLines (); TFB_GL_ScanLines ();
SDL_GL_SwapBuffers (); SDL_GL_SwapBuffers ();
/* remove compiler warning */
(void) force_full_redraw;
} }
SDL_Surface* SDL_Surface*
TFB_GL_DisplayFormatAlpha (SDL_Surface *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 #endif
-8
View File
@@ -331,7 +331,6 @@ TFB_DrawImage_New_Rotated (TFB_Image *img, int angle)
TFB_Canvas dst; TFB_Canvas dst;
EXTENT size; EXTENT size;
TFB_Image* newimg; TFB_Image* newimg;
int r, g, b;
/* sanity check */ /* sanity check */
if (!img->NormalImg) if (!img->NormalImg)
@@ -352,13 +351,6 @@ TFB_DrawImage_New_Rotated (TFB_Image *img, int angle)
TFB_DrawCanvas_Rotate (img->NormalImg, dst, angle, size); TFB_DrawCanvas_Rotate (img->NormalImg, dst, angle, size);
newimg = TFB_DrawImage_New (dst); 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; return newimg;
} }