hedgewars/uLandGraphics.pas
changeset 2602 3deb9ff104da
parent 2599 c7153d2348f3
child 2603 abed6070a669
equal deleted inserted replaced
2601:21ed7cec1fa2 2602:3deb9ff104da
   137      inc(dx)
   137      inc(dx)
   138      end;
   138      end;
   139   if (dx = dy) then ChangeCircleLines(x, y, dx, dy, doSet)
   139   if (dx = dy) then ChangeCircleLines(x, y, dx, dy, doSet)
   140 end;
   140 end;
   141 
   141 
   142 procedure FillLandCircleLines0(x, y, dx, dy: LongInt);
   142 procedure FillLandCircleLines0(x, y, dx, dy, cr: LongInt);
   143 var i: LongInt;
   143 var i: LongInt;
   144 begin
   144 begin
       
   145 cr:= cr * cr; // avoid sqrt() to compare lengths/distances
   145 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   146 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   146     for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
   147     for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
   147         if Land[y + dy, i] = COLOR_LAND then
   148         if (LandPixels[y + dy, i] and $FF000000) <> 0 then
   148             LandPixels[y + dy, i]:= 0;
   149             if (dy * dy + (i - x) * (i - x) < cr) or (Land[y + dy, i] = COLOR_OBJECT) then
       
   150                 LandPixels[y + dy, i]:= 0
       
   151             else
       
   152                 LandPixels[y + dy, i]:= LandBackPixel(i, y + dy);
   149 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   153 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   150     for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
   154     for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
   151         if Land[y - dy, i] = COLOR_LAND then
   155         if (LandPixels[y - dy, i] and $FF000000) <> 0 then
   152              LandPixels[y - dy, i]:= 0;
   156             if (dy * dy + (i - x) * (i - x) < cr) or (Land[y - dy, i] = COLOR_OBJECT) then
       
   157                 LandPixels[y - dy, i]:= 0
       
   158             else
       
   159                 LandPixels[y - dy, i]:= LandBackPixel(i, y - dy);
   153 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   160 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   154     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
   161     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
   155         if Land[y + dx, i] = COLOR_LAND then
   162         if (LandPixels[y + dx, i] and $FF000000) <> 0 then
   156             LandPixels[y + dx, i]:= 0;
   163             if (dx * dx + (i - x) * (i - x) < cr) or (Land[y + dx, i] = COLOR_OBJECT) then
       
   164                 LandPixels[y + dx, i]:= 0
       
   165             else
       
   166                 LandPixels[y + dx, i]:= LandBackPixel(i, y + dx);
   157 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
   167 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
   158     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
   168     for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
   159         if Land[y - dx, i] = COLOR_LAND then
   169         if (LandPixels[y - dx, i] and $FF000000) <> 0 then
   160              LandPixels[y - dx, i]:= 0;
   170             if (dx * dx + (i - x) * (i - x) < cr) or (Land[y - dx, i] = COLOR_OBJECT) then
       
   171                 LandPixels[y - dx, i]:= 0
       
   172             else
       
   173                 LandPixels[y - dx, i]:= LandBackPixel(i, y - dx);
   161 end;
   174 end;
   162 
   175 
   163 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt);
   176 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt);
   164 var i: LongInt;
   177 var i: LongInt;
   165 begin
   178 begin
   166 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   179 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   167    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
   180    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
   168        if Land[y + dy, i] = COLOR_LAND then
   181        if (Land[y + dy, i] = COLOR_LAND) or (Land[y + dy, i] = COLOR_OBJECT) then
   169           begin
   182           begin
   170           LandPixels[y + dy, i]:= cExplosionBorderColor;
   183           LandPixels[y + dy, i]:= cExplosionBorderColor;
   171 //          Despeckle(y + dy, i);
   184 //          Despeckle(y + dy, i);
   172           LandDirty[(y + dy) div 32, i div 32]:= 1;
   185           LandDirty[(y + dy) div 32, i div 32]:= 1;
   173           end;
   186           end;
   174 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   187 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   175    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
   188    for i:= max(x - dx, 0) to min(x + dx, LAND_WIDTH - 1) do
   176        if Land[y - dy, i] = COLOR_LAND then
   189        if (Land[y - dy, i] = COLOR_LAND) or (Land[y - dy, i] = COLOR_OBJECT) then
   177           begin
   190           begin
   178           LandPixels[y - dy, i]:= cExplosionBorderColor;
   191           LandPixels[y - dy, i]:= cExplosionBorderColor;
   179 //          Despeckle(y - dy, i);
   192 //          Despeckle(y - dy, i);
   180           LandDirty[(y - dy) div 32, i div 32]:= 1;
   193           LandDirty[(y - dy) div 32, i div 32]:= 1;
   181           end;
   194           end;
   182 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   195 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   183    for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
   196    for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
   184        if Land[y + dx, i] = COLOR_LAND then
   197        if (Land[y + dx, i] = COLOR_LAND) or (Land[y + dx, i] = COLOR_OBJECT) then
   185            begin
   198            begin
   186            LandPixels[y + dx, i]:= cExplosionBorderColor;
   199            LandPixels[y + dx, i]:= cExplosionBorderColor;
   187 //           Despeckle(y + dx, i);
   200 //           Despeckle(y + dx, i);
   188            LandDirty[(y + dx) div 32, i div 32]:= 1;
   201            LandDirty[(y + dx) div 32, i div 32]:= 1;
   189            end;
   202            end;
   190 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
   203 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
   191    for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
   204    for i:= max(x - dy, 0) to min(x + dy, LAND_WIDTH - 1) do
   192        if Land[y - dx, i] = COLOR_LAND then
   205        if (Land[y - dx, i] = COLOR_LAND) or (Land[y - dx, i] = COLOR_OBJECT) then
   193           begin
   206           begin
   194           LandPixels[y - dx, i]:= cExplosionBorderColor;
   207           LandPixels[y - dx, i]:= cExplosionBorderColor;
   195 //          Despeckle(y - dx, i);
   208 //          Despeckle(y - dx, i);
   196           LandDirty[(y - dx) div 32, i div 32]:= 1;
   209           LandDirty[(y - dx) div 32, i div 32]:= 1;
   197           end;
   210           end;
   198 end;
   211 end;
   199 
   212 
   200 procedure DrawExplosion(X, Y, Radius: LongInt);
   213 procedure DrawExplosion(X, Y, Radius: LongInt);
   201 var dx, dy, ty, tx, d: LongInt;
   214 var dx, dy, ty, tx, d, cr: LongInt;
   202 begin
   215 begin
   203   dx:= 0;
   216   dx:= 0;
   204   dy:= Radius;
   217   dy:= Radius;
   205   d:= 3 - 2 * Radius;
   218   d:= 3 - 2 * Radius;
       
   219   cr:= Radius * 3 div 4;
       
   220   if cr < 10 then cr:= 0;
       
   221   
   206   while (dx < dy) do
   222   while (dx < dy) do
   207      begin
   223      begin
   208      FillLandCircleLines0(x, y, dx, dy);
   224      FillLandCircleLines0(x, y, dx, dy, cr);
   209      if (d < 0)
   225      if (d < 0)
   210      then d:= d + 4 * dx + 6
   226      then d:= d + 4 * dx + 6
   211      else begin
   227      else begin
   212           d:= d + 4 * (dx - dy) + 10;
   228           d:= d + 4 * (dx - dy) + 10;
   213           dec(dy)
   229           dec(dy)
   214           end;
   230           end;
   215      inc(dx)
   231      inc(dx)
   216      end;
   232      end;
   217   if (dx = dy) then FillLandCircleLines0(x, y, dx, dy);
   233   if (dx = dy) then FillLandCircleLines0(x, y, dx, dy, cr);
   218   // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function
   234   // FillRoundInLand after erasing land pixels to allow Land 0 check for mask.png to function
   219   FillRoundInLand(X, Y, Radius, 0);
   235   FillRoundInLand(X, Y, Radius, 0);
   220   inc(Radius, 4);
   236   inc(Radius, 4);
   221   dx:= 0;
   237   dx:= 0;
   222   dy:= Radius;
   238   dy:= Radius;
   247 for i:= 0 to Pred(Count) do
   263 for i:= 0 to Pred(Count) do
   248     begin
   264     begin
   249     for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do
   265     for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do
   250         for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do
   266         for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do
   251             if Land[ty, tx] = COLOR_LAND then
   267             if Land[ty, tx] = COLOR_LAND then
   252                 LandPixels[ty, tx]:= 0;
   268                 LandPixels[ty, tx]:= LandBackPixel(tx, ty)
       
   269 			else if Land[ty, tx] = COLOR_OBJECT then
       
   270 				LandPixels[ty, tx]:= 0;
   253     inc(y, dY)
   271     inc(y, dY)
   254     end;
   272     end;
   255 
   273 
   256 inc(Radius, 4);
   274 inc(Radius, 4);
   257 dec(y, Count * dY);
   275 dec(y, Count * dY);
   258 
   276 
   259 for i:= 0 to Pred(Count) do
   277 for i:= 0 to Pred(Count) do
   260     begin
   278     begin
   261     for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do
   279     for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do
   262         for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do
   280         for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do
   263             if Land[ty, tx] = COLOR_LAND then
   281             if (Land[ty, tx] = COLOR_LAND) or (Land[ty, tx] = COLOR_OBJECT) then
   264                 begin
   282                 begin
   265                 LandPixels[ty, tx]:= cExplosionBorderColor;
   283                 LandPixels[ty, tx]:= cExplosionBorderColor;
   266                 LandDirty[trunc((y + dy)/32), trunc(i/32)]:= 1;
   284                 LandDirty[trunc((y + dy)/32), trunc(i/32)]:= 1;
   267                 end;
   285                 end;
   268     inc(y, dY)
   286     inc(y, dY)
   310         X:= X + dX;
   328         X:= X + dX;
   311         Y:= Y + dY;
   329         Y:= Y + dY;
   312         tx:= hwRound(X);
   330         tx:= hwRound(X);
   313         ty:= hwRound(Y);
   331         ty:= hwRound(Y);
   314         if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) then
   332         if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) then
   315          if Land[ty, tx] = COLOR_LAND then
   333             begin
   316            begin
   334             if Land[ty, tx] = COLOR_LAND then
   317            Land[ty, tx]:= 0;
   335                 LandPixels[ty, tx]:= LandBackPixel(tx, ty)
   318            LandPixels[ty, tx]:= 0;
   336             else if Land[ty, tx] = COLOR_OBJECT then
   319            end
   337                 LandPixels[ty, tx]:= 0;
       
   338             Land[ty, tx]:= 0;
       
   339             end
   320         end;
   340         end;
   321     for t:= 0 to 7 do
   341     for t:= 0 to 7 do
   322         {$INCLUDE "tunsetborder.inc"}
   342         {$INCLUDE "tunsetborder.inc"}
   323     nx:= nx - dY;
   343     nx:= nx - dY;
   324     ny:= ny + dX;
   344     ny:= ny + dX;
   396      4: for y:= 0 to Pred(h) do
   416      4: for y:= 0 to Pred(h) do
   397             begin
   417             begin
   398             for x:= 0 to Pred(w) do
   418             for x:= 0 to Pred(w) do
   399                 if PLongword(@(p^[x * 4]))^ <> 0 then
   419                 if PLongword(@(p^[x * 4]))^ <> 0 then
   400                    begin
   420                    begin
   401                    Land[cpY + y, cpX + x]:= COLOR_LAND;
   421                    Land[cpY + y, cpX + x]:= COLOR_OBJECT;
   402                    LandPixels[cpY + y, cpX + x]:= PLongword(@(p^[x * 4]))^
   422                    LandPixels[cpY + y, cpX + x]:= PLongword(@(p^[x * 4]))^
   403                    end;
   423                    end;
   404             p:= @(p^[Image^.pitch]);
   424             p:= @(p^[Image^.pitch]);
   405             end;
   425             end;
   406      end;
   426      end;
   432 						inc(c);
   452 						inc(c);
   433 				end;
   453 				end;
   434 
   454 
   435 	if c < 4 then // 0-3 neighbours
   455 	if c < 4 then // 0-3 neighbours
   436 		begin
   456 		begin
   437 		LandPixels[Y, X]:= 0;
   457         if Land[Y, X] = COLOR_LAND then
       
   458             LandPixels[Y, X]:= LandBackPixel(X, Y)
       
   459         else if Land[Y, X] = COLOR_OBJECT then
       
   460             LandPixels[Y, X]:= 0;
   438 		Land[Y, X]:= 0;
   461 		Land[Y, X]:= 0;
   439 		exit(true);
   462 		exit(true);
   440 		end;
   463 		end;
   441 	end;
   464 	end;
   442 Despeckle:= false
   465 Despeckle:= false