# HG changeset patch # User nemo # Date 1344127633 14400 # Node ID 26706bf32ecf36a431a05e3ac019fd87f6320106 # Parent bbecb1b4f59ba36bdedde93fe16e07fa3dd1e344 First pass at variable land size. For playing a small map (forced on rqLowRes), this should save 42MiB of RAM. diff -r bbecb1b4f59b -r 26706bf32ecf hedgewars/GSHandlers.inc --- 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; diff -r bbecb1b4f59b -r 26706bf32ecf hedgewars/uGears.pas --- 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; diff -r bbecb1b4f59b -r 26706bf32ecf hedgewars/uLand.pas --- 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);