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