First pass at variable land size. For playing a small map (forced on rqLowRes), this should save 42MiB of RAM.
authornemo
Sat, 04 Aug 2012 20:47:13 -0400
changeset 7477 26706bf32ecf
parent 7474 bbecb1b4f59b
child 7480 536f5f3260f1
First pass at variable land size. For playing a small map (forced on rqLowRes), this should save 42MiB of RAM.
hedgewars/GSHandlers.inc
hedgewars/uGears.pas
hedgewars/uLand.pas
--- a/hedgewars/GSHandlers.inc	Sat Aug 04 18:01:46 2012 -0400
+++ b/hedgewars/GSHandlers.inc	Sat Aug 04 20:47:13 2012 -0400
@@ -610,11 +610,10 @@
     // move back to cloud layer
         if yy > cWaterLine then
             move:= true
-        else if ((yy and LAND_HEIGHT_MASK) <> 0)
-        or (xx > LAND_WIDTH + 512) or (xx < -512) then
+        else if (xx > snowRight) or (xx < snowLeft) then
             move:=true
         // Solid pixel encountered
-        else if ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
+        else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
             begin
             lf:= Land[yy, xx] and (lfObject or lfBasic or lfIndestructible);
             // If there's room below keep falling
@@ -724,8 +723,8 @@
         exit
         end;
     Gear^.Pos:= 0;
-    Gear^.X:= int2hwFloat(GetRandom(LAND_WIDTH+1024)-512);
-    Gear^.Y:= int2hwFloat(750+(GetRandom(50)-25));
+    Gear^.X:= int2hwFloat(GetRandom(snowRight-snowLeft)+snowLeft);
+    Gear^.Y:= int2hwFloat(LAND_HEIGHT-1300+(GetRandom(50)-25));
     Gear^.State:= Gear^.State or gstInvisible;
     end
 end;
--- a/hedgewars/uGears.pas	Sat Aug 04 18:01:46 2012 -0400
+++ b/hedgewars/uGears.pas	Sat Aug 04 20:47:13 2012 -0400
@@ -77,6 +77,7 @@
     stAfterDelay, stChWin, stWater, stChWin2, stHealth,
     stSpawn, stNTurn);
     upd: Longword;
+    snowLeft,snowRight: LongInt;
     //SDMusic: shortstring;
 
 // For better maintainability the step handlers of gears are stored in
@@ -642,9 +643,12 @@
     AddGear(rx, ry, gtGenericFaller, gstInvisible, rdx, rdy, $FFFFFFFF);
     end;
 
+snowRight:= max(LAND_WIDTH,4096)+512;
+snowLeft:= -(snowRight-LAND_WIDTH);
+
 if not hasBorder and ((Theme = 'Snow') or (Theme = 'Christmas')) then
-    for i:= 0 to Pred(vobCount*2) do
-        AddGear(GetRandom(LAND_WIDTH+1024)-512, LAND_HEIGHT - GetRandom(LAND_HEIGHT div 2), gtFlake, 0, _0, _0, 0);
+    for i:= vobCount * max(LAND_WIDTH,4096) div 2048 downto 1 do
+        AddGear(GetRandom(snowRight-snowLeft)+snowLeft, LAND_HEIGHT-1300+GetRandom(750), gtFlake, 0, _0, _0, 0);
 end;
 
 
--- a/hedgewars/uLand.pas	Sat Aug 04 18:01:46 2012 -0400
+++ b/hedgewars/uLand.pas	Sat Aug 04 20:47:13 2012 -0400
@@ -35,6 +35,29 @@
 
 var digest: shortstring;
 
+procedure ResizeLand(width, height: LongWord);
+var potW, potH: LongWord;
+begin 
+potW:= toPowerOf2(width);
+potH:= toPowerOf2(height);
+if (potW <> LAND_WIDTH) or (potH <> LAND_HEIGHT) then
+    begin
+    LAND_WIDTH:= potW;
+    LAND_HEIGHT:= potH;
+    LAND_WIDTH_MASK:= not(LAND_WIDTH-1);
+    LAND_HEIGHT_MASK:= not(LAND_HEIGHT-1);
+    cWaterLine:= LAND_HEIGHT;
+    if (cReducedQuality and rqBlurryLand) = 0 then
+        SetLength(LandPixels, LAND_HEIGHT, LAND_WIDTH)
+    else
+        SetLength(LandPixels, LAND_HEIGHT div 2, LAND_WIDTH div 2);
+
+    SetLength(Land, LAND_HEIGHT, LAND_WIDTH);
+    SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
+    uLandTexture.initModule;
+    end;
+end;
+
 procedure ColorizeLand(Surface: PSDL_Surface);
 var tmpsurf: PSDL_Surface;
     r, rr: TSDL_Rect;
