Snow blends into land, trys to fill the gaps
authorPalewolf
Fri, 31 Dec 2010 00:37:39 +0100
changeset 4791 458d9854c679
parent 4790 4cb3f7890fbd
child 4792 68f9b331014a
Snow blends into land, trys to fill the gaps
hedgewars/GSHandlers.inc
hedgewars/uLandGraphics.pas
share/hedgewars/Data/Graphics/Snow.png
share/hedgewars/Data/Graphics/Snow.svg
--- a/hedgewars/GSHandlers.inc	Thu Dec 30 22:20:17 2010 +0100
+++ b/hedgewars/GSHandlers.inc	Fri Dec 31 00:37:39 2010 +0100
@@ -563,6 +563,7 @@
     move, allpx: Boolean;
     s: PSDL_Surface;
     p: PLongwordArray;
+    oAlpha, nAlpha: byte;
 begin
 if GameTicks and $7 = 0 then
     begin
@@ -590,49 +591,89 @@
         move:= false;
     // move back to cloud layer
         if yy > cWaterLine then move:= true
-        else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] > 255) then
+        else if ((yy and LAND_HEIGHT_MASK) <> 0) or ((xx and LAND_WIDTH_MASK) <> 0) then move:=true
+        // Solid pixel encountered
+        else if (Land[yy, xx] > 255) then
             begin
-            // we've collided with land. draw some stuff and get back into the clouds
-            move:= true;
-            if (CurAmmoGear = nil) or (CurAmmoGear^.Kind <> gtRope) then
+            // If there's room below keep falling
+            if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (Land[yy-1, xx] = 0) then
+                begin
+                X:= X - cWindSpeed * 1600 - dX;
+                end
+            // If there's room below, on the sides, fill the gaps
+            else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx-(1*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx-(1*hwSign(cWindSpeed)))] = 0) then
+                begin
+                X:= X - _0_8 * hwSign(cWindSpeed);
+                Y:= Y - dY - cGravity * vobFallSpeed * 8;
+                end
+            else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx-(2*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx-(2*hwSign(cWindSpeed)))] = 0) then
+                begin
+                X:= X - _0_8 * 2 * hwSign(cWindSpeed);
+                Y:= Y - dY - cGravity * vobFallSpeed * 8;
+                end
+            else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx+(1*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx+(1*hwSign(cWindSpeed)))] = 0) then
+                begin
+                X:= X + _0_8 * hwSign(cWindSpeed);
+                Y:= Y - dY - cGravity * vobFallSpeed * 8;
+                end
+            else if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (((xx+(2*hwSign(cWindSpeed))) and LAND_WIDTH_MASK) = 0) and (Land[yy-1, (xx+(2*hwSign(cWindSpeed)))] = 0) then
+                begin
+                X:= X + _0_8 * 2 * hwSign(cWindSpeed);
+                Y:= Y - dY - cGravity * vobFallSpeed * 8;
+                end
+            else
                 begin
-////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
-                if cWindSpeed * 1600 + dX < _0 then i:= -1
-                else i:= 1;
-                if (yy > 0) and ((Land[yy-1, xx] and $FF00) = 0) then dec(yy)
-                else dec(xx, i);
-                dec(yy,2);
-                dec(xx,i);
-                s:= SpritesData[sprSnow].Surface;
-                p:= s^.pixels;
-                allpx:= true;
-                for py:= 0 to Pred(s^.h) do
+                // we've collided with land. draw some stuff and get back into the clouds
+                move:= true;
+                if (CurAmmoGear = nil) or (CurAmmoGear^.Kind <> gtRope) then
                     begin
-                    for px:= 0 to Pred(s^.w) do
-                        if (((yy + py) and LAND_HEIGHT_MASK) = 0) and (((xx + px) and LAND_WIDTH_MASK) = 0) and 
-                           ((Land[yy + py, xx + px] and $FF00) = 0) then
+    ////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
+                    dec(yy,3);
+                    dec(xx,2);
+                    s:= SpritesData[sprSnow].Surface;
+                    p:= s^.pixels;
+                    allpx:= true;
+                    for py:= 0 to Pred(s^.h) do
+                        begin
+                        for px:= 0 to Pred(s^.w) do
+                            if (((yy + py) and LAND_HEIGHT_MASK) = 0) and (((xx + px) and LAND_WIDTH_MASK) = 0) then
+                                begin
+                                if (cReducedQuality and rqBlurryLand) = 0 then
+                                    begin
+                                    LandPixels[yy + py, xx + px]:= addBgColor(LandPixels[yy + py, xx + px], p^[px]);
+                                    Land[yy + py, xx + px]:= Land[yy + py, xx + px] or lfObject;
+                                    end
+                                else
+                                    begin
+                                    LandPixels[(yy + py) div 2, (xx + px) div 2]:= addBgColor(LandPixels[(yy + py) div 2, (xx + px) div 2], p^[px]);
+                                    Land[(yy + py) div 2, (xx + px) div 2]:= Land[(yy + py) div 2, (xx + px) div 2] or lfObject;
+                                    end;
+                                end
+                            else allpx:= false;
+                        p:= @(p^[s^.pitch shr 2])
+                        end;
+                    
+                    for py:= (yy) to (yy+1) do
+                        begin
+                        for px:= (xx+2) to (xx+3) do
                             begin
