# HG changeset patch # User sheepluva # Date 1480769517 -3600 # Node ID c1d83fc8e89470ac26ee3a525ec76dd3015515de # Parent 966a9739812fdcd6220edefcc12bad1f8759d6f4 copyToXYFromRect: some tweaks diff -r 966a9739812f -r c1d83fc8e894 hedgewars/uRenderUtils.pas --- 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);