First pass at variable land size. For playing a small map (forced on rqLowRes), this should save 42MiB of RAM.
--- 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);