Make land types flagged (to allow stacking future attributes such as indestructible ice, but also for a damaged flag)
authornemo
Thu, 17 Jun 2010 11:41:38 -0400
changeset 3509 d72c2219595d
parent 3507 2e40893e6034
child 3512 6a8b5f313190
Make land types flagged (to allow stacking future attributes such as indestructible ice, but also for a damaged flag) Add a basic patch for downscaling LandPixels to save memory on mobile devices. Probably could use more optimisation in the pixel writes to avoid redundant writes.
hedgewars/GSHandlers.inc
hedgewars/uConsts.pas
hedgewars/uLand.pas
hedgewars/uLandGraphics.pas
hedgewars/uLandObjects.pas
hedgewars/uLandTexture.pas
hedgewars/uStore.pas
--- a/hedgewars/GSHandlers.inc	Wed Jun 16 15:20:18 2010 +0200
+++ b/hedgewars/GSHandlers.inc	Thu Jun 17 11:41:38 2010 -0400
@@ -812,7 +812,7 @@
         end;
 
         if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
-           , COLOR_INDESTRUCTIBLE) then
+           , LAND_INDESTRUCTIBLE) then
         begin
             Gear^.X := Gear^.X + Gear^.dX;
             Gear^.Y := Gear^.Y + _1_9;
@@ -922,11 +922,11 @@
             // why the call to HedgehogStep then a further increment of X?
             if (prevX = hwRound(HHGear^.X)) and
                CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
-               COLOR_INDESTRUCTIBLE) then HedgehogStep(HHGear);
+               LAND_INDESTRUCTIBLE) then HedgehogStep(HHGear);
 
             if (prevX = hwRound(HHGear^.X)) and
                CheckLandValue(hwRound(HHGear^.X + SignAs(_6, HHGear^.dX)), hwRound(HHGear^.Y),
-               COLOR_INDESTRUCTIBLE) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX);
+               LAND_INDESTRUCTIBLE) then HHGear^.X := HHGear^.X + SignAs(_1, HHGear^.dX);
             HHGear^.State := HHGear^.State or gstAttacking
         end;
 
@@ -936,7 +936,7 @@
             BTSteps := 0;
             if CheckLandValue(hwRound(HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC) + SignAs(_6,
                Gear^.dX)), hwRound(HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC)),
-               COLOR_INDESTRUCTIBLE) then
+               LAND_INDESTRUCTIBLE) then
             begin
                 Gear^.X := HHGear^.X + Gear^.dX * (cHHRadius + cBlowTorchC);
                 Gear^.Y := HHGear^.Y + Gear^.dY * (cHHRadius + cBlowTorchC);
@@ -1795,7 +1795,7 @@
     end;
 
     if CheckLandValue(hwRound(HHGear^.X), hwRound(HHGear^.Y + HHGear^.dY + SignAs(_6,Gear^.dY)),
-       COLOR_INDESTRUCTIBLE) then
+       LAND_INDESTRUCTIBLE) then
         HHGear^.Y := HHGear^.Y + HHGear^.dY
 end;
 
@@ -2544,7 +2544,8 @@
        or (t^.Count <> 0)
        or (not TestCollisionYWithGear(Gear, hwSign(Gear^.dY))
        and not TestCollisionXWithGear(Gear, hwSign(Gear^.dX)))
-       or (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] = COLOR_INDESTRUCTIBLE) then
+// CheckLandValue returns true if the type isn't matched
+       or not CheckLandValue(hwRound(Gear^.Y), hwRound(Gear^.X), LAND_INDESTRUCTIBLE) then
     begin
         //out of time or exited ground
         StopSound(Gear^.SoundChannel);
--- a/hedgewars/uConsts.pas	Wed Jun 16 15:20:18 2010 +0200
+++ b/hedgewars/uConsts.pas	Thu Jun 17 11:41:38 2010 -0400
@@ -248,9 +248,11 @@
     LAND_HEIGHT_MASK = $FFFFF800;
 {$ENDIF}
 
