hedgewars/uRenderUtils.pas
changeset 12099 c1d83fc8e894
parent 12098 966a9739812f
child 12101 2e70ef81e281
equal deleted inserted replaced
12098:966a9739812f 12099:c1d83fc8e894
   147     // copy from complete src
   147     // copy from complete src
   148     copyToXYFromRect(src, dest, 0, 0, src^.w, src^.h, destX, destY);
   148     copyToXYFromRect(src, dest, 0, 0, src^.w, src^.h, destX, destY);
   149 end;
   149 end;
   150 
   150 
   151 procedure copyToXYFromRect(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt);
   151 procedure copyToXYFromRect(src, dest: PSDL_Surface; srcX, srcY, srcW, srcH, destX, destY: LongInt);
   152 var i, j, iX, iY, dX, dY, lX, lY: LongInt;
   152 var spi, dpi, iX, iY, dX, dY, lX, lY, aT: LongInt;
   153     srcPixels, destPixels: PLongWordArray;
   153     srcPixels, destPixels: PLongWordArray;
   154     r0, g0, b0, a0, r1, g1, b1, a1: Byte;
   154     rD, gD, bD, aD, rT, gT, bT: Byte;
   155 begin
   155 begin
   156     SDL_LockSurface(src);
   156     SDL_LockSurface(src);
   157     SDL_LockSurface(dest);
   157     SDL_LockSurface(dest);
   158 
   158 
   159     srcPixels:= src^.pixels;
   159     srcPixels:= src^.pixels;
   162     // what's the offset between src and dest coords?
   162     // what's the offset between src and dest coords?
   163     dX:= destX - srcX;
   163     dX:= destX - srcX;
   164     dY:= destY - srcY;
   164     dY:= destY - srcY;
   165 
   165 
   166     // let's figure out where the rectangle we can actually copy ends
   166     // let's figure out where the rectangle we can actually copy ends
   167     lX:= ( min( min(srcX + srcW, src^.w), min(destX + srcW + dx, dest^.w) - dx ) ) - 1;
   167     lX:= ( min( min(srcX + srcW, src^.w), min(destX + srcW, dest^.w) - dx ) ) - 1;
   168     lY:= ( min( min(srcY + srcH, src^.h), min(destY + srcH + dy, dest^.h) - dY ) ) - 1;
   168     lY:= ( min( min(srcY + srcH, src^.h), min(destY + srcH, dest^.h) - dY ) ) - 1;
   169 
   169 
   170     for iX:= srcX to lX do
   170     for iX:= srcX to lX do
   171     for iY:= srcY to lY do
   171     for iY:= srcY to lY do
   172         begin
   172         begin
   173         i:= (iY + dY) * dest^.w + (iX + dX);
   173         // src pixel index
   174         j:= iY * src^.w  + iX;
   174         spi:= iY * src^.w  + iX;
   175         if srcPixels^[j] and AMask <> 0 then
   175         // dest pixel index
   176             begin
   176         dpi:= (iY + dY) * dest^.w + (iX + dX);
   177             SDL_GetRGBA(destPixels^[i], dest^.format, @r0, @g0, @b0, @a0);
   177 
   178             SDL_GetRGBA(srcPixels^[j], src^.format, @r1, @g1, @b1, @a1);
   178         // get src alpha (and set it as target alpha for now)
   179             r0:= (r0 * (255 - LongInt(a1)) + r1 * LongInt(a1)) div 255;
   179         aT:= (srcPixels^[spi] and AMask) shr AShift;
   180             g0:= (g0 * (255 - LongInt(a1)) + g1 * LongInt(a1)) div 255;
   180 
   181             b0:= (b0 * (255 - LongInt(a1)) + b1 * LongInt(a1)) div 255;
   181         // src pixel opaque?
   182             a0:= a0 + ((255 - LongInt(a0)) * a1 div 255);
   182         if aT = 255 then
   183             destPixels^[i]:= SDL_MapRGBA(dest^.format, r0, g0, b0, a0);
   183             begin
   184             end;
   184             // just copy full pixel
       
   185             destPixels^[dpi]:= srcPixels^[spi];
       
   186             continue;
       
   187             end;
       
   188 
       
   189         // get dst alpha (without shift for now)
       
   190         aD:= (destPixels^[dpi] and AMask) shr AShift;
       
   191 
       
   192         // dest completely transparent?
       
   193         if aD = 0 then
       
   194             begin
       
   195             // just copy src pixel
       
   196             destPixels^[dpi]:= srcPixels^[spi];
       
   197             continue;
       
   198             end;
       
   199 
       
   200         // looks like some blending is necessary
       
   201 
       
   202         // set color of target RGB to src for now
       
   203         SDL_GetRGB(srcPixels^[spi],  src^.format,  @rT, @gT, @bT);
       
   204         SDL_GetRGB(destPixels^[dpi], dest^.format, @rD, @gD, @bD);
       
   205         // note: this is not how to correctly blend RGB, just sayin' (R,G,B are not linear...)
       
   206         rT:= (rD * (255 - aT) + rT * aT) div 255;
       
   207         gT:= (gD * (255 - aT) + gT * aT) div 255;
       
   208         bT:= (bD * (255 - aT) + bT * aT) div 255;
       
   209         aT:= aD + ((255 - LongInt(aD)) * aT div 255);
       
   210 
       
   211         destPixels^[dpi]:= SDL_MapRGBA(dest^.format, rT, gT, bT, aT);
   185         end;
   212         end;
   186 
   213 
   187     SDL_UnlockSurface(src);
   214     SDL_UnlockSurface(src);
   188     SDL_UnlockSurface(dest);
   215     SDL_UnlockSurface(dest);
   189 end;
   216 end;
   190 
   217 
   191 procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); inline;
   218 procedure DrawSprite2Surf(sprite: TSprite; dest: PSDL_Surface; x,y: LongInt); inline;
   192 begin
   219 begin
   193     DrawSpriteFrame2Surf(sprite, dest, x, y, 0);
   220    DrawSpriteFrame2Surf(sprite, dest, x, y, 0);
   194 end;
   221 end;
   195 
   222 
   196 procedure DrawSpriteFrame2Surf(sprite: TSprite; dest: PSDL_Surface; x,y,frame: LongInt);
   223 procedure DrawSpriteFrame2Surf(sprite: TSprite; dest: PSDL_Surface; x,y,frame: LongInt);
   197 var numFramesFirstCol, row, col: LongInt;
   224 var numFramesFirstCol, row, col: LongInt;
   198 begin
   225 begin