--- a/hedgewars/uRenderUtils.pas Sat Dec 03 09:09:16 2016 +0100
+++ b/hedgewars/uRenderUtils.pas Sat Dec 03 13:51:57 2016 +0100
@@ -149,9 +149,9 @@
end;
procedure copyToXYFromRect(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt);
-var i, j, iX, iY, dX, dY, lX, lY: LongInt;
+var spi, dpi, iX, iY, dX, dY, lX, lY, aT: LongInt;
srcPixels, destPixels: PLongWordArray;
- r0, g0, b0, a0, r1, g1, b1, a1: Byte;
+ rD, gD, bD, aD, rT, gT, bT: Byte;
begin
SDL_LockSurface(src);
SDL_LockSurface(dest);
@@ -164,24 +164,51 @@
dY:= destY - srcY;
// let's figure out where the rectangle we can actually copy ends
- lX:= ( min( min(srcX + srcW, src^.w), min(destX + srcW + dx, dest^.w) - dx ) ) - 1;
- lY:= ( min( min(srcY + srcH, src^.h), min(destY + srcH + dy, dest^.h) - dY ) ) - 1;
+ lX:= ( min( min(srcX + srcW, src^.w), min(destX + srcW, dest^.w) - dx ) ) - 1;
+ lY:= ( min( min(srcY + srcH, src^.h), min(destY + srcH, dest^.h) - dY ) ) - 1;
for iX:= srcX to lX do
for iY:= srcY to lY do
begin
- i:= (iY + dY) * dest^.w + (iX + dX);
- j:= iY * src^.w + iX;
- if srcPixels^[j] and AMask <> 0 then
+ // src pixel index
+ spi:= iY * src^.w + iX;
+ // dest pixel index
+ dpi:= (iY + dY) * dest^.w + (iX + dX);
+
+ // get src alpha (and set it as target alpha for now)
+ aT:= (srcPixels^[spi] and AMask) shr AShift;
+
+ // src pixel opaque?
+ if aT = 255 then
begin
- SDL_GetRGBA(destPixels^[i], dest^.format, @r0, @g0, @b0, @a0);
- SDL_GetRGBA(srcPixels^[j], src^.format, @r1, @g1, @b1, @a1);
- r0:= (r0 * (255 - LongInt(a1)) + r1 * LongInt(a1)) div 255;
- g0:= (g0 * (255 - LongInt(a1)) + g1 * LongInt(a1)) div 255;
- b0:= (b0 * (255 - LongInt(a1)) + b1 * LongInt(a1)) div 255;
- a0:= a0 + ((255 - LongInt(a0)) * a1 div 255);
- destPixels^[i]:= SDL_MapRGBA(dest^.format, r0, g0, b0, a0);
+ // just copy full pixel
+ destPixels^[dpi]:= srcPixels^[spi];
+ continue;
end;
+
+ // get dst alpha (without shift for now)
+ aD:= (destPixels^[dpi] and AMask) shr AShift;
+
+ // dest completely transparent?
+ if aD = 0 then
+ begin
+ // just copy src pixel
+ destPixels^[dpi]:= srcPixels^[spi];
+ continue;
+ end;
+
+ // looks like some blending is necessary
+
+ // set color of target RGB to src for now
+ SDL_GetRGB(srcPixels^[spi], src^.format, @rT, @gT, @bT);
+ SDL_GetRGB(destPixels^[dpi], dest^.format, @rD, @gD, @bD);
+ // note: this is not how to correctly blend RGB, just sayin' (R,G,B are not linear...)
+ rT:= (rD * (255 - aT) + rT * aT) div 255;
+ gT:= (gD * (255 - aT) + gT * aT) div 255;
+ bT:= (bD * (255 - aT) + bT * aT) div 255;
+ aT:= aD + ((255 - LongInt(aD)) * aT div 255);
+
+ destPixels^[dpi]:= SDL_MapRGBA(dest^.format, rT, gT, bT, aT);
end;
SDL_UnlockSurface(src);
@@ -190,7 +217,7 @@
procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); inline;
begin
- DrawSpriteFrame2Surf(sprite, dest, x, y, 0);
+ DrawSpriteFrame2Surf(sprite, dest, x, y, 0);
end;
procedure DrawSpriteFrame2Surf(sprite: TSprite; dest: PSDL_Surface; x,y,frame: LongInt);