-    COLOR_LAND           = $FFFF;  // white
-    COLOR_INDESTRUCTIBLE = $88FF;  // red
-    COLOR_OBJECT         = $44FF;  // no idea
+// To allow these to layer, going to treat them as masks. The bottom byte is reserved for objects
+    LAND_BASIC          = $8000;  // white
+    LAND_INDESTRUCTIBLE = $4000;  // red
+    LAND_OBJECT         = $2000;  // no idea
+    LAND_DAMAGED        = $1000;  // no idea
 
     cMaxPower     = 1500;
     cMaxAngle     = 2048;
--- a/hedgewars/uLand.pas	Wed Jun 16 15:20:18 2010 +0200
+++ b/hedgewars/uLand.pas	Thu Jun 17 11:41:38 2010 -0400
@@ -22,7 +22,13 @@
 interface
 uses SDLh, uLandTemplates, uFloat, uConsts, GLunit;
 
-type TLandArray = packed array[0 .. LAND_HEIGHT - 1, 0 .. LAND_WIDTH - 1] of LongWord;
+type
+{$IFDEF DOWNSCALE}
+    TLandArray = packed array[0 .. LAND_HEIGHT div 2 - 1, 0 .. LAND_WIDTH div 2 - 1] of LongWord;
+{$ELSE}
+    TLandArray = packed array[0 .. LAND_HEIGHT - 1, 0 .. LAND_WIDTH - 1] of LongWord;
+{$ENDIF}
+ 
     TCollisionArray = packed array[0 .. LAND_HEIGHT - 1, 0 .. LAND_WIDTH - 1] of Word;
     TPreview  = packed array[0..127, 0..31] of byte;
     TDirtyTag = packed array[0 .. LAND_HEIGHT div 32 - 1, 0 .. LAND_WIDTH div 32 - 1] of byte;
@@ -555,7 +561,7 @@
 begin
 for y:= 0 to LAND_HEIGHT - 1 do
     for x:= 0 to LAND_WIDTH - 1 do
-        Land[y, x]:= COLOR_LAND;
+        Land[y, x]:= LAND_BASIC;
 
 {$HINTS OFF}
 SetPoints(Template, pa);
@@ -576,7 +582,7 @@
          with FillPoints^[i] do
               FillLand(x, y);
 
-DrawEdge(pa, COLOR_LAND);
+DrawEdge(pa, LAND_BASIC);
 
 MaxHedgehogs:= Template.MaxHedgehogs;
 hasGirders:= Template.hasGirders;
@@ -599,8 +605,8 @@
             else
             begin
                if Land[y, x] = 0 then
-                   Land[y, x]:= COLOR_LAND
-               else if Land[y, x] = COLOR_LAND then
+                   Land[y, x]:= LAND_BASIC
+               else if Land[y, x] = LAND_BASIC then
                    Land[y, x]:= 0;
             end;
     end;
@@ -644,7 +650,11 @@
 for y:= 0 to LAND_HEIGHT - 1 do
     begin
     for x:= 0 to LAND_WIDTH - 1 do
+{$IFDEF DOWNSCALE}
+        if Land[y, x] <> 0 then LandPixels[y div 2, x div 2]:= p^[x] or AMask;
+{$ELSE}
         if Land[y, x] <> 0 then LandPixels[y, x]:= p^[x] or AMask;
+{$ENDIF}
 
     p:= @(p^[Surface^.pitch div 4]);
     end;
@@ -968,7 +978,7 @@
 
 for x := 0 to playWidth do
     for y := off_y to LAND_HEIGHT - 1 do
-        Land[y, x] := COLOR_LAND;
+        Land[y, x] := LAND_BASIC;
 
 for y := 0 to num_cells_y - 1 do
     for x := 0 to num_cells_x - 1 do
@@ -1069,7 +1079,7 @@
 else
 begin
     x := 0;
-    while Land[cellsize div 2 + cellsize + off_y, x] = COLOR_LAND do
+    while Land[cellsize div 2 + cellsize + off_y, x] = LAND_BASIC do
         x := x + 1;
     while Land[cellsize div 2 + cellsize + off_y, x] = 0 do
         x := x + 1;
@@ -1155,9 +1165,9 @@
                     if ((AMask and p^[x]) = 0) then  // Tiy was having trouble generating transparent black
                         Land[cpY + y, cpX + x]:= 0
                     else if p^[x] = (AMask or RMask) then
