hedgewars/uLandGraphics.pas
changeset 6580 6155187bf599
parent 6490 531bf083e8db
child 6681 f46b1a1de2ce
equal deleted inserted replaced
6579:fc52f7c22c9b 6580:6155187bf599
    82 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
    82 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
    83     for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
    83     for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
    84         if (Land[y + dy, i] and lfIndestructible) = 0 then
    84         if (Land[y + dy, i] and lfIndestructible) = 0 then
    85             Land[y + dy, i]:= Value;
    85             Land[y + dy, i]:= Value;
    86 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
    86 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
    87    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
    87     for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
    88         if (Land[y - dy, i] and lfIndestructible) = 0 then
    88         if (Land[y - dy, i] and lfIndestructible) = 0 then
    89             Land[y - dy, i]:= Value;
    89             Land[y - dy, i]:= Value;
    90 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
    90 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
    91     for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
    91     for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
    92         if (Land[y + dx, i] and lfIndestructible) = 0 then
    92         if (Land[y + dx, i] and lfIndestructible) = 0 then
    99 
    99 
   100 procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet: boolean);
   100 procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet: boolean);
   101 var i: LongInt;
   101 var i: LongInt;
   102 begin
   102 begin
   103 if not doSet then
   103 if not doSet then
   104    begin
   104     begin
   105    if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   105     if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   106       for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   106         for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   107           if (Land[y + dy, i] > 0) and (Land[y + dy, i] < 256) then dec(Land[y + dy, i]); // check > 0 because explosion can erase collision data
   107             if (Land[y + dy, i] > 0) and (Land[y + dy, i] < 256) then
   108    if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   108                 dec(Land[y + dy, i]); // check > 0 because explosion can erase collision data
   109       for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   109     if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   110           if (Land[y - dy, i] > 0) and (Land[y - dy, i] < 256) then dec(Land[y - dy, i]);
   110         for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   111    if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   111             if (Land[y - dy, i] > 0) and (Land[y - dy, i] < 256) then
   112       for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   112                 dec(Land[y - dy, i]);
   113           if (Land[y + dx, i] > 0) and (Land[y + dx, i] < 256) then dec(Land[y + dx, i]);
   113     if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   114    if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
   114         for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   115       for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   115             if (Land[y + dx, i] > 0) and (Land[y + dx, i] < 256) then
   116           if (Land[y - dx, i] > 0) and (Land[y - dx, i] < 256) then dec(Land[y - dx, i]);
   116                 dec(Land[y + dx, i]);
   117    end else
   117     if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
   118    begin
   118         for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   119    if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   119             if (Land[y - dx, i] > 0) and (Land[y - dx, i] < 256) then
   120       for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   120                 dec(Land[y - dx, i]);
   121           if (Land[y + dy, i] < 256) then
   121     end
   122               inc(Land[y + dy, i]);
   122 else
   123    if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   123     begin
   124       for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   124     if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   125           if (Land[y - dy, i] < 256) then
   125         for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   126               inc(Land[y - dy, i]);
   126             if (Land[y + dy, i] < 256) then
   127    if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   127                 inc(Land[y + dy, i]);
   128       for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   128     if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   129           if (Land[y + dx, i] < 256) then
   129         for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   130               inc(Land[y + dx, i]);
   130             if (Land[y - dy, i] < 256) then
   131    if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
   131                 inc(Land[y - dy, i]);
   132       for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   132     if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   133           if (Land[y - dx, i] < 256) then
   133         for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   134               inc(Land[y - dx, i]);
   134             if (Land[y + dx, i] < 256) then
   135    end
   135                 inc(Land[y + dx, i]);
       
   136     if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
       
   137         for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
       
   138             if (Land[y - dx, i] < 256) then
       
   139                 inc(Land[y - dx, i]);
       
   140     end
   136 end;
   141 end;
   137 
   142 
   138 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
   143 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
   139 var dx, dy, d: LongInt;
   144 var dx, dy, d: LongInt;
   140 begin
   145 begin
   141   dx:= 0;
   146 dx:= 0;
   142   dy:= Radius;
   147 dy:= Radius;
   143   d:= 3 - 2 * Radius;
   148 d:= 3 - 2 * Radius;
   144   while (dx < dy) do
   149 while (dx < dy) do
   145      begin
   150     begin
   146      FillCircleLines(x, y, dx, dy, Value);
   151     FillCircleLines(x, y, dx, dy, Value);
   147      if (d < 0)
   152     if (d < 0) then
   148      then d:= d + 4 * dx + 6
   153         d:= d + 4 * dx + 6
   149      else begin
   154     else
   150           d:= d + 4 * (dx - dy) + 10;
   155         begin
   151           dec(dy)
   156         d:= d + 4 * (dx - dy) + 10;
   152           end;
   157         dec(dy)
   153      inc(dx)
   158         end;
   154      end;
   159     inc(dx)
   155   if (dx = dy) then FillCircleLines(x, y, dx, dy, Value);
   160     end;
       
   161 if (dx = dy) then
       
   162     FillCircleLines(x, y, dx, dy, Value);
   156 end;
   163 end;
   157 
   164 
   158 procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean);
   165 procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet: boolean);
   159 var dx, dy, d: LongInt;
   166 var dx, dy, d: LongInt;
   160 begin
   167 begin
   161   dx:= 0;
   168 dx:= 0;
   162   dy:= Radius;
   169 dy:= Radius;
   163   d:= 3 - 2 * Radius;
   170 d:= 3 - 2 * Radius;
   164   while (dx < dy) do
   171 while (dx < dy) do
   165      begin
   172     begin
   166      ChangeCircleLines(x, y, dx, dy, doSet);
   173     ChangeCircleLines(x, y, dx, dy, doSet);
   167      if (d < 0)
   174     if (d < 0) then
   168      then d:= d + 4 * dx + 6
   175         d:= d + 4 * dx + 6
   169      else begin
   176     else
   170           d:= d + 4 * (dx - dy) + 10;
   177         begin
   171           dec(dy)
   178         d:= d + 4 * (dx - dy) + 10;
   172           end;
   179         dec(dy)
   173      inc(dx)
   180         end;
   174      end;
   181     inc(dx)
   175   if (dx = dy) then ChangeCircleLines(x, y, dx, dy, doSet)
   182     end;
       
   183 if (dx = dy) then
       
   184     ChangeCircleLines(x, y, dx, dy, doSet)
   176 end;
   185 end;
   177 
   186 
   178 procedure FillLandCircleLines0(x, y, dx, dy: LongInt);
   187 procedure FillLandCircleLines0(x, y, dx, dy: LongInt);
   179 var i, t: LongInt;
   188 var i, t: LongInt;
   180 begin
   189 begin
   221     cnt: Longword;
   230     cnt: Longword;
   222 begin
   231 begin
   223 cnt:= 0;
   232 cnt:= 0;
   224 t:= y + dy;
   233 t:= y + dy;
   225 if (t and LAND_HEIGHT_MASK) = 0 then
   234 if (t and LAND_HEIGHT_MASK) = 0 then
   226    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   235     for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   227        if (Land[t, i] and lfIndestructible) = 0 then
   236         if (Land[t, i] and lfIndestructible) = 0 then
   228            begin
   237             begin
   229            if (cReducedQuality and rqBlurryLand) = 0 then
   238             if (cReducedQuality and rqBlurryLand) = 0 then
   230                begin
   239                 begin
   231                by:= t; bx:= i;
   240                 by:= t; bx:= i;
   232                end
   241                 end
   233            else
   242             else
   234                begin
   243                 begin
   235                by:= t div 2; bx:= i div 2;
   244                 by:= t div 2; bx:= i div 2;
   236                end;
   245                 end;
   237            if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
   246             if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
   238                begin
   247                 begin
   239                inc(cnt);
   248                 inc(cnt);
   240                LandPixels[by, bx]:= LandBackPixel(i, t)
   249                 LandPixels[by, bx]:= LandBackPixel(i, t)
   241                end
   250                 end
   242            else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
   251             else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
   243                LandPixels[by, bx]:= 0
   252                 LandPixels[by, bx]:= 0
   244            end;
   253             end;
   245 
   254 
   246 t:= y - dy;
   255 t:= y - dy;
   247 if (t and LAND_HEIGHT_MASK) = 0 then
   256 if (t and LAND_HEIGHT_MASK) = 0 then
   248    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   257     for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   249        if (Land[t, i] and lfIndestructible) = 0 then
   258         if (Land[t, i] and lfIndestructible) = 0 then
   250            begin
   259             begin
   251            if (cReducedQuality and rqBlurryLand) = 0 then
   260             if (cReducedQuality and rqBlurryLand) = 0 then
   252                begin
   261                 begin
   253                by:= t; bx:= i;
   262                 by:= t; bx:= i;
   254                end
   263                 end
   255            else
   264             else
   256                begin
   265                 begin
   257                by:= t div 2; bx:= i div 2;
   266                 by:= t div 2; bx:= i div 2;
   258                end;
   267                 end;
   259            if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
   268             if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
   260                begin
   269                 begin
   261                inc(cnt);
   270                 inc(cnt);
   262                LandPixels[by, bx]:= LandBackPixel(i, t)
   271                 LandPixels[by, bx]:= LandBackPixel(i, t)
   263                end
   272                 end
   264            else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
   273             else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
   265                LandPixels[by, bx]:= 0
   274                 LandPixels[by, bx]:= 0
   266            end;
   275             end;
   267 
   276 
   268 t:= y + dx;
   277 t:= y + dx;
   269 if (t and LAND_HEIGHT_MASK) = 0 then
   278 if (t and LAND_HEIGHT_MASK) = 0 then
   270    for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   279     for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   271        if (Land[t, i] and lfIndestructible) = 0 then
   280         if (Land[t, i] and lfIndestructible) = 0 then
   272            begin
   281             begin
   273            if (cReducedQuality and rqBlurryLand) = 0 then
   282             if (cReducedQuality and rqBlurryLand) = 0 then
   274                begin
   283                 begin
   275                by:= t; bx:= i;
   284                 by:= t; bx:= i;
   276                end
   285                 end
   277            else
   286             else
   278                begin
   287                 begin
   279                by:= t div 2; bx:= i div 2;
   288                 by:= t div 2; bx:= i div 2;
   280                end;
   289                 end;
   281            if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
   290             if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
   282                begin
   291                 begin
   283                inc(cnt);
   292                 inc(cnt);
   284                LandPixels[by, bx]:= LandBackPixel(i, t)
   293                 LandPixels[by, bx]:= LandBackPixel(i, t)
   285                end
   294                 end
   286            else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
   295             else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
   287                LandPixels[by, bx]:= 0
   296                 LandPixels[by, bx]:= 0
   288            end;
   297             end;
   289 t:= y - dx;
   298 t:= y - dx;
   290 if (t and LAND_HEIGHT_MASK) = 0 then
   299 if (t and LAND_HEIGHT_MASK) = 0 then
   291    for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   300     for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   292        if (Land[t, i] and lfIndestructible) = 0 then
   301         if (Land[t, i] and lfIndestructible) = 0 then
   293            begin
   302             begin
   294            if (cReducedQuality and rqBlurryLand) = 0 then
   303             if (cReducedQuality and rqBlurryLand) = 0 then
   295                begin
   304                 begin
   296                by:= t; bx:= i;
   305                 by:= t; bx:= i;
   297                end
   306                 end
   298            else
   307             else
   299                begin
   308                 begin
   300                by:= t div 2; bx:= i div 2;
   309                 by:= t div 2; bx:= i div 2;
   301                end;
   310                 end;
   302            if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
   311             if ((Land[t, i] and lfBasic) <> 0) and (((LandPixels[by,bx] and AMask) shr AShift) = 255) and (not disableLandBack) then
   303                begin
   312                 begin
   304                inc(cnt);
   313                 inc(cnt);
   305                LandPixels[by, bx]:= LandBackPixel(i, t)
   314                 LandPixels[by, bx]:= LandBackPixel(i, t)
   306                end
   315                 end
   307            else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
   316             else if ((Land[t, i] and lfObject) <> 0) or (((LandPixels[by,bx] and AMask) shr AShift) < 255) then 
   308                LandPixels[by, bx]:= 0
   317                 LandPixels[by, bx]:= 0
   309            end;
   318             end;
   310 FillLandCircleLinesBG:= cnt;
   319 FillLandCircleLinesBG:= cnt;
   311 end;
   320 end;
   312 
   321 
   313 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt);
   322 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt);
   314 var i, t: LongInt;
   323 var i, t: LongInt;
   315 begin
   324 begin
   316 t:= y + dy;
   325 t:= y + dy;
   317 if (t and LAND_HEIGHT_MASK) = 0 then
   326 if (t and LAND_HEIGHT_MASK) = 0 then
   318    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   327     for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   319        if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
   328         if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
   320           begin
   329             begin
   321            if (cReducedQuality and rqBlurryLand) = 0 then
   330             if (cReducedQuality and rqBlurryLand) = 0 then
   322             LandPixels[t, i]:= cExplosionBorderColor
   331                 LandPixels[t, i]:= cExplosionBorderColor
   323           else
   332             else
   324             LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
   333                 LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
   325 
   334 
   326           Land[t, i]:= Land[t, i] or lfDamaged;
   335             Land[t, i]:= Land[t, i] or lfDamaged;
   327           //Despeckle(i, t);
   336             //Despeckle(i, t);
   328           LandDirty[t div 32, i div 32]:= 1;
   337             LandDirty[t div 32, i div 32]:= 1;
   329           end;
   338             end;
   330 
   339 
   331 t:= y - dy;
   340 t:= y - dy;
   332 if (t and LAND_HEIGHT_MASK) = 0 then
   341 if (t and LAND_HEIGHT_MASK) = 0 then
   333    for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   342     for i:= Max(x - dx, 0) to Min(x + dx, LAND_WIDTH - 1) do
   334        if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
   343         if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
   335           begin
   344             begin
   336            if (cReducedQuality and rqBlurryLand) = 0 then
   345             if (cReducedQuality and rqBlurryLand) = 0 then
   337               LandPixels[t, i]:= cExplosionBorderColor
   346                 LandPixels[t, i]:= cExplosionBorderColor
   338             else
   347             else
   339               LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
   348                 LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
   340           Land[t, i]:= Land[t, i] or lfDamaged;
   349             Land[t, i]:= Land[t, i] or lfDamaged;
   341           //Despeckle(i, t);
   350             //Despeckle(i, t);
   342           LandDirty[t div 32, i div 32]:= 1;
   351             LandDirty[t div 32, i div 32]:= 1;
   343           end;
   352             end;
   344 
   353 
   345 t:= y + dx;
   354 t:= y + dx;
   346 if (t and LAND_HEIGHT_MASK) = 0 then
   355 if (t and LAND_HEIGHT_MASK) = 0 then
   347    for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   356     for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   348        if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
   357         if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
   349            begin
   358             begin
   350            if (cReducedQuality and rqBlurryLand) = 0 then
   359             if (cReducedQuality and rqBlurryLand) = 0 then
   351            LandPixels[t, i]:= cExplosionBorderColor
   360                 LandPixels[t, i]:= cExplosionBorderColor
   352             else
   361             else
   353            LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
   362                LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
   354 
   363 
   355            Land[t, i]:= Land[t, i] or lfDamaged;
   364             Land[t, i]:= Land[t, i] or lfDamaged;
   356            //Despeckle(i, t);
   365             //Despeckle(i, t);
   357            LandDirty[t div 32, i div 32]:= 1;
   366             LandDirty[t div 32, i div 32]:= 1;
   358            end;
   367             end;
   359 
   368 
   360 t:= y - dx;
   369 t:= y - dx;
   361 if (t and LAND_HEIGHT_MASK) = 0 then
   370 if (t and LAND_HEIGHT_MASK) = 0 then
   362    for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   371     for i:= Max(x - dy, 0) to Min(x + dy, LAND_WIDTH - 1) do
   363        if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
   372         if ((Land[t, i] and lfBasic) <> 0) or ((Land[t, i] and lfObject) <> 0) then
   364           begin
   373             begin
   365            if (cReducedQuality and rqBlurryLand) = 0 then
   374             if (cReducedQuality and rqBlurryLand) = 0 then
   366           LandPixels[t, i]:= cExplosionBorderColor
   375                 LandPixels[t, i]:= cExplosionBorderColor
   367             else
   376             else
   368           LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
   377                 LandPixels[t div 2, i div 2]:= cExplosionBorderColor;
   369 
   378 
   370           Land[t, i]:= Land[t, i] or lfDamaged;
   379             Land[t, i]:= Land[t, i] or lfDamaged;
   371           //Despeckle(i, y - dy);
   380             //Despeckle(i, y - dy);
   372           LandDirty[t div 32, i div 32]:= 1;
   381             LandDirty[t div 32, i div 32]:= 1;
   373           end;
   382             end;
   374 end;
   383 end;
   375 
   384 
   376 function DrawExplosion(X, Y, Radius: LongInt): Longword;
   385 function DrawExplosion(X, Y, Radius: LongInt): Longword;
   377 var dx, dy, ty, tx, d: LongInt;
   386 var dx, dy, ty, tx, d: LongInt;
   378     cnt: Longword;
   387     cnt: Longword;
   386     d:= 3 - 2 * Radius;
   395     d:= 3 - 2 * Radius;
   387 
   396 
   388     while (dx < dy) do
   397     while (dx < dy) do
   389         begin
   398         begin
   390         inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
   399         inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
   391         if (d < 0)
   400         if (d < 0) then
   392         then d:= d + 4 * dx + 6
   401             d:= d + 4 * dx + 6
   393         else begin
   402         else
       
   403             begin
   394             d:= d + 4 * (dx - dy) + 10;
   404             d:= d + 4 * (dx - dy) + 10;
   395             dec(dy)
   405             dec(dy)
   396             end;
   406             end;
   397         inc(dx)
   407         inc(dx)
   398         end;
   408         end;
   399     if (dx = dy) then inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
   409     if (dx = dy) then
       
   410         inc(cnt, FillLandCircleLinesBG(x, y, dx, dy));
   400     end;
   411     end;
   401 
   412 
   402 // draw a hole in land
   413 // draw a hole in land
   403 if Radius > 20 then
   414 if Radius > 20 then
   404     begin
   415     begin
   407     d:= 3 - 2 * dy;
   418     d:= 3 - 2 * dy;
   408 
   419 
   409     while (dx < dy) do
   420     while (dx < dy) do
   410         begin
   421         begin
   411         FillLandCircleLines0(x, y, dx, dy);
   422         FillLandCircleLines0(x, y, dx, dy);
   412         if (d < 0)
   423         if (d < 0) then
   413         then d:= d + 4 * dx + 6
   424             d:= d + 4 * dx + 6
   414         else begin
   425         else
       
   426             begin
   415             d:= d + 4 * (dx - dy) + 10;
   427             d:= d + 4 * (dx - dy) + 10;
   416             dec(dy)
   428             dec(dy)
   417             end;
   429             end;
   418         inc(dx)
   430         inc(dx)
   419         end;
   431         end;
   420     if (dx = dy) then FillLandCircleLines0(x, y, dx, dy);
   432     if (dx = dy) then
       
   433         FillLandCircleLines0(x, y, dx, dy);
   421     end;
   434     end;
   422 
   435 
   423   // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function
   436   // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function
   424     FillRoundInLand(X, Y, Radius, 0);
   437     FillRoundInLand(X, Y, Radius, 0);
   425 
   438 
   430     dy:= Radius;
   443     dy:= Radius;
   431     d:= 3 - 2 * Radius;
   444     d:= 3 - 2 * Radius;
   432     while (dx < dy) do
   445     while (dx < dy) do
   433         begin
   446         begin
   434         FillLandCircleLinesEBC(x, y, dx, dy);
   447         FillLandCircleLinesEBC(x, y, dx, dy);
   435         if (d < 0)
   448         if (d < 0) then
   436         then d:= d + 4 * dx + 6
   449             d:= d + 4 * dx + 6
   437         else begin
   450         else
       
   451             begin
   438             d:= d + 4 * (dx - dy) + 10;
   452             d:= d + 4 * (dx - dy) + 10;
   439             dec(dy)
   453             dec(dy)
   440             end;
   454             end;
   441         inc(dx)
   455         inc(dx)
   442         end;
   456         end;
   443     if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy);
   457     if (dx = dy) then
       
   458         FillLandCircleLinesEBC(x, y, dx, dy);
   444     end;
   459     end;
   445 
   460 
   446 tx:= Max(X - Radius - 1, 0);
   461 tx:= Max(X - Radius - 1, 0);
   447 dx:= Min(X + Radius + 1, LAND_WIDTH) - tx;
   462 dx:= Min(X + Radius + 1, LAND_WIDTH) - tx;
   448 ty:= Max(Y - Radius - 1, 0);
   463 ty:= Max(Y - Radius - 1, 0);
   485     begin
   500     begin
   486     for ty:= Max(y - Radius, 0) to Min(y + Radius, LAND_HEIGHT) do
   501     for ty:= Max(y - Radius, 0) to Min(y + Radius, LAND_HEIGHT) do
   487         for tx:= Max(0, ar^[i].Left - Radius) to Min(LAND_WIDTH, ar^[i].Right + Radius) do
   502         for tx:= Max(0, ar^[i].Left - Radius) to Min(LAND_WIDTH, ar^[i].Right + Radius) do
   488             if ((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0) then
   503             if ((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0) then
   489                 begin
   504                 begin
   490                     if (cReducedQuality and rqBlurryLand) = 0 then
   505                  if (cReducedQuality and rqBlurryLand) = 0 then
   491                         LandPixels[ty, tx]:= cExplosionBorderColor
   506                     LandPixels[ty, tx]:= cExplosionBorderColor
   492                     else
   507                 else
   493                         LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor;
   508                     LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor;
   494 
   509 
   495                 Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   510                 Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   496                 LandDirty[ty div 32, tx div 32]:= 1;
   511                 LandDirty[ty div 32, tx div 32]:= 1;
   497                 end;
   512                 end;
   498     inc(y, dY)
   513     inc(y, dY)
   528     begin
   543     begin
   529     X:= X + dX;
   544     X:= X + dX;
   530     Y:= Y + dY;
   545     Y:= Y + dY;
   531     tx:= hwRound(X);
   546     tx:= hwRound(X);
   532     ty:= hwRound(Y);
   547     ty:= hwRound(Y);
   533     if ((ty and LAND_HEIGHT_MASK) = 0) and
   548     if ((ty and LAND_HEIGHT_MASK) = 0)
   534        ((tx and LAND_WIDTH_MASK) = 0) and
   549     and ((tx and LAND_WIDTH_MASK) = 0)
   535        (((Land[ty, tx] and lfBasic) <> 0) or
   550     and (((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0)) then
   536        ((Land[ty, tx] and lfObject) <> 0)) then
       
   537         begin
   551         begin
   538         if despeckle then 
   552         if despeckle then 
   539             begin
   553             begin
   540             Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   554             Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   541             LandDirty[ty div 32, tx div 32]:= 1
   555             LandDirty[ty div 32, tx div 32]:= 1
   542             end;
   556             end;
   543         if (cReducedQuality and rqBlurryLand) = 0 then
   557         if (cReducedQuality and rqBlurryLand) = 0 then
   544             LandPixels[ty, tx]:= cExplosionBorderColor
   558             LandPixels[ty, tx]:= cExplosionBorderColor
   545         else LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
   559         else
       
   560             LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
   546         end
   561         end
   547     end;
   562     end;
   548     nx:= nx - dY;
   563     nx:= nx - dY;
   549     ny:= ny + dX;
   564     ny:= ny + dX;
   550     end;
   565     end;
   552 for i:= -HalfWidth to HalfWidth do
   567 for i:= -HalfWidth to HalfWidth do
   553     begin
   568     begin
   554     X:= nx - dX8;
   569     X:= nx - dX8;
   555     Y:= ny - dY8;
   570     Y:= ny - dY8;
   556     for t:= 0 to 7 do
   571     for t:= 0 to 7 do
   557     begin
   572         begin
   558     X:= X + dX;
   573         X:= X + dX;
   559     Y:= Y + dY;
   574         Y:= Y + dY;
   560     tx:= hwRound(X);
   575         tx:= hwRound(X);
   561     ty:= hwRound(Y);
   576         ty:= hwRound(Y);
   562     if ((ty and LAND_HEIGHT_MASK) = 0) and
   577         if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
   563        ((tx and LAND_WIDTH_MASK) = 0) and
   578         or ((Land[ty, tx] and lfObject) <> 0)) then
   564        (((Land[ty, tx] and lfBasic) <> 0) or
   579             begin
   565        ((Land[ty, tx] and lfObject) <> 0)) then
   580             Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   566         begin
   581             if despeckle then
   567         Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   582                 LandDirty[ty div 32, tx div 32]:= 1;
   568         if despeckle then LandDirty[ty div 32, tx div 32]:= 1;
   583             if (cReducedQuality and rqBlurryLand) = 0 then
   569         if (cReducedQuality and rqBlurryLand) = 0 then
   584                 LandPixels[ty, tx]:= cExplosionBorderColor
   570             LandPixels[ty, tx]:= cExplosionBorderColor
   585             else
   571         else LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
   586                 LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
   572         end
   587             end
   573     end;
   588         end;
   574     X:= nx;
   589     X:= nx;
   575     Y:= ny;
   590     Y:= ny;
   576     for t:= 0 to ticks do
   591     for t:= 0 to ticks do
   577         begin
   592         begin
   578         X:= X + dX;
   593         X:= X + dX;
   600     begin
   615     begin
   601     X:= X + dX;
   616     X:= X + dX;
   602     Y:= Y + dY;
   617     Y:= Y + dY;
   603     tx:= hwRound(X);
   618     tx:= hwRound(X);
   604     ty:= hwRound(Y);
   619     ty:= hwRound(Y);
   605     if ((ty and LAND_HEIGHT_MASK) = 0) and
   620     if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
   606        ((tx and LAND_WIDTH_MASK) = 0) and
   621     or ((Land[ty, tx] and lfObject) <> 0)) then
   607        (((Land[ty, tx] and lfBasic) <> 0) or
       
   608        ((Land[ty, tx] and lfObject) <> 0)) then
       
   609         begin
   622         begin
   610         Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   623         Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   611         if despeckle then LandDirty[ty div 32, tx div 32]:= 1;
   624         if despeckle then
       
   625             LandDirty[ty div 32, tx div 32]:= 1;
   612         if (cReducedQuality and rqBlurryLand) = 0 then
   626         if (cReducedQuality and rqBlurryLand) = 0 then
   613             LandPixels[ty, tx]:= cExplosionBorderColor
   627             LandPixels[ty, tx]:= cExplosionBorderColor
   614         else LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
   628         else
       
   629             LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
   615         end
   630         end
   616     end;
   631         end;
   617     nx:= nx - dY;
   632     nx:= nx - dY;
   618     ny:= ny + dX;
   633     ny:= ny + dX;
   619     end;
   634     end;
   620 
   635 
   621 for i:= 0 to 7 do
   636 for i:= 0 to 7 do
   626     begin
   641     begin
   627     X:= X + dX;
   642     X:= X + dX;
   628     Y:= Y + dY;
   643     Y:= Y + dY;
   629     tx:= hwRound(X);
   644     tx:= hwRound(X);
   630     ty:= hwRound(Y);
   645     ty:= hwRound(Y);
   631     if ((ty and LAND_HEIGHT_MASK) = 0) and
   646     if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
   632        ((tx and LAND_WIDTH_MASK) = 0) and
   647     or ((Land[ty, tx] and lfObject) <> 0)) then
   633        (((Land[ty, tx] and lfBasic) <> 0) or
       
   634        ((Land[ty, tx] and lfObject) <> 0)) then
       
   635         begin
   648         begin
   636         Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   649         Land[ty, tx]:= Land[ty, tx] or lfDamaged;
   637         if despeckle then LandDirty[ty div 32, tx div 32]:= 1;
   650         if despeckle then
       
   651             LandDirty[ty div 32, tx div 32]:= 1;
   638         if (cReducedQuality and rqBlurryLand) = 0 then
   652         if (cReducedQuality and rqBlurryLand) = 0 then
   639             LandPixels[ty, tx]:= cExplosionBorderColor
   653             LandPixels[ty, tx]:= cExplosionBorderColor
   640         else LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
   654         else
       
   655             LandPixels[ty div 2, tx div 2]:= cExplosionBorderColor
   641         end
   656         end
   642     end;
   657     end;
   643     nx:= nx - dY;
   658     nx:= nx - dY;
   644     ny:= ny + dX;
   659     ny:= ny + dX;
   645     end;
   660     end;
   665 h:= SpritesData[Obj].Height;
   680 h:= SpritesData[Obj].Height;
   666 row:= Frame mod numFramesFirstCol;
   681 row:= Frame mod numFramesFirstCol;
   667 col:= Frame div numFramesFirstCol;
   682 col:= Frame div numFramesFirstCol;
   668 
   683 
   669 if SDL_MustLock(Image) then
   684 if SDL_MustLock(Image) then
   670    SDLTry(SDL_LockSurface(Image) >= 0, true);
   685     SDLTry(SDL_LockSurface(Image) >= 0, true);
   671 
   686 
   672 bpp:= Image^.format^.BytesPerPixel;
   687 bpp:= Image^.format^.BytesPerPixel;
   673 TryDo(bpp = 4, 'It should be 32 bpp sprite', true);
   688 TryDo(bpp = 4, 'It should be 32 bpp sprite', true);
   674 // Check that sprite fits free space
   689 // Check that sprite fits free space
   675 p:= @(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ]);
   690 p:= @(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ]);
   676 case bpp of
   691 case bpp of
   677      4: for y:= 0 to Pred(h) do
   692     4: for y:= 0 to Pred(h) do
   678             begin
   693         begin
   679             for x:= 0 to Pred(w) do
   694         for x:= 0 to Pred(w) do
   680                 if (PLongword(@(p^[x * 4]))^) <> 0 then
   695             if (PLongword(@(p^[x * 4]))^) <> 0 then
   681                    if ((cpY + y) <= Longint(topY)) or
   696                 if ((cpY + y) <= Longint(topY)) or ((cpY + y) >= LAND_HEIGHT)
   682                       ((cpY + y) >= LAND_HEIGHT) or
   697                 or ((cpX + x) <= Longint(leftX)) or ((cpX + x) >= Longint(rightX)) or (Land[cpY + y, cpX + x] <> 0) then
   683                       ((cpX + x) <= Longint(leftX)) or
   698                     begin
   684                       ((cpX + x) >= Longint(rightX)) or
   699                     if SDL_MustLock(Image) then
   685                       (Land[cpY + y, cpX + x] <> 0) then
   700                         SDL_UnlockSurface(Image);
   686                       begin
   701                     exit(false)
   687                       if SDL_MustLock(Image) then
   702                     end;
   688                          SDL_UnlockSurface(Image);
   703         p:= @(p^[Image^.pitch]);
   689                       exit(false)
   704         end;
   690                       end;
   705     end;
   691             p:= @(p^[Image^.pitch]);
       
   692             end;
       
   693      end;
       
   694 
   706 
   695 TryPlaceOnLand:= true;
   707 TryPlaceOnLand:= true;
   696 if not doPlace then
   708 if not doPlace then
   697    begin
   709     begin
   698    if SDL_MustLock(Image) then
   710     if SDL_MustLock(Image) then
   699       SDL_UnlockSurface(Image);
   711         SDL_UnlockSurface(Image);
   700    exit
   712     exit
   701    end;
   713     end;
   702 
   714 
   703 // Checked, now place
   715 // Checked, now place
   704 p:= @(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ]);
   716 p:= @(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ]);
   705 case bpp of
   717 case bpp of
   706      4: for y:= 0 to Pred(h) do
   718     4: for y:= 0 to Pred(h) do
   707             begin
   719         begin
   708             for x:= 0 to Pred(w) do
   720         for x:= 0 to Pred(w) do
   709                 if (PLongword(@(p^[x * 4]))^) <> 0 then
   721             if (PLongword(@(p^[x * 4]))^) <> 0 then
   710                    begin
   722                    begin
   711                    if (cReducedQuality and rqBlurryLand) = 0 then
   723                 if (cReducedQuality and rqBlurryLand) = 0 then
   712                        begin
   724                     begin
   713                        gX:= cpX + x;
   725                     gX:= cpX + x;
   714                        gY:= cpY + y;
   726                     gY:= cpY + y;
   715                        end
   727                     end
   716                    else
   728                 else
   717                        begin
   729                      begin
   718                        gX:= (cpX + x) div 2;
   730                      gX:= (cpX + x) div 2;
   719                        gY:= (cpY + y) div 2;
   731                      gY:= (cpY + y) div 2;
   720                        end;
   732                     end;
   721                    if indestructible then
   733                 if indestructible then
   722                        Land[cpY + y, cpX + x]:= lfIndestructible
   734                     Land[cpY + y, cpX + x]:= lfIndestructible
   723                    else if (LandPixels[gY, gX] and AMask) shr AShift = 255 then  // This test assumes lfBasic and lfObject differ only graphically
   735                 else if (LandPixels[gY, gX] and AMask) shr AShift = 255 then  // This test assumes lfBasic and lfObject differ only graphically
   724                        Land[cpY + y, cpX + x]:= lfBasic
   736                     Land[cpY + y, cpX + x]:= lfBasic
   725                    else
   737                 else
   726                        Land[cpY + y, cpX + x]:= lfObject;
   738                     Land[cpY + y, cpX + x]:= lfObject;
   727                    // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun
   739                 // For testing only. Intent is to flag this on objects with masks, or use it for an ice ray gun
   728                    if (Theme = 'Snow') or (Theme = 'Christmas') then Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or lfIce;
   740                 if (Theme = 'Snow') or (Theme = 'Christmas') then
   729                    LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^
   741                     Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or lfIce;
   730                    end;
   742                     LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^
   731             p:= @(p^[Image^.pitch]);
   743                 end;
   732             end;
   744         p:= @(p^[Image^.pitch]);
   733      end;
   745         end;
       
   746     end;
   734 if SDL_MustLock(Image) then
   747 if SDL_MustLock(Image) then
   735    SDL_UnlockSurface(Image);
   748     SDL_UnlockSurface(Image);
   736 
   749 
   737 x:= Max(cpX, leftX);
   750 x:= Max(cpX, leftX);
   738 w:= Min(cpX + Image^.w, LAND_WIDTH) - x;
   751 w:= Min(cpX + Image^.w, LAND_WIDTH) - x;
   739 y:= Max(cpY, topY);
   752 y:= Max(cpY, topY);
   740 h:= Min(cpY + Image^.h, LAND_HEIGHT) - y;
   753 h:= Min(cpY + Image^.h, LAND_HEIGHT) - y;
   744 function Despeckle(X, Y: LongInt): boolean;
   757 function Despeckle(X, Y: LongInt): boolean;
   745 var nx, ny, i, j, c, xx, yy: LongInt;
   758 var nx, ny, i, j, c, xx, yy: LongInt;
   746     pixelsweep: boolean;
   759     pixelsweep: boolean;
   747 begin
   760 begin
   748 if (cReducedQuality and rqBlurryLand) = 0 then
   761 if (cReducedQuality and rqBlurryLand) = 0 then
   749    begin
   762     begin
   750    xx:= X;
   763     xx:= X;
   751    yy:= Y;
   764     yy:= Y;
   752    end
   765     end
   753 else
   766 else
   754    begin
   767     begin
   755    xx:= X div 2;
   768     xx:= X div 2;
   756    yy:= Y div 2;
   769     yy:= Y div 2;
   757    end;
   770     end;
   758 pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0);
   771 pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0);
   759 if (((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then
   772 if (((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then
   760     begin
   773     begin
   761     c:= 0;
   774     c:= 0;
   762     for i:= -1 to 1 do
   775     for i:= -1 to 1 do
   772                         if ((cReducedQuality and rqBlurryLand) <> 0) then
   785                         if ((cReducedQuality and rqBlurryLand) <> 0) then
   773                             begin
   786                             begin
   774                             nx:= nx div 2;
   787                             nx:= nx div 2;
   775                             ny:= ny div 2
   788                             ny:= ny div 2
   776                             end;
   789                             end;
   777                         if LandPixels[ny, nx] <> 0 then inc(c);
   790                         if LandPixels[ny, nx] <> 0 then
       
   791                             inc(c);
   778                         end
   792                         end
   779                     else if Land[ny, nx] > 255 then inc(c);
   793                     else if Land[ny, nx] > 255 then
       
   794                         inc(c);
   780                     end
   795                     end
   781                 end;
   796                 end;
   782 
   797 
   783     if c < 4 then // 0-3 neighbours
   798     if c < 4 then // 0-3 neighbours
   784         begin
   799         begin
   786             LandPixels[yy, xx]:= LandBackPixel(X, Y)
   801             LandPixels[yy, xx]:= LandBackPixel(X, Y)
   787         else
   802         else
   788             LandPixels[yy, xx]:= 0;
   803             LandPixels[yy, xx]:= 0;
   789 
   804 
   790         Land[Y, X]:= 0;
   805         Land[Y, X]:= 0;
   791         if not pixelsweep then exit(true);
   806         if not pixelsweep then
       
   807             exit(true);
   792         end;
   808         end;
   793     end;
   809     end;
   794 Despeckle:= false
   810 Despeckle:= false
   795 end;
   811 end;
   796 
   812 
   797 procedure Smooth(X, Y: LongInt);
   813 procedure Smooth(X, Y: LongInt);
   798 begin
   814 begin
   799 // a bit of AA for explosions
   815 // a bit of AA for explosions
   800 if (Land[Y, X] = 0) and (Y > LongInt(topY) + 1) and 
   816 if (Land[Y, X] = 0) and (Y > LongInt(topY) + 1) and 
   801    (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
   817     (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
   802     begin
   818     begin
   803     if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0)) or
   819     if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0))
   804        (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then
   820     or (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then
   805         begin
   821         begin
   806         if (cReducedQuality and rqBlurryLand) = 0 then
   822         if (cReducedQuality and rqBlurryLand) = 0 then
   807             begin
   823             begin
   808             if ((LandPixels[y,x] and AMask) shr AShift) < 10 then LandPixels[y,x]:= (cExplosionBorderColor and (not AMask)) or (128 shl AShift)
   824             if ((LandPixels[y,x] and AMask) shr AShift) < 10 then
       
   825                 LandPixels[y,x]:= (cExplosionBorderColor and (not AMask)) or (128 shl AShift)
   809             else
   826             else
   810                 LandPixels[y,x]:=
   827                 LandPixels[y,x]:=
   811                                 (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
   828                                 (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
   812                                 (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or
   829                                 (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or
   813                                 (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift)
   830                                 (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift)
   814             end;
   831             end;
   815         if (Land[y, x-1] = lfObject) then Land[y,x]:= lfObject
   832         if (Land[y, x-1] = lfObject) then
   816         else if (Land[y, x+1] = lfObject) then Land[y,x]:= lfObject
   833             Land[y,x]:= lfObject
   817         else Land[y,x]:= lfBasic;
   834         else if (Land[y, x+1] = lfObject) then
       
   835             Land[y,x]:= lfObject
       
   836         else
       
   837             Land[y,x]:= lfBasic;
   818         end
   838         end
   819     else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or
   839     else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0))
   820             (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or
   840     or (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0))
   821             (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or
   841     or (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0))
   822             (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or
   842     or (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0))
   823             (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or
   843     or (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0))
   824             (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or
   844     or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0))
   825             (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0)) or
   845     or (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))
   826             (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then
   846     or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then
   827         begin
   847         begin
   828         if (cReducedQuality and rqBlurryLand) = 0 then
   848         if (cReducedQuality and rqBlurryLand) = 0 then
   829             begin
   849             begin
   830             if ((LandPixels[y,x] and AMask) shr AShift) < 10 then LandPixels[y,x]:= (cExplosionBorderColor and (not AMask)) or (64 shl AShift)
   850             if ((LandPixels[y,x] and AMask) shr AShift) < 10 then
       
   851                 LandPixels[y,x]:= (cExplosionBorderColor and (not AMask)) or (64 shl AShift)
   831             else
   852             else
   832                 LandPixels[y,x]:=
   853                 LandPixels[y,x]:=
   833                                 (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
   854                                 (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
   834                                 (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or
   855                                 (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or
   835                                 (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift)
   856                                 (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift)
   836             end;
   857             end;
   837         if (Land[y, x-1] = lfObject) then Land[y, x]:= lfObject
   858         if (Land[y, x-1] = lfObject) then
   838         else if (Land[y, x+1] = lfObject) then Land[y, x]:= lfObject
   859             Land[y, x]:= lfObject
   839         else if (Land[y+1, x] = lfObject) then Land[y, x]:= lfObject
   860         else if (Land[y, x+1] = lfObject) then
   840         else if (Land[y-1, x] = lfObject) then Land[y, x]:= lfObject
   861             Land[y, x]:= lfObject
       
   862         else if (Land[y+1, x] = lfObject) then
       
   863             Land[y, x]:= lfObject
       
   864         else if (Land[y-1, x] = lfObject) then
       
   865         Land[y, x]:= lfObject
   841         else Land[y,x]:= lfBasic
   866         else Land[y,x]:= lfBasic
   842         end
   867         end
   843     end
   868     end
   844 else if ((cReducedQuality and rqBlurryLand) = 0) and (LandPixels[Y, X] and AMask = 255) and
   869 else if ((cReducedQuality and rqBlurryLand) = 0) and (LandPixels[Y, X] and AMask = 255)
   845     ((Land[Y, X] and (lfDamaged or lfBasic) = lfBasic) or (Land[Y, X] and (lfDamaged or lfBasic) = lfBasic)) and 
   870 and ((Land[Y, X] and (lfDamaged or lfBasic) = lfBasic) or (Land[Y, X] and (lfDamaged or lfBasic) = lfBasic))
   846     (Y > LongInt(topY) + 1) and (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
   871 and (Y > LongInt(topY) + 1) and (Y < LAND_HEIGHT-2) and (X > LongInt(leftX) + 1) and (X < LongInt(rightX) - 1) then
   847     begin
   872     begin
   848     if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0)) or
   873     if ((((Land[y, x-1] and lfDamaged) <> 0) and (((Land[y+1,x] and lfDamaged) <> 0)) or ((Land[y-1,x] and lfDamaged) <> 0))
   849        (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then
   874     or (((Land[y, x+1] and lfDamaged) <> 0) and (((Land[y-1,x] and lfDamaged) <> 0) or ((Land[y+1,x] and lfDamaged) <> 0)))) then
   850         begin
   875         begin
   851         LandPixels[y,x]:=
   876         LandPixels[y,x]:=
   852                         (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
   877                         (((((LandPixels[y,x] and RMask shr RShift) div 2)+((cExplosionBorderColor and RMask) shr RShift) div 2) and $FF) shl RShift) or
   853                         (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or
   878                         (((((LandPixels[y,x] and GMask shr GShift) div 2)+((cExplosionBorderColor and GMask) shr GShift) div 2) and $FF) shl GShift) or
   854                         (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift)
   879                         (((((LandPixels[y,x] and BMask shr BShift) div 2)+((cExplosionBorderColor and BMask) shr BShift) div 2) and $FF) shl BShift) or ($FF shl AShift)
   855         end
   880         end
   856     else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or
   881     else if ((((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0))
   857             (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or
   882     or (((Land[y, x-1] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0))
   858             (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0)) or
   883     or (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y+2,x] and lfDamaged) <> 0))
   859             (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0)) or
   884     or (((Land[y, x+1] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y-2,x] and lfDamaged) <> 0))
   860             (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or
   885     or (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0))
   861             (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0)) or
   886     or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x+1] and lfDamaged) <> 0) and ((Land[y,x+2] and lfDamaged) <> 0))
   862             (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0)) or
   887     or (((Land[y+1, x] and lfDamaged) <> 0) and ((Land[y+1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))
   863             (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then
   888     or (((Land[y-1, x] and lfDamaged) <> 0) and ((Land[y-1,x-1] and lfDamaged) <> 0) and ((Land[y,x-2] and lfDamaged) <> 0))) then
   864         begin
   889         begin
   865         LandPixels[y,x]:=
   890         LandPixels[y,x]:=
   866                         (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
   891                         (((((LandPixels[y,x] and RMask shr RShift) * 3 div 4)+((cExplosionBorderColor and RMask) shr RShift) div 4) and $FF) shl RShift) or
   867                         (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or
   892                         (((((LandPixels[y,x] and GMask shr GShift) * 3 div 4)+((cExplosionBorderColor and GMask) shr GShift) div 4) and $FF) shl GShift) or
   868                         (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift)
   893                         (((((LandPixels[y,x] and BMask shr BShift) * 3 div 4)+((cExplosionBorderColor and BMask) shr BShift) div 4) and $FF) shl BShift) or ($FF shl AShift)
   920                                     LandDirty[y, x+1]:= 1;
   945                                     LandDirty[y, x+1]:= 1;
   921                                     recheck:= true;
   946                                     recheck:= true;
   922                                     end
   947                                     end
   923                                 end;
   948                                 end;
   924                     end;
   949                     end;
   925                 if updateBlock then UpdateLandTexture(tx, 32, ty, 32);
   950                 if updateBlock then
       
   951                     UpdateLandTexture(tx, 32, ty, 32);
   926                 LandDirty[y, x]:= 2;
   952                 LandDirty[y, x]:= 2;
   927                 end;
   953                 end;
   928             end;
   954             end;
   929         end;
   955         end;
   930      end;
   956      end;
   946 
   972 
   947 
   973 
   948 // Return true if outside of land or not the value tested, used right now for some X/Y movement that does not use normal hedgehog movement in GSHandlers.inc
   974 // Return true if outside of land or not the value tested, used right now for some X/Y movement that does not use normal hedgehog movement in GSHandlers.inc
   949 function CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean; inline;
   975 function CheckLandValue(X, Y: LongInt; LandFlag: Word): boolean; inline;
   950 begin
   976 begin
   951      CheckLandValue:= ((X and LAND_WIDTH_MASK <> 0) or (Y and LAND_HEIGHT_MASK <> 0)) or ((Land[Y, X] and LandFlag) = 0)
   977     CheckLandValue:= ((X and LAND_WIDTH_MASK <> 0) or (Y and LAND_HEIGHT_MASK <> 0)) or ((Land[Y, X] and LandFlag) = 0)
   952 end;
   978 end;
   953 
   979 
   954 function LandBackPixel(x, y: LongInt): LongWord; inline;
   980 function LandBackPixel(x, y: LongInt): LongWord; inline;
   955 var p: PLongWordArray;
   981 var p: PLongWordArray;
   956 begin
   982 begin
   957     if LandBackSurface = nil then LandBackPixel:= 0
   983     if LandBackSurface = nil then
       
   984         LandBackPixel:= 0
   958     else
   985     else
   959     begin
   986         begin
   960         p:= LandBackSurface^.pixels;
   987         p:= LandBackSurface^.pixels;
   961         LandBackPixel:= p^[LandBackSurface^.w * (y mod LandBackSurface^.h) + (x mod LandBackSurface^.w)];// or $FF000000;
   988         LandBackPixel:= p^[LandBackSurface^.w * (y mod LandBackSurface^.h) + (x mod LandBackSurface^.w)];// or $FF000000;
   962     end
   989         end
   963 end;
   990 end;
   964 
   991 
   965 
   992 
   966 procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
   993 procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
   967 var
   994 var
   971 eX:= 0;
   998 eX:= 0;
   972 eY:= 0;
   999 eY:= 0;
   973 dX:= X2 - X1;
  1000 dX:= X2 - X1;
   974 dY:= Y2 - Y1;
  1001 dY:= Y2 - Y1;
   975 
  1002 
   976 if (dX > 0) then sX:= 1
  1003 if (dX > 0) then
       
  1004     sX:= 1
   977 else
  1005 else
   978   if (dX < 0) then
  1006     if (dX < 0) then
   979      begin
  1007         begin
   980      sX:= -1;
  1008         sX:= -1;
   981      dX:= -dX
  1009         dX:= -dX
   982      end else sX:= dX;
  1010         end
   983 
  1011     else
   984 if (dY > 0) then sY:= 1
  1012         sX:= dX;
   985   else
  1013 
   986   if (dY < 0) then
  1014 if (dY > 0) then
   987      begin
  1015     sY:= 1
   988      sY:= -1;
  1016 else
   989      dY:= -dY
  1017     if (dY < 0) then
   990      end else sY:= dY;
  1018         begin
   991 
  1019         sY:= -1;
   992 if (dX > dY) then d:= dX
  1020         dY:= -dY
   993              else d:= dY;
  1021         end
       
  1022     else
       
  1023         sY:= dY;
       
  1024 
       
  1025 if (dX > dY) then
       
  1026     d:= dX
       
  1027 else
       
  1028     d:= dY;
   994 
  1029 
   995 x:= X1;
  1030 x:= X1;
   996 y:= Y1;
  1031 y:= Y1;
   997 
  1032 
   998 for i:= 0 to d do
  1033 for i:= 0 to d do
   999     begin
  1034     begin
  1000     inc(eX, dX);
  1035     inc(eX, dX);
  1001     inc(eY, dY);
  1036     inc(eY, dY);
  1002     if (eX > d) then
  1037     if (eX > d) then
  1003        begin
  1038         begin
  1004        dec(eX, d);
  1039         dec(eX, d);
  1005        inc(x, sX);
  1040         inc(x, sX);
  1006        end;
  1041         end;
  1007     if (eY > d) then
  1042     if (eY > d) then
  1008        begin
  1043         begin
  1009        dec(eY, d);
  1044         dec(eY, d);
  1010        inc(y, sY);
  1045         inc(y, sY);
  1011        end;
  1046         end;
  1012 
  1047 
  1013     if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
  1048     if ((x and LAND_WIDTH_MASK) = 0) and ((y and LAND_HEIGHT_MASK) = 0) then
  1014        Land[y, x]:= Color;
  1049         Land[y, x]:= Color;
  1015     end
  1050     end
  1016 end;
  1051 end;
  1017 
  1052 
  1018 end.
  1053 end.