hedgewars/uLand.pas
changeset 7628 bc7b1d228a2c
parent 7594 5f03595335e6
child 7613 ce6ead3327b2
child 7640 e9e6b4d740f6
equal deleted inserted replaced
7533:7ee319134713 7628:bc7b1d228a2c
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uLand;
    21 unit uLand;
    22 interface
    22 interface
    23 uses SDLh, uLandTemplates, uFloat, uConsts, GLunit, uTypes;
    23 uses SDLh, uLandTemplates, uFloat, uConsts, GLunit, uTypes, uAILandMarks;
    24 
    24 
    25 procedure initModule;
    25 procedure initModule;
    26 procedure freeModule;
    26 procedure freeModule;
    27 procedure DrawBottomBorder;
    27 procedure DrawBottomBorder;
    28 procedure GenMap;
    28 procedure GenMap;
    32 uses uConsole, uStore, uRandom, uLandObjects, uIO, uLandTexture, SysUtils,
    32 uses uConsole, uStore, uRandom, uLandObjects, uIO, uLandTexture, SysUtils,
    33      uVariables, uUtils, uCommands, adler32, uDebug, uLandPainted, uTextures,
    33      uVariables, uUtils, uCommands, adler32, uDebug, uLandPainted, uTextures,
    34      uLandGenMaze, uLandOutline;
    34      uLandGenMaze, uLandOutline;
    35 
    35 
    36 var digest: shortstring;
    36 var digest: shortstring;
       
    37 
       
    38 procedure ResizeLand(width, height: LongWord);
       
    39 var potW, potH: LongWord;
       
    40 begin 
       
    41 potW:= toPowerOf2(width);
       
    42 potH:= toPowerOf2(height);
       
    43 if (potW <> LAND_WIDTH) or (potH <> LAND_HEIGHT) then
       
    44     begin
       
    45     LAND_WIDTH:= potW;
       
    46     LAND_HEIGHT:= potH;
       
    47     LAND_WIDTH_MASK:= not(LAND_WIDTH-1);
       
    48     LAND_HEIGHT_MASK:= not(LAND_HEIGHT-1);
       
    49     cWaterLine:= LAND_HEIGHT;
       
    50     if (cReducedQuality and rqBlurryLand) = 0 then
       
    51         SetLength(LandPixels, LAND_HEIGHT, LAND_WIDTH)
       
    52     else
       
    53         SetLength(LandPixels, LAND_HEIGHT div 2, LAND_WIDTH div 2);
       
    54 
       
    55     SetLength(Land, LAND_HEIGHT, LAND_WIDTH);
       
    56     SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
       
    57     end;
       
    58 end;
    37 
    59 
    38 procedure ColorizeLand(Surface: PSDL_Surface);
    60 procedure ColorizeLand(Surface: PSDL_Surface);
    39 var tmpsurf: PSDL_Surface;
    61 var tmpsurf: PSDL_Surface;
    40     r, rr: TSDL_Rect;
    62     r, rr: TSDL_Rect;
    41     x, yd, yu: LongInt;
    63     x, yd, yu: LongInt;
   179 procedure GenBlank(var Template: TEdgeTemplate);
   201 procedure GenBlank(var Template: TEdgeTemplate);
   180 var pa: TPixAr;
   202 var pa: TPixAr;
   181     i: Longword;
   203     i: Longword;
   182     y, x: Longword;
   204     y, x: Longword;
   183 begin
   205 begin
       
   206     ResizeLand(Template.TemplateWidth, Template.TemplateHeight);
   184     for y:= 0 to LAND_HEIGHT - 1 do
   207     for y:= 0 to LAND_HEIGHT - 1 do
   185         for x:= 0 to LAND_WIDTH - 1 do
   208         for x:= 0 to LAND_WIDTH - 1 do
   186             Land[y, x]:= lfBasic;
   209             Land[y, x]:= lfBasic;
   187     {$HINTS OFF}
   210     {$HINTS OFF}
   188     SetPoints(Template, pa);
   211     SetPoints(Template, pa);
   235         end;
   258         end;
   236 end;
   259 end;
   237 
   260 
   238 procedure GenDrawnMap;
   261 procedure GenDrawnMap;
   239 begin
   262 begin
       
   263     ResizeLand(4096, 2048);
   240     uLandPainted.Draw;
   264     uLandPainted.Draw;
   241 
   265 
   242     MaxHedgehogs:= 48;
   266     MaxHedgehogs:= 48;
   243     hasGirders:= true;
   267     hasGirders:= true;
   244     playHeight:= 2048;
   268     playHeight:= 2048;
   258         1: SelectTemplate:= SmallTemplates[getrandom(Succ(High(SmallTemplates)))];
   282         1: SelectTemplate:= SmallTemplates[getrandom(Succ(High(SmallTemplates)))];
   259         2: SelectTemplate:= MediumTemplates[getrandom(Succ(High(MediumTemplates)))];
   283         2: SelectTemplate:= MediumTemplates[getrandom(Succ(High(MediumTemplates)))];
   260         3: SelectTemplate:= LargeTemplates[getrandom(Succ(High(LargeTemplates)))];
   284         3: SelectTemplate:= LargeTemplates[getrandom(Succ(High(LargeTemplates)))];
   261         4: SelectTemplate:= CavernTemplates[getrandom(Succ(High(CavernTemplates)))];
   285         4: SelectTemplate:= CavernTemplates[getrandom(Succ(High(CavernTemplates)))];
   262         5: SelectTemplate:= WackyTemplates[getrandom(Succ(High(WackyTemplates)))];
   286         5: SelectTemplate:= WackyTemplates[getrandom(Succ(High(WackyTemplates)))];
       
   287 // For lua only!
       
   288         6: begin
       
   289            SelectTemplate:= min(LuaTemplateNumber,High(EdgeTemplates));
       
   290            GetRandom(2) // burn 1
       
   291            end;
   263     end;
   292     end;
   264 
   293 
   265     WriteLnToConsole('Selected template #'+inttostr(SelectTemplate)+' using filter #'+inttostr(cTemplateFilter));
   294     WriteLnToConsole('Selected template #'+inttostr(SelectTemplate)+' using filter #'+inttostr(cTemplateFilter));
   266 end;
   295 end;
   267 
   296 
   297     x,y: Longword;
   326     x,y: Longword;
   298 begin
   327 begin
   299     WriteLnToConsole('Generating land...');
   328     WriteLnToConsole('Generating land...');
   300     case cMapGen of
   329     case cMapGen of
   301         0: GenBlank(EdgeTemplates[SelectTemplate]);
   330         0: GenBlank(EdgeTemplates[SelectTemplate]);
   302         1: GenMaze;
   331         1: begin ResizeLand(4096,2048); GenMaze; end;
   303         2: GenDrawnMap;
   332         2: GenDrawnMap;
   304     else
   333     else
   305         OutError('Unknown mapgen', true);
   334         OutError('Unknown mapgen', true);
   306     end;
   335     end;
   307     AddProgress();
   336     AddProgress();
   487     mapName:= ExtractFileName(Pathz[ptMapCurrent]);
   516     mapName:= ExtractFileName(Pathz[ptMapCurrent]);
   488     tmpsurf:= LoadImage(UserPathz[ptMissionMaps] + '/' + mapName + '/map', ifAlpha or ifTransparent or ifIgnoreCaps);
   517     tmpsurf:= LoadImage(UserPathz[ptMissionMaps] + '/' + mapName + '/map', ifAlpha or ifTransparent or ifIgnoreCaps);
   489     if tmpsurf = nil then
   518     if tmpsurf = nil then
   490         tmpsurf:= LoadImage(Pathz[ptMissionMaps] + '/' + mapName + '/map', ifAlpha or ifCritical or ifTransparent or ifIgnoreCaps);
   519         tmpsurf:= LoadImage(Pathz[ptMissionMaps] + '/' + mapName + '/map', ifAlpha or ifCritical or ifTransparent or ifIgnoreCaps);
   491     end;
   520     end;
   492 TryDo((tmpsurf^.w <= LAND_WIDTH) and (tmpsurf^.h <= LAND_HEIGHT), 'Map dimensions too big!', true);
   521 // (bare) Sanity check. Considering possible LongInt comparisons as well as just how much system memoery it would take
       
   522 TryDo((tmpsurf^.w < $40000000) and (tmpsurf^.h < $40000000) and (tmpsurf^.w * tmpsurf^.h < 6*1024*1024*1024), 'Map dimensions too big!', true);
       
   523 
       
   524 ResizeLand(tmpsurf^.w, tmpsurf^.h);
   493 
   525 
   494 // unC0Rr - should this be passed from the GUI? I am not sure which layer does what
   526 // unC0Rr - should this be passed from the GUI? I am not sure which layer does what
   495 s:= UserPathz[ptMapCurrent] + '/map.cfg';
   527 s:= UserPathz[ptMapCurrent] + '/map.cfg';
   496 if not FileExists(s) then
   528 if not FileExists(s) then
   497     s:= Pathz[ptMapCurrent] + '/map.cfg';
   529     s:= Pathz[ptMapCurrent] + '/map.cfg';
   579     for y:= topY to topY + 5 do
   611     for y:= topY to topY + 5 do
   580         for x:= leftX to rightX do
   612         for x:= leftX to rightX do
   581             if Land[y, x] <> 0 then
   613             if Land[y, x] <> 0 then
   582                 begin
   614                 begin
   583                 inc(c);
   615                 inc(c);
   584                 if c > 200 then // avoid accidental triggering
   616                 if c > 1000 then // avoid accidental triggering
   585                     begin
   617                     begin
   586                     hasBorder:= true;
   618                     hasBorder:= true;
   587                     break;
   619                     break;
   588                     end;
   620                     end;
   589                 end;
   621                 end;
   674                     w:= 255;
   706                     w:= 255;
   675                 w:= (w and $FF shl RShift) or (w and $FF shl BShift) or (w and $FF shl GShift) or (LandPixels[y div 2,x div 2] and AMask);
   707                 w:= (w and $FF shl RShift) or (w and $FF shl BShift) or (w and $FF shl GShift) or (LandPixels[y div 2,x div 2] and AMask);
   676                 LandPixels[y,x]:= w or (LandPixels[y div 2, x div 2] and AMask)
   708                 LandPixels[y,x]:= w or (LandPixels[y div 2, x div 2] and AMask)
   677                 end
   709                 end
   678     end;
   710     end;
   679 
       
   680 UpdateLandTexture(0, LAND_WIDTH, 0, LAND_HEIGHT, false);
       
   681 end;
   711 end;
   682 
   712 
   683 procedure GenPreview(out Preview: TPreview);
   713 procedure GenPreview(out Preview: TPreview);
   684 var x, y, xx, yy, t, bit, cbit, lh, lw: LongInt;
   714 var rh, rw, ox, oy, x, y, xx, yy, t, bit, cbit, lh, lw: LongInt;
   685 begin
   715 begin
   686     WriteLnToConsole('Generating preview...');
   716     WriteLnToConsole('Generating preview...');
   687     case cMapGen of
   717     case cMapGen of
   688         0: GenBlank(EdgeTemplates[SelectTemplate]);
   718         0: GenBlank(EdgeTemplates[SelectTemplate]);
   689         1: GenMaze;
   719         1: begin ResizeLand(4096,2048); GenMaze; end;
   690         2: GenDrawnMap;
   720         2: GenDrawnMap;
   691     else
   721     else
   692         OutError('Unknown mapgen', true);
   722         OutError('Unknown mapgen', true);
   693     end;
   723     end;
   694 
   724 
   695     lh:= LAND_HEIGHT div 128;
   725     // strict scaling needed here since preview assumes a rectangle
   696     lw:= LAND_WIDTH div 32;
   726     rh:= max(LAND_HEIGHT,2048);
       
   727     rw:= max(LAND_WIDTH,4096);
       
   728     ox:= 0;
       
   729     if rw < rh*2 then
       
   730         begin
       
   731         rw:= rh*2;
       
   732         end;
       
   733     if rh < rw div 2 then rh:= rw * 2;
       
   734     
       
   735     ox:= (rw-LAND_WIDTH) div 2;
       
   736     oy:= rh-LAND_HEIGHT;
       
   737 
       
   738     lh:= rh div 128;
       
   739     lw:= rw div 32;
   697     for y:= 0 to 127 do
   740     for y:= 0 to 127 do
   698         for x:= 0 to 31 do
   741         for x:= 0 to 31 do
   699         begin
   742         begin
   700             Preview[y, x]:= 0;
   743             Preview[y, x]:= 0;
   701             for bit:= 0 to 7 do
   744             for bit:= 0 to 7 do
   702             begin
   745             begin
   703                 t:= 0;
   746                 t:= 0;
   704                 cbit:= bit * 8;
   747                 cbit:= bit * 8;
   705                 for yy:= y * lh to y * lh + 7 do
   748                 for yy:= y * lh to y * lh + 7 do
   706                     for xx:= x * lw + cbit to x * lw + cbit + 7 do
   749                     for xx:= x * lw + cbit to x * lw + cbit + 7 do
   707                         if Land[yy, xx] <> 0 then
   750                         if ((yy-oy) and LAND_HEIGHT_MASK = 0) and ((xx-ox) and LAND_WIDTH_MASK = 0) 
       
   751                            and (Land[yy-oy, xx-ox] <> 0) then
   708                             inc(t);
   752                             inc(t);
   709                 if t > 8 then
   753                 if t > 8 then
   710                     Preview[y, x]:= Preview[y, x] or ($80 shr bit);
   754                     Preview[y, x]:= Preview[y, x] or ($80 shr bit);
   711             end;
   755             end;
   712         end;
   756         end;
   739     RegisterVariable('landcheck', @chLandCheck, false);
   783     RegisterVariable('landcheck', @chLandCheck, false);
   740     RegisterVariable('sendlanddigest', @chSendLandDigest, false);
   784     RegisterVariable('sendlanddigest', @chSendLandDigest, false);
   741 
   785 
   742     LandBackSurface:= nil;
   786     LandBackSurface:= nil;
   743     digest:= '';
   787     digest:= '';
   744 
   788     LAND_WIDTH:= 0;
       
   789     LAND_HEIGHT:= 0;
       
   790 (*
   745     if (cReducedQuality and rqBlurryLand) = 0 then
   791     if (cReducedQuality and rqBlurryLand) = 0 then
   746         SetLength(LandPixels, LAND_HEIGHT, LAND_WIDTH)
   792         SetLength(LandPixels, LAND_HEIGHT, LAND_WIDTH)
   747     else
   793     else
   748         SetLength(LandPixels, LAND_HEIGHT div 2, LAND_WIDTH div 2);
   794         SetLength(LandPixels, LAND_HEIGHT div 2, LAND_WIDTH div 2);
   749 
   795 
   750     SetLength(Land, LAND_HEIGHT, LAND_WIDTH);
   796     SetLength(Land, LAND_HEIGHT, LAND_WIDTH);
   751     SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
   797     SetLength(LandDirty, (LAND_HEIGHT div 32), (LAND_WIDTH div 32));
       
   798 *)
   752 end;
   799 end;
   753 
   800 
   754 procedure freeModule;
   801 procedure freeModule;
   755 begin
   802 begin
   756     SetLength(Land, 0, 0);
   803     SetLength(Land, 0, 0);