-                        Land[cpY + y, cpX + x]:= COLOR_INDESTRUCTIBLE
+                        Land[cpY + y, cpX + x]:= LAND_INDESTRUCTIBLE
                     else if p^[x] = $FFFFFFFF then
-                        Land[cpY + y, cpX + x]:= COLOR_LAND;
+                        Land[cpY + y, cpX + x]:= LAND_BASIC;
                 end;
                 p:= @(p^[tmpsurf^.pitch div 4]);
             end;
@@ -1250,31 +1260,40 @@
     for y:= 0 to LAND_HEIGHT - 1 do
         for x:= 0 to LAND_WIDTH - 1 do
             if (y < topY) or (x < leftX) or (x > rightX) then
-                Land[y, x]:= COLOR_INDESTRUCTIBLE;
+                Land[y, x]:= LAND_INDESTRUCTIBLE;
     // experiment hardcoding cave
     // also try basing cave dimensions on map/template dimensions, if they exist
     for w:= 0 to 5 do // width of 3 allowed hogs to be knocked through with grenade
         begin
         for y:= topY to LAND_HEIGHT - 1 do
             begin
-            Land[y, leftX + w]:= COLOR_INDESTRUCTIBLE;
-            Land[y, rightX - w]:= COLOR_INDESTRUCTIBLE;
+            Land[y, leftX + w]:= LAND_INDESTRUCTIBLE;
+            Land[y, rightX - w]:= LAND_INDESTRUCTIBLE;
             if (y + w) mod 32 < 16 then
                 c:= AMask
             else
                 c:= AMask or RMask or GMask; // FF00FFFF
+{$IFDEF DOWNSCALE}
+            LandPixels[y div 2, (leftX + w) div 2]:= c;
+            LandPixels[y div 2, (rightX - w) div 2]:= c;
+{$ELSE}
             LandPixels[y, leftX + w]:= c;
             LandPixels[y, rightX - w]:= c;
+{$ENDIF}
             end;
 
         for x:= leftX to rightX do
             begin
-            Land[topY + w, x]:= COLOR_INDESTRUCTIBLE;
+            Land[topY + w, x]:= LAND_INDESTRUCTIBLE;
             if (x + w) mod 32 < 16 then
                 c:= AMask
             else
                 c:= AMask or RMask or GMask; // FF00FFFF
+{$IFDEF DOWNSCALE}
+            LandPixels[(topY + w) div 2, x div 2]:= c;
+{$ELSE}
             LandPixels[topY + w, x]:= c;
+{$ENDIF}
             end;
         end;
     end;
--- a/hedgewars/uLandGraphics.pas	Wed Jun 16 15:20:18 2010 +0200
+++ b/hedgewars/uLandGraphics.pas	Thu Jun 17 11:41:38 2010 -0400
@@ -29,7 +29,7 @@
 
 function  SweepDirty: boolean;
 function  Despeckle(X, Y: LongInt): boolean;
-function  CheckLandValue(X, Y: LongInt; Color: Word): boolean;
+function  CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean;
 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);
@@ -46,19 +46,19 @@
 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_INDESTRUCTIBLE then
+        if (Land[y + dy, i] and LAND_INDESTRUCTIBLE) = 0 then
             Land[y + dy, i]:= Value;
 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_INDESTRUCTIBLE then
+        if (Land[y - dy, i] and LAND_INDESTRUCTIBLE) = 0 then
             Land[y - dy, i]:= Value;
 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_INDESTRUCTIBLE then
+        if (Land[y + dx, i] and LAND_INDESTRUCTIBLE) = 0 then
             Land[y + dx, i]:= Value;
 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_INDESTRUCTIBLE then
+        if (Land[y - dx, i] and LAND_INDESTRUCTIBLE) = 0 then
             Land[y - dx, i]:= Value;
 end;
 
@@ -145,20 +145,36 @@
 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 (not isMap and (Land[y + dy, i] <> COLOR_INDESTRUCTIBLE)) or (Land[y + dy, i] = COLOR_LAND) then
+        if (not isMap and ((Land[y + dy, i] and LAND_INDESTRUCTIBLE) = 0)) or ((Land[y + dy, i] and LAND_BASIC) <> 0) then
+{$IFDEF DOWNSCALE}
+            LandPixels[(y + dy) div 2, i div 2]:= 0;
+{$ELSE}
             LandPixels[y + dy, i]:= 0;
