diff -r 6a1185633872 -r 0e1208e92dfe hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Sun Nov 29 16:37:12 2009 +0000 +++ b/hedgewars/uLandGraphics.pas Sun Nov 29 16:56:04 2009 +0000 @@ -30,7 +30,6 @@ function SweepDirty: boolean; function Despeckle(X, Y: LongInt): boolean; function CheckLandValue(X, Y: LongInt; Color: Word): boolean; -procedure Despeckle2(X, Y, Threesold: LongInt); procedure DrawExplosion(X, Y, Radius: LongInt); procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte); procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); @@ -42,44 +41,6 @@ implementation uses SDLh, uMisc, uLand, uLandTexture; -procedure Despeckle2(X, Y, Threesold: LongInt); -var - i, j: LongInt; - x0, x1, y0, y1: LongInt; - c: byte; -begin - // If the pixel has less than Threesold neightbours, it gets erased - // Erasing is outwards recursive - c := 0; - - x0 := max(X-1, 0); - x1 := min(X+1, LAND_WIDTH - 1); - y0 := max(Y-1, 0); - y1 := min(Y+1, LAND_HEIGHT - 1); - - for i:=x0 to x1 do begin - for j:=y0 to y1 do begin - if Land[j, i]<>0 then begin - c := c+1; - end; - end; - end; - - if c0 then begin - LandPixels[j, i] := cExplosionBorderColor; - Despeckle2(i, j, 5); - end; - end; - end; - end; - UpdateLandTexture(x0, x1-x0, y0, y1-y0); -end; - procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword); var i: LongInt; begin @@ -184,55 +145,84 @@ begin if ((y + dy) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do - if Land[y + dy, i] = COLOR_LAND then + if (Land[y + dy, i] <> COLOR_INDESTRUCTIBLE) then LandPixels[y + dy, i]:= 0; if ((y - dy) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do - if Land[y - dy, i] = COLOR_LAND then + if (Land[y - dy, i] <> COLOR_INDESTRUCTIBLE) then LandPixels[y - dy, i]:= 0; if ((y + dx) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do - if Land[y + dx, i] = COLOR_LAND then + if (Land[y + dx, i] <> COLOR_INDESTRUCTIBLE) then LandPixels[y + dx, i]:= 0; if ((y - dx) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do - if Land[y - dx, i] = COLOR_LAND then + if (Land[y - dx, i] <> COLOR_INDESTRUCTIBLE) then LandPixels[y - dx, i]:= 0; end; +procedure FillLandCircleLinesBG(x, y, dx, dy: LongInt); +var i: LongInt; +begin +if ((y + dy) and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do + if (Land[y + dy, i] = COLOR_LAND) then + LandPixels[y + dy, i]:= LandBackPixel(i, y + dy) + else + if (Land[y + dy, i] = COLOR_OBJECT) then LandPixels[y + dy, i]:= 0; +if ((y - dy) and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do + if (Land[y - dy, i] = COLOR_LAND) then + LandPixels[y - dy, i]:= LandBackPixel(i, y - dy) + else + if (Land[y - dy, i] = COLOR_OBJECT) then LandPixels[y - dy, i]:= 0; +if ((y + dx) and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do + if (Land[y + dx, i] = COLOR_LAND) then + LandPixels[y + dx, i]:= LandBackPixel(i, y + dx) + else + if (Land[y + dx, i] = COLOR_OBJECT) then LandPixels[y + dx, i]:= 0; +if ((y - dx) and LAND_HEIGHT_MASK) = 0 then + for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do + if (Land[y - dx, i] = COLOR_LAND) then + LandPixels[y - dx, i]:= LandBackPixel(i, y - dx) + else + if (Land[y - dx, i] = COLOR_OBJECT) then LandPixels[y - dx, i]:= 0; +end; + procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt); var i: LongInt; begin if ((y + dy) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do - if Land[y + dy, i] = COLOR_LAND then + if (Land[y + dy, i] = COLOR_LAND) or (Land[y + dy, i] = COLOR_OBJECT) then begin LandPixels[y + dy, i]:= cExplosionBorderColor; - Despeckle2(i, y + dy, 6); + Despeckle(i, y + dy); LandDirty[(y + dy) div 32, i div 32]:= 1; end; if ((y - dy) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do - if Land[y - dy, i] = COLOR_LAND then + if (Land[y - dy, i] = COLOR_LAND) or (Land[y - dy, i] = COLOR_OBJECT) then begin LandPixels[y - dy, i]:= cExplosionBorderColor; - Despeckle2(i, y - dy, 6); + Despeckle(i, y - dy); LandDirty[(y - dy) div 32, i div 32]:= 1; end; if ((y + dx) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do - if Land[y + dx, i] = COLOR_LAND then + if (Land[y + dx, i] = COLOR_LAND) or (Land[y + dx, i] = COLOR_OBJECT) then begin LandPixels[y + dx, i]:= cExplosionBorderColor; - Despeckle2(i, y + dx, 6); + Despeckle(i, y + dx); LandDirty[(y + dx) div 32, i div 32]:= 1; end; if ((y - dx) and LAND_HEIGHT_MASK) = 0 then for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do - if Land[y - dx, i] = COLOR_LAND then + if (Land[y - dx, i] = COLOR_LAND) or (Land[y - dx, i] = COLOR_OBJECT) then begin LandPixels[y - dx, i]:= cExplosionBorderColor; - Despeckle2(i, y - dy, 6); + Despeckle(i, y - dy); LandDirty[(y - dx) div 32, i div 32]:= 1; end; end; @@ -240,39 +230,70 @@ procedure DrawExplosion(X, Y, Radius: LongInt); var dx, dy, ty, tx, d: LongInt; begin - dx:= 0; - dy:= Radius; - d:= 3 - 2 * Radius; - while (dx < dy) do - begin - FillLandCircleLines0(x, y, dx, dy); - if (d < 0) - then d:= d + 4 * dx + 6 - else begin - d:= d + 4 * (dx - dy) + 10; - dec(dy) - end; - inc(dx) - end; - if (dx = dy) then FillLandCircleLines0(x, y, dx, dy); + +// draw background land texture + begin + dx:= 0; + dy:= Radius; + d:= 3 - 2 * Radius; + + while (dx < dy) do + begin + FillLandCircleLinesBG(x, y, dx, dy); + if (d < 0) + then d:= d + 4 * dx + 6 + else begin + d:= d + 4 * (dx - dy) + 10; + dec(dy) + end; + inc(dx) + end; + if (dx = dy) then FillLandCircleLinesBG(x, y, dx, dy); + end; + +// draw a hole in land +if Radius > 25 then + begin + dx:= 0; + dy:= Radius - 25; + d:= 3 - 2 * dy; + + while (dx < dy) do + begin + FillLandCircleLines0(x, y, dx, dy); + if (d < 0) + then d:= d + 4 * dx + 6 + else begin + d:= d + 4 * (dx - dy) + 10; + dec(dy) + end; + inc(dx) + end; + if (dx = dy) then FillLandCircleLines0(x, y, dx, dy); + end; + // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function - FillRoundInLand(X, Y, Radius, 0); - inc(Radius, 4); - dx:= 0; - dy:= Radius; - d:= 3 - 2 * Radius; - while (dx < dy) do - begin - FillLandCircleLinesEBC(x, y, dx, dy); - if (d < 0) - then d:= d + 4 * dx + 6 - else begin - d:= d + 4 * (dx - dy) + 10; - dec(dy) - end; - inc(dx) - end; - if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy); + FillRoundInLand(X, Y, Radius, 0); + +// draw explosion border + begin + inc(Radius, 4); + dx:= 0; + dy:= Radius; + d:= 3 - 2 * Radius; + while (dx < dy) do + begin + FillLandCircleLinesEBC(x, y, dx, dy); + if (d < 0) + then d:= d + 4 * dx + 6 + else begin + d:= d + 4 * (dx - dy) + 10; + dec(dy) + end; + inc(dx) + end; + if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy); + end; tx:= max(X - Radius - 1, 0); dx:= min(X + Radius + 1, LAND_WIDTH) - tx; @@ -285,13 +306,15 @@ var tx, ty, i: LongInt; begin for i:= 0 to Pred(Count) do - begin - for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do - for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do - if Land[ty, tx] = COLOR_LAND then - LandPixels[ty, tx]:= 0; - inc(y, dY) - end; + begin + for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do + for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do + if Land[ty, tx] = COLOR_LAND then + LandPixels[ty, tx]:= LandBackPixel(tx, ty) + else if Land[ty, tx] = COLOR_OBJECT then + LandPixels[ty, tx]:= 0; + inc(y, dY) + end; inc(Radius, 4); dec(y, Count * dY); @@ -300,10 +323,10 @@ begin for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do - if Land[ty, tx] = COLOR_LAND then + if (Land[ty, tx] = COLOR_LAND) or (Land[ty, tx] = COLOR_OBJECT) then begin LandPixels[ty, tx]:= cExplosionBorderColor; - LandDirty[trunc((y + dy)/32), trunc(i/32)]:= 1; + LandDirty[(y + dy) shr 5, i shr 5]:= 1; end; inc(y, dY) end; @@ -352,11 +375,13 @@ tx:= hwRound(X); ty:= hwRound(Y); if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) then - if Land[ty, tx] = COLOR_LAND then - begin - Land[ty, tx]:= 0; - LandPixels[ty, tx]:= 0; - end + begin + if Land[ty, tx] = COLOR_LAND then + LandPixels[ty, tx]:= LandBackPixel(tx, ty) + else if Land[ty, tx] = COLOR_OBJECT then + LandPixels[ty, tx]:= 0; + Land[ty, tx]:= 0; + end end; for t:= 0 to 7 do {$INCLUDE "tunsetborder.inc"} @@ -438,7 +463,7 @@ for x:= 0 to Pred(w) do if PLongword(@(p^[x * 4]))^ <> 0 then begin - Land[cpY + y, cpX + x]:= COLOR_LAND; + Land[cpY + y, cpX + x]:= COLOR_OBJECT; LandPixels[cpY + y, cpX + x]:= PLongword(@(p^[x * 4]))^ end; p:= @(p^[Image^.pitch]); @@ -474,7 +499,7 @@ if c < 4 then // 0-3 neighbours begin - LandPixels[Y, X]:= 0; + LandPixels[Y, X]:= ToggleLongInt(Land[Y, X] = COLOR_LAND, LandBackPixel(X, Y), 0); Land[Y, X]:= 0; exit(true); end;