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);
|
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;
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user