+{$ENDIF}
 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
-        if (not isMap and (Land[y - dy, i] <> COLOR_INDESTRUCTIBLE)) or (Land[y - dy, i] = COLOR_LAND) then
+        if (not isMap and ((Land[y - dy, i] and LAND_INDESTRUCTIBLE) = 0)) or ((Land[y - dy, i] and LAND_BASIC) <> 0) then
+{$IFDEF DOWNSCALE}
+             LandPixels[(y - dy) div 2, i div 2]:= 0;
+{$ELSE}
              LandPixels[y - dy, i]:= 0;
+{$ENDIF}
 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-        if (not isMap and (Land[y + dx, i] <> COLOR_INDESTRUCTIBLE)) or (Land[y + dx, i] = COLOR_LAND) then
+        if (not isMap and ((Land[y + dx, i] and LAND_INDESTRUCTIBLE) = 0)) or ((Land[y + dx, i] and LAND_BASIC) <> 0) then
+{$IFDEF DOWNSCALE}
+            LandPixels[(y + dx) div 2, i div 2]:= 0;
+{$ELSE}
             LandPixels[y + dx, i]:= 0;
+{$ENDIF}
 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
-        if (not isMap and (Land[y - dx, i] <> COLOR_INDESTRUCTIBLE)) or (Land[y - dx, i] = COLOR_LAND) then
+        if (not isMap and ((Land[y - dx, i] and LAND_INDESTRUCTIBLE) = 0)) or ((Land[y - dx, i] and LAND_BASIC) <> 0) then
+{$IFDEF DOWNSCALE}
+             LandPixels[(y - dx) div 2, i div 2]:= 0;
+{$ELSE}
              LandPixels[y - dx, i]:= 0;
+{$ENDIF}
 end;
 
 procedure FillLandCircleLinesBG(x, y, dx, dy: LongInt);
@@ -166,28 +182,60 @@
 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] and LAND_BASIC) <> 0) then
+{$IFDEF DOWNSCALE}
+          LandPixels[(y + dy) div 2, i div 2]:= LandBackPixel(i, y + dy)
+{$ELSE}
           LandPixels[y + dy, i]:= LandBackPixel(i, y + dy)
+{$ENDIF}
        else
-          if (Land[y + dy, i] = COLOR_OBJECT) then LandPixels[y + dy, i]:= 0;
+{$IFDEF DOWNSCALE}
+          if (Land[y + dy, i] = LAND_OBJECT) then LandPixels[(y + dy) div 2, i div 2]:= 0;
+{$ELSE}
+          if (Land[y + dy, i] = LAND_OBJECT) then LandPixels[y + dy, i]:= 0;
+{$ENDIF}
 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] and LAND_BASIC) <> 0) then
+{$IFDEF DOWNSCALE}
+          LandPixels[(y - dy) div 2, i div 2]:= LandBackPixel(i, y - dy)
+{$ELSE}
           LandPixels[y - dy, i]:= LandBackPixel(i, y - dy)
+{$ENDIF}
        else
-          if (Land[y - dy, i] = COLOR_OBJECT) then LandPixels[y - dy, i]:= 0;
+{$IFDEF DOWNSCALE}
+          if (Land[y - dy, i] = LAND_OBJECT) then LandPixels[(y - dy) div 2, i div 2]:= 0;
+{$ELSE}
+          if (Land[y - dy, i] = LAND_OBJECT) then LandPixels[y - dy, i]:= 0;
+{$ENDIF}
 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] and LAND_BASIC) <> 0) then
+{$IFDEF DOWNSCALE}
+           LandPixels[(y + dx) div 2, i div 2]:= LandBackPixel(i, y + dx)
+{$ELSE}
            LandPixels[y + dx, i]:= LandBackPixel(i, y + dx)
+{$ENDIF}
        else
-          if (Land[y + dx, i] = COLOR_OBJECT) then LandPixels[y + dx, i]:= 0;
+{$IFDEF DOWNSCALE}
+          if (Land[y + dx, i] = LAND_OBJECT) then LandPixels[(y + dx) div 2, i div 2]:= 0;
+{$ELSE}
+          if (Land[y + dx, i] = LAND_OBJECT) then LandPixels[y + dx, i]:= 0;
+{$ENDIF}
 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] and LAND_BASIC) <> 0) then