-                            if (cReducedQuality and rqBlurryLand) = 0 then
-                                LandPixels[yy + py, xx + px]:= p^[px]
-                            else
-                                LandPixels[(yy + py) div 2, (xx + px) div 2]:= p^[px]
-                            end
-                        else allpx:= false;
-                    p:= @(p^[s^.pitch shr 2])
-                    end;
-                if allpx then UpdateLandTexture(xx, 4, yy, 4)
-                else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) then UpdateLandTexture(xx, 1, yy, 1);
-                inc(yy,2);
-                inc(xx,i);
-                if ((xx and LAND_WIDTH_MASK) = 0) and ((yy and LAND_HEIGHT_MASK) = 0) then Land[yy, xx]:= Land[yy, xx] or lfObject;
-                if yy > 0 then
-                    begin 
-                    Land[yy-1, xx]:= Land[yy-1, xx] or lfObject;
-                    if ((xx-i and LAND_WIDTH_MASK) = 0) then Land[yy-1, xx-i]:= Land[yy-1, xx-i] or lfObject;
-                    end;
-                if ((xx-i and LAND_WIDTH_MASK) = 0) and ((yy and LAND_HEIGHT_MASK) = 0) then Land[yy, xx-i]:= Land[yy, xx-i] or lfObject
-////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
-                end
+                            Land[py, px]:= lfBasic;
+                            end;
+                        end;
+                    
+                    if allpx then UpdateLandTexture(xx, Pred(s^.h), yy, Pred(s^.w))
+                    else
+                        begin
+                        UpdateLandTexture(
+                            max(0, min(LAND_WIDTH, xx)),
+                            min(LAND_WIDTH - xx, Pred(s^.w)),
+                            max(0, min(LAND_WIDTH, yy)),
+                            min(LAND_HEIGHT - yy, Pred(s^.h))
+                        );
+                        end;
+    ////////////////////////////////// TODO - ASK UNC0RR FOR A GOOD HOME FOR THIS ////////////////////////////////////
+                    end
+                end;
             end;
         if move then
             begin
--- a/hedgewars/uLandGraphics.pas	Thu Dec 30 22:20:17 2010 +0100
+++ b/hedgewars/uLandGraphics.pas	Fri Dec 31 00:37:39 2010 +0100
@@ -27,6 +27,7 @@
                                    Left, Right: LongInt;
                                    end;
 
+function  addBgColor(OldColor, NewColor: LongWord): LongWord;
 function  SweepDirty: boolean;
 function  Despeckle(X, Y: LongInt): boolean;
 function  CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean;
@@ -42,6 +43,31 @@
 implementation
 uses SDLh, uLandTexture, uVariables, uUtils, uDebug;
 
+function addBgColor(OldColor, NewColor: LongWord): LongWord;
+// Factor ranges from 0 to 100% NewColor
+var
+    oRed, oBlue, oGreen, oAlpha, nRed, nBlue, nGreen, nAlpha: Byte;
+begin
+    // Get colors
+    oAlpha := (OldColor shr 24) and $FF;
+    oRed   := (OldColor shr 16) and $FF;
+    oGreen := (OldColor shr 8) and $FF;
+    oBlue  := (OldColor) and $FF;
+
+    nAlpha := (NewColor shr 24) and $FF;
+    nRed   := (NewColor shr 16) and $FF;
+    nGreen := (NewColor shr 8) and $FF;
+    nBlue  := (NewColor) and $FF;
+
+    // Mix colors
+    nAlpha := min(255, oAlpha + nAlpha);
+    nRed   := ((oRed * oAlpha) + (nRed * (255-oAlpha))) div 255;
+    nGreen := ((oGreen * oAlpha) + (nGreen * (255-oAlpha))) div 255;
+    nBlue  := ((oBlue * oAlpha) + (nBlue * (255-oAlpha))) div 255;
+
+    addBgColor := (nAlpha shl 24) or (nRed shl 16) or (nGreen shl 8) or (nBlue);
+end;
+
 procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword);
 var i: LongInt;
 begin
Binary file share/hedgewars/Data/Graphics/Snow.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/hedgewars/Data/Graphics/Snow.svg	Fri Dec 31 00:37:39 2010 +0100
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.0 r9654"
+   width="5"
+   height="5"
+   sodipodi:docname="Snow.svg"
+   inkscape:export-filename="/mnt/y/src/hedgewars/share/hedgewars/Data/Graphics/Snow.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <metadata
+     id="metadata8">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs6">
+    <linearGradient
+       id="linearGradient3757">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop3759" />
+      <stop
+         id="stop3765"
+         offset="0.47515857"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         style="stop-color:#cedcea;stop-opacity:1;"
+         offset="1"
+         id="stop3761" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3757"
+       id="radialGradient3763"
+       cx="2.9785273"
+       cy="2.015959"
+       fx="2.9785273"
+       fy="2.015959"
+       r="2.6945455"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1016"
+     inkscape:window-height="770"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="45.254834"
+     inkscape:cx="3.4892683"
+     inkscape:cy="1.3238902"
+     inkscape:window-x="169"
+     inkscape:window-y="99"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <path
+     sodipodi:type="arc"
+     style="color:#000000;fill:url(#radialGradient3763);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+     id="path2987"
+     sodipodi:cx="2.76"
+     sodipodi:cy="2.8036363"
+     sodipodi:rx="2.6945455"
+     sodipodi:ry="2.6945455"
+     d="m 5.4545455,2.8036363 a 2.6945455,2.6945455 0 1 1 -5.38909102,0 2.6945455,2.6945455 0 1 1 5.38909102,0 z"
+     transform="matrix(0.92780025,0,0,0.92780025,-0.06072869,-0.10121454)" />
+</svg>