hedgewars/uLand.pas
changeset 7628 bc7b1d228a2c
parent 7594 5f03595335e6
child 7613 ce6ead3327b2
child 7640 e9e6b4d740f6
--- a/hedgewars/uLand.pas	Thu Aug 30 12:47:41 2012 -0400
+++ b/hedgewars/uLand.pas	Thu Aug 30 13:02:19 2012 -0400
@@ -20,7 +20,7 @@
 
 unit uLand;
 interface
-uses SDLh, uLandTemplates, uFloat, uConsts, GLunit, uTypes;
+uses SDLh, uLandTemplates, uFloat, uConsts, GLunit, uTypes, uAILandMarks;
 
 procedure initModule;
 procedure freeModule;
@@ -35,6 +35,28 @@
 
 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));
+    end;
+end;
+
 procedure ColorizeLand(Surface: PSDL_Surface);
 var tmpsurf: PSDL_Surface;
     r, rr: TSDL_Rect;
@@ -181,6 +203,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 +260,7 @@
 
 procedure GenDrawnMap;
 begin
+    ResizeLand(4096, 2048);
     uLandPainted.Draw;
 
     MaxHedgehogs:= 48;
@@ -260,6 +284,11 @@
         3: SelectTemplate:= LargeTemplates[getrandom(Succ(High(LargeTemplates)))];
         4: SelectTemplate:= CavernTemplates[getrandom(Succ(High(CavernTemplates)))];
         5: SelectTemplate:= WackyTemplates[getrandom(Succ(High(WackyTemplates)))];
+// For lua only!
+        6: begin
+           SelectTemplate:= min(LuaTemplateNumber,High(EdgeTemplates));
+           GetRandom(2) // burn 1
+           end;
     end;
 
     WriteLnToConsole('Selected template #'+inttostr(SelectTemplate)+' using filter #'+inttostr(cTemplateFilter));
@@ -299,7 +328,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 +518,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';
@@ -581,7 +613,7 @@
             if Land[y, x] <> 0 then
                 begin
                 inc(c);
-                if c > 200 then // avoid accidental triggering
+                if c > 1000 then // avoid accidental triggering
                     begin
                     hasBorder:= true;
                     break;
@@ -676,24 +708,35 @@
                 LandPixels[y,x]:= w or (LandPixels[y div 2, x div 2] and AMask)
                 end
     end;
-
-UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false);
 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
         0: GenBlank(EdgeTemplates[SelectTemplate]);
-        1: GenMaze;
+        1: begin ResizeLand(4096,2048); GenMaze; end;
         2: GenDrawnMap;
     else
         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 +747,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);
@@ -741,7 +785,9 @@
 
     LandBackSurface:= nil;
     digest:= '';
-
+    LAND_WIDTH:= 0;
+    LAND_HEIGHT:= 0;
+(*
     if (cReducedQuality and rqBlurryLand) = 0 then
         SetLength(LandPixels, LAND_HEIGHT, LAND_WIDTH)
     else
@@ -749,6 +795,7 @@
 
     SetLength(Land, LAND_HEIGHT, LAND_WIDTH);
     SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
+*)
 end;
 
 procedure freeModule;