+{$IFDEF DOWNSCALE}
+          LandPixels[(y - dx) div 2, i div 2]:= LandBackPixel(i, y - dx)
+{$ELSE}
           LandPixels[y - dx, i]:= LandBackPixel(i, y - dx)
+{$ENDIF}
        else
-          if (Land[y - dx, i] = COLOR_OBJECT) then LandPixels[y - dx, i]:= 0;
+{$IFDEF DOWNSCALE}
+          if (Land[y - dx, i] = LAND_OBJECT) then LandPixels[(y - dx) div 2, i div 2]:= 0;
+{$ELSE}
+          if (Land[y - dx, i] = LAND_OBJECT) then LandPixels[y - dx, i]:= 0;
+{$ENDIF}
 end;
 
 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt);
@@ -195,33 +243,53 @@
 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) or (Land[y + dy, i] = COLOR_OBJECT) then
+       if ((Land[y + dy, i] and LAND_BASIC) <> 0) or (Land[y + dy, i] = LAND_OBJECT) then
           begin
+{$IFDEF DOWNSCALE}
+          LandPixels[(y + dy) div 2, i div 2]:= cExplosionBorderColor;
+{$ELSE}
           LandPixels[y + dy, i]:= cExplosionBorderColor;
+{$ENDIF}
+          Land[y + dy, i]:= Land[y + dy, i] or LAND_DAMAGED;
           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) or (Land[y - dy, i] = COLOR_OBJECT) then
+       if ((Land[y - dy, i] and LAND_BASIC) <> 0) or (Land[y - dy, i] = LAND_OBJECT) then
           begin
+{$IFDEF DOWNSCALE}
+          LandPixels[(y - dy) div 2, i div 2]:= cExplosionBorderColor;
+{$ELSE}
           LandPixels[y - dy, i]:= cExplosionBorderColor;
+{$ENDIF}
+          Land[y - dy, i]:= Land[y - dy, i] or LAND_DAMAGED;
           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) or (Land[y + dx, i] = COLOR_OBJECT) then
+       if ((Land[y + dx, i] and LAND_BASIC) <> 0) or (Land[y + dx, i] = LAND_OBJECT) then
            begin
+{$IFDEF DOWNSCALE}
+           LandPixels[(y + dx) div 2, i div 2]:= cExplosionBorderColor;
+{$ELSE}
            LandPixels[y + dx, i]:= cExplosionBorderColor;
+{$ENDIF}
+           Land[y + dx, i]:= Land[y + dx, i] or LAND_DAMAGED;
            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) or (Land[y - dx, i] = COLOR_OBJECT) then
+       if ((Land[y - dx, i] and LAND_BASIC) <> 0) or (Land[y - dx, i] = LAND_OBJECT) then
           begin
+{$IFDEF DOWNSCALE}
+          LandPixels[(y - dx) div 2, i div 2]:= cExplosionBorderColor;
+{$ELSE}
           LandPixels[y - dx, i]:= cExplosionBorderColor;
+{$ENDIF}
+          Land[y - dx, i]:= Land[y - dx, i] or LAND_DAMAGED;
           Despeckle(i, y - dy);
           LandDirty[(y - dx) div 32, i div 32]:= 1;
           end;
@@ -309,10 +377,18 @@
     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] and LAND_BASIC) <> 0 then
+{$IFDEF DOWNSCALE}
+                LandPixels[ty div 2, tx div 2]:= LandBackPixel(tx, ty)
+{$ELSE}
                 LandPixels[ty, tx]:= LandBackPixel(tx, ty)
-            else if Land[ty, tx] = COLOR_OBJECT then
+{$ENDIF}
+            else if Land[ty, tx] = LAND_OBJECT then
+{$IFDEF DOWNSCALE}
+                LandPixels[ty div 2, tx div 2]:= 0;
+{$ELSE}
                 LandPixels[ty, tx]:= 0;
+{$ENDIF}
     inc(y, dY)
     end;
 
