separate landpixels/land despeckling results to avoid desyncing on blurry land due to extra despeckling passes. right now, this does mean landpixels edge-of-block recheck is not done
authornemo
Sun, 03 Jul 2011 20:01:13 -0400
changeset 5384 83d3b50d7e24
parent 5382 d5321b22aed2
child 5386 ba85acff9828
separate landpixels/land despeckling results to avoid desyncing on blurry land due to extra despeckling passes. right now, this does mean landpixels edge-of-block recheck is not done
hedgewars/uLandGraphics.pas
--- a/hedgewars/uLandGraphics.pas	Sun Jul 03 22:47:57 2011 +0200
+++ b/hedgewars/uLandGraphics.pas	Sun Jul 03 20:01:13 2011 -0400
@@ -29,7 +29,7 @@
 
 function  addBgColor(OldColor, NewColor: LongWord): LongWord;
 function  SweepDirty: boolean;
-function  Despeckle(X, Y: LongInt): boolean;
+function  Despeckle(X, Y: LongInt; gfxOnly: boolean): LongWord;
 procedure Smooth(X, Y: LongInt);
 function  CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean;
 function  DrawExplosion(X, Y, Radius: LongInt): Longword;
@@ -700,7 +700,7 @@
 end;
 
 // was experimenting with applying as damage occurred.
-function Despeckle(X, Y: LongInt): boolean;
+function Despeckle(X, Y: LongInt; gfxOnly: boolean): LongWord;
 var nx, ny, i, j, c, xx, yy: LongInt;
     pixelsweep: boolean;
 begin
@@ -715,6 +715,7 @@
    yy:= Y div 2;
    end;
 pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0);
+if not pixelsweep and gfxOnly then exit(0);
 if ((Land[Y, X] > 255) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then
     begin
     c:= 0;
@@ -747,10 +748,11 @@
             LandPixels[yy, xx]:= 0;
 
         Land[Y, X]:= 0;
-        exit(true);
+        if not pixelsweep then exit(1)  // cannot exit true on pixel sweep, or risk desyncs due to inconsistent resweeps
+        else exit(2)
         end;
     end;
-Despeckle:= false
+Despeckle:= 0
 end;
 
 procedure Smooth(X, Y: LongInt);
@@ -797,8 +799,8 @@
 end;
 
 function SweepDirty: boolean;
-var x, y, xx, yy, ty, tx: LongInt;
-    bRes, updateBlock, resweep, recheck, firstpass: boolean;
+var x, y, xx, yy, ty, tx, d: LongInt;
+    bRes, updateBlock, resweepCol, resweepGfx, gfxOnly, recheck, firstpass: boolean;
 begin
 bRes:= false;
 reCheck:= true;
@@ -813,41 +815,47 @@
             if LandDirty[y, x] <> 0 then
                 begin
                 updateBlock:= false;
-                resweep:= true;
+                resweepCol:= true;
+                resweepGfx:= true;
                 firstpass:= true;
                 ty:= y * 32;
                 tx:= x * 32;
-                while(resweep) do
+                while(resweepCol or resweepGfx) do
                     begin
-                    resweep:= false;
+                    gfxOnly:= resweepGfx and not resweepCol;
+                    resweepCol:= false;
+                    resweepGfx:= false;
                     for yy:= ty to ty + 31 do
                         for xx:= tx to tx + 31 do
                             begin
-                            if Despeckle(xx, yy) then
+                            d:= Despeckle(xx, yy, gfxOnly);
+                            if d <> 0 then
                                 begin
                                 bRes:= true;
                                 updateBlock:= true;
-                                resweep:= true;
-                                if (yy = ty) and (y > 0) then
-                                    begin
-                                    LandDirty[y-1, x]:= 1;
-                                    recheck:= true;
-                                    end
-                                else if (yy = ty+31) and (y < LAND_HEIGHT div 32 - 1) then
-                                    begin
-                                    LandDirty[y+1, x]:= 1;
-                                    recheck:= true;
-                                    end;
-                                if (xx = tx) and (x > 0) then
-                                    begin
-                                    LandDirty[y, x-1]:= 1;
-                                    recheck:= true;
-                                    end
-                                else if (xx = tx+31) and (x < LAND_WIDTH div 32 - 1) then
-                                    begin
-                                    LandDirty[y, x+1]:= 1;
-                                    recheck:= true;
-                                    end
+                                if d = 1 then resweepCol:= true
+                                else resweepGfx:= true;
+                                if not resweepGfx then
+                                    if (yy = ty) and (y > 0) then
+                                        begin
+                                        LandDirty[y-1, x]:= 1;
+                                        recheck:= true;
+                                        end
+                                    else if (yy = ty+31) and (y < LAND_HEIGHT div 32 - 1) then
+                                        begin
+                                        LandDirty[y+1, x]:= 1;
+                                        recheck:= true;
+                                        end;
+                                    if (xx = tx) and (x > 0) then
+                                        begin
+                                        LandDirty[y, x-1]:= 1;
+                                        recheck:= true;
+                                        end
+                                    else if (xx = tx+31) and (x < LAND_WIDTH div 32 - 1) then
+                                        begin
+                                        LandDirty[y, x+1]:= 1;
+                                        recheck:= true;
+                                        end
                                 end;
                             if firstpass then Smooth(xx,yy);
                             end;