hedgewars/uLandGraphics.pas
changeset 10897 8ea636ce120a
parent 10878 963bc20f511c
child 10901 fbf6fbe66092
--- a/hedgewars/uLandGraphics.pas	Sun Apr 05 16:41:39 2015 -0400
+++ b/hedgewars/uLandGraphics.pas	Wed Apr 08 15:04:48 2015 -0400
@@ -20,7 +20,7 @@
 
 unit uLandGraphics;
 interface
-uses uFloat, uConsts, uTypes;
+uses uFloat, uConsts, uTypes, Math, uRenderUtils;
 
 type
     fillType = (nullPixel, backgroundPixel, ebcPixel, icePixel, setNotCurrentMask, changePixelSetNotCurrent, setCurrentHog, changePixelNotSetNotCurrent);
@@ -49,8 +49,8 @@
 procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint);
 function TryPlaceOnLandSimple(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean): boolean; inline;
 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline;
-function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word): boolean; inline;
-function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force: boolean; LandFlags: Word): boolean;
+function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; Tint: LongWord; Behind, flipHoriz, flipVert: boolean): boolean; inline;
+function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force, behind, flipHoriz, flipVert: boolean; LandFlags: Word; Tint: LongWord): boolean;
 function GetPlaceCollisionTex(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): PTexture;
 
 implementation
@@ -679,37 +679,37 @@
     lf:= lfIndestructible
 else
     lf:= 0;
-TryPlaceOnLandSimple:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, lf);
+TryPlaceOnLandSimple:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, false, false, false, lf, $FFFFFFFF);
 end;
 
 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline;
 begin
-TryPlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, LandFlags);
+TryPlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, false, false, false, LandFlags, $FFFFFFFF);
 end;
 
-function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word): boolean; inline;
+function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; Tint: LongWord; Behind, flipHoriz, flipVert: boolean): boolean; inline;
 begin
-    ForcePlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, true, false, true, LandFlags)
+    ForcePlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, true, false, true, behind, flipHoriz, flipVert, LandFlags, Tint)
 end;
 
-function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force: boolean; LandFlags: Word): boolean;
+function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force, behind, flipHoriz, flipVert: boolean; LandFlags: Word; Tint: LongWord): boolean;
 var X, Y, bpp, h, w, row, col, gx, gy, numFramesFirstCol: LongInt;
     p: PByteArray;
     Image: PSDL_Surface;
-    indestructible: boolean;
+    pixel: LongWord;
 begin
 TryPlaceOnLand:= false;
 numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height;
 
-// make land indestructible if lfIndestructible is passed
-indestructible:= (LandFlags and lfIndestructible <> 0);
-
 if outOfMap then doPlace:= false; // just using for a check
 
 TryDo(SpritesData[Obj].Surface <> nil, 'Assert SpritesData[Obj].Surface failed', true);
+
 Image:= SpritesData[Obj].Surface;
 w:= SpritesData[Obj].Width;
 h:= SpritesData[Obj].Height;
+if flipVert then flipSurface(Image, true);
+if flipHoriz then flipSurface(Image, false);
 row:= Frame mod numFramesFirstCol;
 col:= Frame div numFramesFirstCol;
 
@@ -765,17 +765,32 @@
                     gY:= cpY + y;
                     end
                 else
-                     begin
-                     gX:= (cpX + x) div 2;
-                     gY:= (cpY + y) div 2;
+                    begin
+                    gX:= (cpX + x) div 2;
+                    gY:= (cpY + y) div 2;
+                    end;
+		if not behind or (Land[cpY + y, cpX + x] and lfLandMask = 0) then
+                    begin
+                    if (LandFlags and lfBasic <> 0) or 
+                       (((LandPixels[gY, gX] and AMask) shr AShift = 255) and  // This test assumes lfBasic and lfObject differ only graphically
+                         (LandFlags or lfObject = 0)) then
+                         Land[cpY + y, cpX + x]:= lfBasic or LandFlags
+                    else Land[cpY + y, cpX + x]:= lfObject or LandFlags
                     end;
-                if indestructible then
-                    Land[cpY + y, cpX + x]:= {lfIndestructible or }LandFlags
-                else if (LandPixels[gY, gX] and AMask) shr AShift = 255 then  // This test assumes lfBasic and lfObject differ only graphically
-                    Land[cpY + y, cpX + x]:= lfBasic or LandFlags
-                else
-                    Land[cpY + y, cpX + x]:= lfObject or LandFlags;
-                LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^
+		if not behind or (LandPixels[gY, gX] = 0) then
+                    begin
+                    if tint = $FFFFFFFF then
+                        LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^
+                    else 
+                        begin
+                        pixel:= PLongword(@(p^[x * 4]))^;
+                        LandPixels[gY, gX]:= 
+                           ceil((pixel shr RShift and $FF) * ((tint shr 24) / 255)) shl RShift or
+                           ceil((pixel shr GShift and $FF) * ((tint shr 16 and $ff) / 255)) shl GShift or
+                           ceil((pixel shr BShift and $FF) * ((tint shr  8 and $ff) / 255)) shl BShift or
+                           ceil((pixel shr AShift and $FF) * ((tint and $ff) / 255)) shl AShift;
+                        end
+                    end
                 end;
         p:= PByteArray(@(p^[Image^.pitch]));
         end;
@@ -783,6 +798,9 @@
 if SDL_MustLock(Image) then
     SDL_UnlockSurface(Image);
 
+if flipVert then flipSurface(Image, true);
+if flipHoriz then flipSurface(Image, false);
+
 x:= Max(cpX, leftX);
 w:= Min(cpX + Image^.w, LAND_WIDTH) - x;
 y:= Max(cpY, topY);