@@ -323,9 +399,14 @@
     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) or (Land[ty, tx] = COLOR_OBJECT) then
+            if ((Land[ty, tx] and LAND_BASIC) <> 0) or (Land[ty, tx] = LAND_OBJECT) then
                 begin
+{$IFDEF DOWNSCALE}
+                LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor;
+{$ELSE}
                 LandPixels[ty, tx]:= cExplosionBorderColor;
+{$ENDIF}
+                Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
                 LandDirty[(y + dy) shr 5, i shr 5]:= 1;
                 end;
     inc(y, dY)
@@ -362,9 +443,16 @@
     ty:= hwRound(Y);
     if ((ty and LAND_HEIGHT_MASK) = 0) and
        ((tx and LAND_WIDTH_MASK) = 0) and
-       ((Land[ty, tx] = COLOR_LAND) or 
-       (Land[ty, tx] = COLOR_OBJECT)) then
+       (((Land[ty, tx] and LAND_BASIC) <> 0) or 
+       (Land[ty, tx] = LAND_OBJECT)) then
+        begin
+        Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+{$IFDEF DOWNSCALE}
+        LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
+{$ELSE}
         LandPixels[ty, tx]:= cExplosionBorderColor
+{$ENDIF}
+        end
     end;
     nx:= nx - dY;
     ny:= ny + dX;
@@ -382,9 +470,16 @@
     ty:= hwRound(Y);
     if ((ty and LAND_HEIGHT_MASK) = 0) and
        ((tx and LAND_WIDTH_MASK) = 0) and
-       ((Land[ty, tx] = COLOR_LAND) or 
-       (Land[ty, tx] = COLOR_OBJECT)) then
+       (((Land[ty, tx] and LAND_BASIC) <> 0) or 
+       (Land[ty, tx] = LAND_OBJECT)) then
+        begin
+        Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+{$IFDEF DOWNSCALE}
+        LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
+{$ELSE}
         LandPixels[ty, tx]:= cExplosionBorderColor
+{$ENDIF}
+        end
     end;
     X:= nx;
     Y:= ny;
@@ -394,12 +489,20 @@
         Y:= Y + dY;
         tx:= hwRound(X);
         ty:= hwRound(Y);
-        if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (Land[ty, tx] <> COLOR_INDESTRUCTIBLE) then
+        if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and ((Land[ty, tx] and LAND_INDESTRUCTIBLE) = 0) then
             begin
-            if Land[ty, tx] = COLOR_LAND then
+            if (Land[ty, tx] and LAND_BASIC) <> 0 then
+{$IFDEF DOWNSCALE}
+                LandPixels[ty div 2, tx div 2]:= LandBackPixel(tx, ty)
+{$ELSE}
                 LandPixels[ty, tx]:= LandBackPixel(tx, ty)
-            else if Land[ty, tx] = COLOR_OBJECT then
+{$ENDIF}
+            else if Land[ty, tx] = LAND_OBJECT then
+{$IFDEF DOWNSCALE}
+                LandPixels[ty div 2, tx div 2]:= 0;
+{$ELSE}
                 LandPixels[ty, tx]:= 0;
+{$ENDIF}
             Land[ty, tx]:= 0;
             end
         end;
@@ -411,9 +514,16 @@
     ty:= hwRound(Y);
     if ((ty and LAND_HEIGHT_MASK) = 0) and
        ((tx and LAND_WIDTH_MASK) = 0) and
-       ((Land[ty, tx] = COLOR_LAND) or 
-       (Land[ty, tx] = COLOR_OBJECT)) then
+       (((Land[ty, tx] and LAND_BASIC) <> 0) or 
+       (Land[ty, tx] = LAND_OBJECT)) then
+        begin
+        Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+{$IFDEF DOWNSCALE}
+        LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
+{$ELSE}
         LandPixels[ty, tx]:= cExplosionBorderColor
+{$ENDIF}
+        end
     end;
     nx:= nx - dY;
     ny:= ny + dX;
@@ -431,9 +541,16 @@
     ty:= hwRound(Y);
     if ((ty and LAND_HEIGHT_MASK) = 0) and
        ((tx and LAND_WIDTH_MASK) = 0) and