@@ -181,6 +204,7 @@
     i: Longword;
     y, x: Longword;
 begin
+    ResizeLand(Template.TemplateWidth, Template.TemplateHeight);
     for y:= 0 to LAND_HEIGHT - 1 do
         for x:= 0 to LAND_WIDTH - 1 do
             Land[y, x]:= lfBasic;
@@ -237,6 +261,7 @@
 
 procedure GenDrawnMap;
 begin
+    ResizeLand(4096, 2048);
     uLandPainted.Draw;
 
     MaxHedgehogs:= 48;
@@ -299,7 +324,7 @@
     WriteLnToConsole('Generating land...');
     case cMapGen of
         0: GenBlank(EdgeTemplates[SelectTemplate]);
-        1: GenMaze;
+        1: begin ResizeLand(4096,2048); GenMaze; end;
         2: GenDrawnMap;
     else
         OutError('Unknown mapgen', true);
@@ -489,7 +514,10 @@
     if tmpsurf = nil then
         tmpsurf:= LoadImage(Pathz[ptMissionMaps] + '/' + mapName + '/map', ifAlpha or ifCritical or ifTransparent or ifIgnoreCaps);
     end;
-TryDo((tmpsurf^.w <= LAND_WIDTH) and (tmpsurf^.h <= LAND_HEIGHT), 'Map dimensions too big!', true);
+// (bare) Sanity check. Considering possible LongInt comparisons as well as just how much system memoery it would take
+TryDo((tmpsurf^.w < $40000000) and (tmpsurf^.h < $40000000) and (tmpsurf^.w * tmpsurf^.h < 6*1024*1024*1024), 'Map dimensions too big!', true);
+
+ResizeLand(tmpsurf^.w, tmpsurf^.h);
 
 // unC0Rr - should this be passed from the GUI? I am not sure which layer does what
 s:= UserPathz[ptMapCurrent] + '/map.cfg';
@@ -681,7 +709,7 @@
 end;
 
 procedure GenPreview(out Preview: TPreview);
-var x, y, xx, yy, t, bit, cbit, lh, lw: LongInt;
+var rh, rw, ox, oy, x, y, xx, yy, t, bit, cbit, lh, lw: LongInt;
 begin
     WriteLnToConsole('Generating preview...');
     case cMapGen of
@@ -692,8 +720,21 @@
         OutError('Unknown mapgen', true);
     end;
 
-    lh:= LAND_HEIGHT div 128;
-    lw:= LAND_WIDTH div 32;
+    // strict scaling needed here since preview assumes a rectangle
+    rh:= max(LAND_HEIGHT,2048);
+    rw:= max(LAND_WIDTH,4096);
+    ox:= 0;
+    if rw < rh*2 then
+        begin
+        rw:= rh*2;
+        end;
+    if rh < rw div 2 then rh:= rw * 2;
+    
+    ox:= (rw-LAND_WIDTH) div 2;
+    oy:= rh-LAND_HEIGHT;
+
+    lh:= rh div 128;
+    lw:= rw div 32;
     for y:= 0 to 127 do
         for x:= 0 to 31 do
         begin
@@ -704,7 +745,8 @@
                 cbit:= bit * 8;
                 for yy:= y * lh to y * lh + 7 do
                     for xx:= x * lw + cbit to x * lw + cbit + 7 do
-                        if Land[yy, xx] <> 0 then
+                        if ((yy-oy) and LAND_HEIGHT_MASK = 0) and ((xx-ox) and LAND_WIDTH_MASK = 0) 
+                           and (Land[yy-oy, xx-ox] <> 0) then
                             inc(t);
                 if t > 8 then
                     Preview[y, x]:= Preview[y, x] or ($80 shr bit);