diff options
-rw-r--r-- | sword2/driver/render.cpp | 90 | ||||
-rw-r--r-- | sword2/driver/sprite.cpp | 5 |
2 files changed, 86 insertions, 9 deletions
diff --git a/sword2/driver/render.cpp b/sword2/driver/render.cpp index 3bdc306f97..eeb79188a0 100644 --- a/sword2/driver/render.cpp +++ b/sword2/driver/render.cpp @@ -353,10 +353,14 @@ static uint16 yScale[SCALE_MAXHEIGHT]; // DrawSprite() where it wasn't obvious if the sprite should grow or shrink, // which caused crashes. // -// Maybe the functions can be merged later? +// Keeping them separate might be a good idea anyway, for readability. // // The code is based on the original DrawSprite() code, so apart from not // knowing if I got it right, I don't know how good the original really is. +// +// The backbuf parameter points to the buffer where the image will eventually +// be drawn. This is only used at the highest graphics detail setting (and not +// always even then) and is used to help anti-alias the image. void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight, byte *backbuf) { int32 ince, incne, d; @@ -402,7 +406,7 @@ void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, yScale[y] = x; } - // Copy the image + // Copy the image (with or without anti-aliasing) if (backbuf) { for (y = 0; y < dstHeight; y++) { @@ -454,6 +458,7 @@ void SquashImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, } void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, byte *src, uint16 srcPitch, uint16 srcWidth, uint16 srcHeight, byte *backbuf) { + byte *origDst = dst; int32 ince, incne, d; int16 x, y, i, j, k; @@ -498,8 +503,6 @@ void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, // Copy the image - // FIXME: If backbuf != NULL the image should be anti-aliased - for (y = 0; y < srcHeight; y++) { for (j = yScale[y]; j < yScale[y + 1]; j++) { k = 0; @@ -511,6 +514,85 @@ void StretchImage(byte *dst, uint16 dstPitch, uint16 dstWidth, uint16 dstHeight, dst += dstPitch; } } + + // Anti-aliasing + + if (backbuf) { + byte *newDst = (byte *) malloc(dstWidth * dstHeight); + if (!newDst) + return; + + memcpy(newDst, origDst, dstWidth); + + for (y = 1; y < dstHeight - 1; y++) { + src = origDst + y * dstPitch; + dst = newDst + y * dstWidth; + *dst++ = *src++; + for (x = 1; x < dstWidth - 1; x++) { + byte pt[5]; + byte *p = backbuf + y * 640 + x; + int count = 0; + + if (*src) { + count++; + pt[0] = *src; + } else + pt[0] = *p; + + pt[1] = *(src - dstPitch); + if (pt[1] == 0) + pt[1] = *(p - 640); + else + count++; + + pt[2] = *(src - 1); + if (pt[2] == 0) + pt[2] = *(p - 1); + else + count++; + + pt[3] = *(src + 1); + if (pt[3] == 0) + pt[3] = *(p + 1); + else + count++; + + pt[4] = *(src + dstPitch); + if (pt[4] == 0) + pt[4] = *(p + 640); + else + count++; + + if (count) { + int red = palCopy[pt[0]][0] << 2; + int green = palCopy[pt[0]][1] << 2; + int blue = palCopy[pt[0]][2] << 2; + for (i = 1; i < 5; i++) { + red += palCopy[pt[i]][0]; + green += palCopy[pt[i]][1]; + blue += palCopy[pt[i]][2]; + } + + *dst++ = QuickMatch((uint8) (red >> 3), (uint8) (green >> 3), (uint8) (blue >> 3)); + } else + *dst++ = 0; + src++; + } + *dst++ = *src++; + } + memcpy(dst, src, dstWidth); + + src = newDst; + dst = origDst; + + for (i = 0; i < dstHeight; i++) { + memcpy(dst, src, dstWidth); + dst += dstPitch; + src += dstWidth; + } + + free(newDst); + } } int32 RestoreBackgroundLayer(_parallax *p, int16 l) diff --git a/sword2/driver/sprite.cpp b/sword2/driver/sprite.cpp index 023b61f35c..82d7a76a69 100644 --- a/sword2/driver/sprite.cpp +++ b/sword2/driver/sprite.cpp @@ -1357,11 +1357,6 @@ int32 DrawSprite(_spriteInfo *s) { bool clipped = false; ScummVM::Rect rd, rs; - // FIXME: There are still a few minor details that I think the - // original did. Off-hand, I know that at the highest graphics - // quality setting sprites should be anti-aliased when they are - // upscaled. - // ----------------------------------------------------------------- // Decompression and mirroring // ----------------------------------------------------------------- |