-       ((Land[ty, tx] = COLOR_LAND) or 
-       (Land[ty, tx] = COLOR_OBJECT)) then
+       (((Land[ty, tx] and LAND_BASIC) <> 0) or 
+       (Land[ty, tx] = LAND_OBJECT)) then
+        begin
+        Land[ty, tx]:= Land[ty, tx] or LAND_DAMAGED;
+{$IFDEF DOWNSCALE}
+        LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
+{$ELSE}
         LandPixels[ty, tx]:= cExplosionBorderColor
+{$ENDIF}
+        end
     end;
     nx:= nx - dY;
     ny:= ny + dX;
@@ -503,8 +620,12 @@
             for x:= 0 to Pred(w) do
                 if PLongword(@(p^[x * 4]))^ <> 0 then
                    begin
-                   Land[cpY + y, cpX + x]:= COLOR_OBJECT;
+                   Land[cpY + y, cpX + x]:= LAND_OBJECT;
+{$IFDEF DOWNSCALE}
+                   LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= PLongword(@(p^[x * 4]))^
+{$ELSE}
                    LandPixels[cpY + y, cpX + x]:= PLongword(@(p^[x * 4]))^
+{$ENDIF}
                    end;
             p:= @(p^[Image^.pitch]);
             end;
@@ -523,7 +644,7 @@
 function Despeckle(X, Y: LongInt): boolean;
 var nx, ny, i, j, c: LongInt;
 begin
-if (Land[Y, X] > 255) and (Land[Y, X] <> COLOR_INDESTRUCTIBLE) and (LandPixels[Y, X] = cExplosionBorderColor)then // check neighbours
+if (Land[Y, X] > 255) and ((Land[Y, X] and LAND_INDESTRUCTIBLE) = 0) and ((Land[Y, X] and LAND_DAMAGED) <> 0)then // check neighbours
     begin
     c:= 0;
     for i:= -1 to 1 do
@@ -539,7 +660,11 @@
 
     if c < 4 then // 0-3 neighbours
         begin
-        if Land[Y, X] = COLOR_LAND then LandPixels[Y, X]:= LandBackPixel(X, Y) else LandPixels[Y, X]:= 0;
+{$IFDEF DOWNSCALE}
+        if (Land[Y, X] and LAND_BASIC) <> 0 then LandPixels[Y div 2, X div 2]:= LandBackPixel(X, Y) else LandPixels[Y div 2, X div 2]:= 0;
+{$ELSE}
+        if (Land[Y, X] and LAND_BASIC) <> 0 then LandPixels[Y, X]:= LandBackPixel(X, Y) else LandPixels[Y, X]:= 0;
+{$ENDIF}
         Land[Y, X]:= 0;
         exit(true);
         end;
@@ -584,8 +709,8 @@
 end;
 
 // Return true if outside of land or not the value tested, used right now for some X/Y movement that does not use normal hedgehog movement in GSHandlers.inc
-function CheckLandValue(X, Y: LongInt; Color: Word): boolean;
+function CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean;
 begin
-     CheckLandValue:= ((X and LAND_WIDTH_MASK <> 0) or (Y and LAND_HEIGHT_MASK <> 0)) or (Land[Y, X] <> Color)
+     CheckLandValue:= ((X and LAND_WIDTH_MASK <> 0) or (Y and LAND_HEIGHT_MASK <> 0)) or ((Land[Y, X] and LandFlag) = 0)
 end;
 end.
--- a/hedgewars/uLandObjects.pas	Wed Jun 16 15:20:18 2010 +0200
+++ b/hedgewars/uLandObjects.pas	Thu Jun 17 11:41:38 2010 -0400
@@ -84,12 +84,18 @@
 for y:= 0 to Pred(Image^.h) do
     begin
     for x:= 0 to Pred(Width) do
+        begin
+{$IFDEF DOWNSCALE}
+        if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then
+            LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x];
+{$ELSE}
         if LandPixels[cpY + y, cpX + x] = 0 then
-            begin
             LandPixels[cpY + y, cpX + x]:= p^[x];
-            if (p^[x] and AMask) <> 0 then Land[cpY + y, cpX + x]:= COLOR_OBJECT;
-            end;
-    p:= @(p^[Image^.pitch shr 2]);
+{$ENDIF}
+        if ((Land[cpY + y, cpX + x] and $FF00) = 0) and ((p^[x] and AMask) <> 0) then 
+            Land[cpY + y, cpX + x]:= LAND_OBJECT
+        end;
+    p:= @(p^[Image^.pitch shr 2])
     end;
 
 if SDL_MustLock(Image) then
@@ -232,7 +238,7 @@
     bRes: boolean;
 begin
 with Obj do
-     if CheckLand(inland, x, y, COLOR_LAND) then
+     if CheckLand(inland, x, y, LAND_BASIC) then
         begin
         bRes:= true;
         i:= 1;
@@ -312,7 +318,7 @@
     repeat
         y:= 8;
         repeat
-            if CheckLand(r, x, y - 8, COLOR_LAND)
+            if CheckLand(r, x, y - 8, LAND_BASIC)
             and not CheckIntersect(x, y, Width, Height) then
             begin
             ar[cnt].x:= x;
--- a/hedgewars/uLandTexture.pas	Wed Jun 16 15:20:18 2010 +0200
+++ b/hedgewars/uLandTexture.pas	Thu Jun 17 11:41:38 2010 -0400
@@ -31,8 +31,13 @@
 
 
 const TEXSIZE = 256;
+{$IFDEF DOWNSCALE}
+    LANDTEXARW = (LAND_WIDTH div TEXSIZE) div 2;
+    LANDTEXARH = (LAND_HEIGHT div TEXSIZE) div 2;
+{$ELSE}
     LANDTEXARW = LAND_WIDTH div TEXSIZE;
     LANDTEXARH = LAND_HEIGHT div TEXSIZE;
+{$ENDIF}
 
 var
     LandTextures: array[0..LANDTEXARW - 1, 0..LANDTEXARH - 1] of
@@ -71,9 +76,15 @@
 TryDo((Y >= 0) and (Y < LAND_HEIGHT), 'UpdateLandTexture: wrong Y parameter', true);
 TryDo(Y + Height <= LAND_HEIGHT, 'UpdateLandTexture: wrong Height parameter', true);
 
+{$IFDEF DOWNSCALE}
+for ty:= (Y div TEXSIZE) div 2 to ((Y + Height - 1) div TEXSIZE) div 2 do
+    for tx:= (X div TEXSIZE) div 2 to ((X + Width - 1) div TEXSIZE) div 2 do
+        LandTextures[tx, ty].shouldUpdate:= true
+{$ELSE}
 for ty:= Y div TEXSIZE to (Y + Height - 1) div TEXSIZE do
     for tx:= X div TEXSIZE to (X + Width - 1) div TEXSIZE do
         LandTextures[tx, ty].shouldUpdate:= true
+{$ENDIF}
 end;
 
 procedure RealLandTexUpdate;
@@ -108,7 +119,11 @@
 for x:= 0 to LANDTEXARW -1 do
     for y:= 0 to LANDTEXARH - 1 do
         with LandTextures[x, y] do
+{$IFDEF DOWNSCALE}
+            DrawTexture(dX + x * TEXSIZE * 2, dY + y * TEXSIZE * 2, tex, 2.0)
+{$ELSE}
             DrawTexture(dX + x * TEXSIZE, dY + y * TEXSIZE, tex)
+{$ENDIF}
 end;
 
 procedure FreeLand;
--- a/hedgewars/uStore.pas	Wed Jun 16 15:20:18 2010 +0200
+++ b/hedgewars/uStore.pas	Thu Jun 17 11:41:38 2010 -0400
@@ -51,7 +51,7 @@
 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt);
 procedure DrawSprite2(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
 procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
-procedure DrawTexture(X, Y: LongInt; Texture: PTexture);
+procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat = 1.0);
 procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
 procedure DrawRotatedTextureF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real);
 procedure DrawRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
@@ -524,10 +524,11 @@
 glDisableClientState(GL_VERTEX_ARRAY)
 end;
 
-procedure DrawTexture(X, Y: LongInt; Texture: PTexture);
+procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
 begin
 glPushMatrix;
 glTranslatef(X, Y, 0);
+glScalef(Scale, Scale, 1);
 
 glBindTexture(GL_TEXTURE_2D, Texture^.id);