hedgewars/uLandGraphics.pas
changeset 1753 2ccba26f1aa4
parent 1738 00e8dadce69a
child 1760 55a1edd97911
equal deleted inserted replaced
1752:769986d39202 1753:2ccba26f1aa4
    40 uses SDLh, uMisc, uLand;
    40 uses SDLh, uMisc, uLand;
    41 
    41 
    42 procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword);
    42 procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword);
    43 var i: LongInt;
    43 var i: LongInt;
    44 begin
    44 begin
    45 if ((y + dy) and $FFFFFC00) = 0 then
    45 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
    46    for i:= max(x - dx, 0) to min(x + dx, 2047) do Land[y + dy, i]:= Value;
    46     for i:= max(x - dx, 0) to min(x + dx, 4095) do 
    47 if ((y - dy) and $FFFFFC00) = 0 then
    47         if Land[y + dy, i] <> COLOR_INDESTRUCTIBLE then
    48    for i:= max(x - dx, 0) to min(x + dx, 2047) do Land[y - dy, i]:= Value;
    48             Land[y + dy, i]:= Value;
    49 if ((y + dx) and $FFFFFC00) = 0 then
    49 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
    50    for i:= max(x - dy, 0) to min(x + dy, 2047) do Land[y + dx, i]:= Value;
    50    for i:= max(x - dx, 0) to min(x + dx, 4095) do 
    51 if ((y - dx) and $FFFFFC00) = 0 then
    51         if Land[y - dy, i] <> COLOR_INDESTRUCTIBLE then
    52    for i:= max(x - dy, 0) to min(x + dy, 2047) do Land[y - dx, i]:= Value;
    52             Land[y - dy, i]:= Value;
       
    53 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
       
    54     for i:= max(x - dy, 0) to min(x + dy, 4095) do 
       
    55         if Land[y + dx, i] <> COLOR_INDESTRUCTIBLE then
       
    56             Land[y + dx, i]:= Value;
       
    57 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
       
    58     for i:= max(x - dy, 0) to min(x + dy, 4095) do 
       
    59         if Land[y - dx, i] <> COLOR_INDESTRUCTIBLE then
       
    60             Land[y - dx, i]:= Value;
    53 end;
    61 end;
    54 
    62 
    55 procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet: boolean);
    63 procedure ChangeCircleLines(x, y, dx, dy: LongInt; doSet: boolean);
    56 var i: LongInt;
    64 var i: LongInt;
    57 begin
    65 begin
    58 if not doSet then
    66 if not doSet then
    59    begin
    67    begin
    60    if ((y + dy) and $FFFFFC00) = 0 then
    68    if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
    61       for i:= max(x - dx, 0) to min(x + dx, 2047) do
    69       for i:= max(x - dx, 0) to min(x + dx, 4095) do
    62           if (Land[y + dy, i] > 0) then dec(Land[y + dy, i]); // check > 0 because explosion can erase collision data
    70           if (Land[y + dy, i] > 0) then dec(Land[y + dy, i]); // check > 0 because explosion can erase collision data
    63    if ((y - dy) and $FFFFFC00) = 0 then
    71    if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
    64       for i:= max(x - dx, 0) to min(x + dx, 2047) do
    72       for i:= max(x - dx, 0) to min(x + dx, 4095) do
    65           if (Land[y - dy, i] > 0) then dec(Land[y - dy, i]);
    73           if (Land[y - dy, i] > 0) then dec(Land[y - dy, i]);
    66    if ((y + dx) and $FFFFFC00) = 0 then
    74    if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
    67       for i:= max(x - dy, 0) to min(x + dy, 2047) do
    75       for i:= max(x - dy, 0) to min(x + dy, 4095) do
    68           if (Land[y + dx, i] > 0) then dec(Land[y + dx, i]);
    76           if (Land[y + dx, i] > 0) then dec(Land[y + dx, i]);
    69    if ((y - dx) and $FFFFFC00) = 0 then
    77    if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
    70       for i:= max(x - dy, 0) to min(x + dy, 2047) do
    78       for i:= max(x - dy, 0) to min(x + dy, 4095) do
    71           if (Land[y - dx, i] > 0) then dec(Land[y - dx, i]);
    79           if (Land[y - dx, i] > 0) then dec(Land[y - dx, i]);
    72    end else
    80    end else
    73    begin
    81    begin
    74    if ((y + dy) and $FFFFFC00) = 0 then
    82    if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
    75       for i:= max(x - dx, 0) to min(x + dx, 2047) do inc(Land[y + dy, i]);
    83       for i:= max(x - dx, 0) to min(x + dx, 4095) do inc(Land[y + dy, i]);
    76    if ((y - dy) and $FFFFFC00) = 0 then
    84    if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
    77       for i:= max(x - dx, 0) to min(x + dx, 2047) do inc(Land[y - dy, i]);
    85       for i:= max(x - dx, 0) to min(x + dx, 4095) do inc(Land[y - dy, i]);
    78    if ((y + dx) and $FFFFFC00) = 0 then
    86    if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
    79       for i:= max(x - dy, 0) to min(x + dy, 2047) do inc(Land[y + dx, i]);
    87       for i:= max(x - dy, 0) to min(x + dy, 4095) do inc(Land[y + dx, i]);
    80    if ((y - dx) and $FFFFFC00) = 0 then
    88    if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
    81       for i:= max(x - dy, 0) to min(x + dy, 2047) do inc(Land[y - dx, i]);
    89       for i:= max(x - dy, 0) to min(x + dy, 4095) do inc(Land[y - dx, i]);
    82    end
    90    end
    83 end;
    91 end;
    84 
    92 
    85 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
    93 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
    86 var dx, dy, d: LongInt;
    94 var dx, dy, d: LongInt;
   123 end;
   131 end;
   124 
   132 
   125 procedure FillLandCircleLines0(x, y, dx, dy: LongInt);
   133 procedure FillLandCircleLines0(x, y, dx, dy: LongInt);
   126 var i: LongInt;
   134 var i: LongInt;
   127 begin
   135 begin
   128 if ((y + dy) and $FFFFFC00) = 0 then
   136 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   129    for i:= max(x - dx, 0) to min(x + dx, 2047) do LandPixels[y + dy, i]:= 0;
   137     for i:= max(x - dx, 0) to min(x + dx, 4095) do 
   130 if ((y - dy) and $FFFFFC00) = 0 then
   138         if Land[y + dy, i] <> COLOR_INDESTRUCTIBLE then
   131    for i:= max(x - dx, 0) to min(x + dx, 2047) do LandPixels[y - dy, i]:= 0;
   139             LandPixels[y + dy, i]:= 0;
   132 if ((y + dx) and $FFFFFC00) = 0 then
   140 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   133    for i:= max(x - dy, 0) to min(x + dy, 2047) do LandPixels[y + dx, i]:= 0;
   141     for i:= max(x - dx, 0) to min(x + dx, 4095) do 
   134 if ((y - dx) and $FFFFFC00) = 0 then
   142         if Land[y - dy, i] <> COLOR_INDESTRUCTIBLE then
   135    for i:= max(x - dy, 0) to min(x + dy, 2047) do LandPixels[y - dx, i]:= 0;
   143              LandPixels[y - dy, i]:= 0;
       
   144 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
       
   145     for i:= max(x - dy, 0) to min(x + dy, 4095) do 
       
   146         if Land[y + dx, i] <> COLOR_INDESTRUCTIBLE then
       
   147             LandPixels[y + dx, i]:= 0;
       
   148 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
       
   149     for i:= max(x - dy, 0) to min(x + dy, 4095) do 
       
   150         if Land[y - dx, i] <> COLOR_INDESTRUCTIBLE then
       
   151              LandPixels[y - dx, i]:= 0;
   136 end;
   152 end;
   137 
   153 
   138 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt);
   154 procedure FillLandCircleLinesEBC(x, y, dx, dy: LongInt);
   139 var i: LongInt;
   155 var i: LongInt;
   140 begin
   156 begin
   141 if ((y + dy) and $FFFFFC00) = 0 then
   157 if ((y + dy) and LAND_HEIGHT_MASK) = 0 then
   142    for i:= max(x - dx, 0) to min(x + dx, 2047) do
   158    for i:= max(x - dx, 0) to min(x + dx, 4095) do
   143        if Land[y + dy, i] = COLOR_LAND then 
   159        if Land[y + dy, i] = COLOR_LAND then 
   144           begin
   160           begin
   145           LandPixels[y + dy, i]:= cExplosionBorderColor;
   161           LandPixels[y + dy, i]:= cExplosionBorderColor;
   146 //          Despeckle(y + dy, i);
   162 //          Despeckle(y + dy, i);
   147           LandDirty[(y + dy) div 32, i div 32]:= 1;
   163           LandDirty[(y + dy) div 32, i div 32]:= 1;
   148           end;
   164           end;
   149 if ((y - dy) and $FFFFFC00) = 0 then
   165 if ((y - dy) and LAND_HEIGHT_MASK) = 0 then
   150    for i:= max(x - dx, 0) to min(x + dx, 2047) do
   166    for i:= max(x - dx, 0) to min(x + dx, 4095) do
   151        if Land[y - dy, i] = COLOR_LAND then
   167        if Land[y - dy, i] = COLOR_LAND then
   152           begin
   168           begin
   153           LandPixels[y - dy, i]:= cExplosionBorderColor;
   169           LandPixels[y - dy, i]:= cExplosionBorderColor;
   154 //          Despeckle(y - dy, i);
   170 //          Despeckle(y - dy, i);
   155           LandDirty[(y - dy) div 32, i div 32]:= 1;
   171           LandDirty[(y - dy) div 32, i div 32]:= 1;
   156           end;
   172           end;
   157 if ((y + dx) and $FFFFFC00) = 0 then
   173 if ((y + dx) and LAND_HEIGHT_MASK) = 0 then
   158    for i:= max(x - dy, 0) to min(x + dy, 2047) do
   174    for i:= max(x - dy, 0) to min(x + dy, 4095) do
   159        if Land[y + dx, i] = COLOR_LAND then
   175        if Land[y + dx, i] = COLOR_LAND then
   160            begin
   176            begin
   161            LandPixels[y + dx, i]:= cExplosionBorderColor;
   177            LandPixels[y + dx, i]:= cExplosionBorderColor;
   162 //           Despeckle(y + dx, i);
   178 //           Despeckle(y + dx, i);
   163            LandDirty[(y + dx) div 32, i div 32]:= 1;
   179            LandDirty[(y + dx) div 32, i div 32]:= 1;
   164            end;
   180            end;
   165 if ((y - dx) and $FFFFFC00) = 0 then
   181 if ((y - dx) and LAND_HEIGHT_MASK) = 0 then
   166    for i:= max(x - dy, 0) to min(x + dy, 2047) do
   182    for i:= max(x - dy, 0) to min(x + dy, 4095) do
   167        if Land[y - dx, i] = COLOR_LAND then
   183        if Land[y - dx, i] = COLOR_LAND then
   168           begin
   184           begin
   169           LandPixels[y - dx, i]:= cExplosionBorderColor;
   185           LandPixels[y - dx, i]:= cExplosionBorderColor;
   170 //          Despeckle(y - dx, i);
   186 //          Despeckle(y - dx, i);
   171           LandDirty[(y - dx) div 32, i div 32]:= 1;
   187           LandDirty[(y - dx) div 32, i div 32]:= 1;
   208      inc(dx)
   224      inc(dx)
   209      end;
   225      end;
   210   if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy);
   226   if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy);
   211 
   227 
   212 d:= max(Y - Radius - 1, 0);
   228 d:= max(Y - Radius - 1, 0);
   213 dy:= min(Y + Radius + 1, 1023) - d;
   229 dy:= min(Y + Radius + 1, 2047) - d;
   214 UpdateLandTexture(d, dy)
   230 UpdateLandTexture(d, dy)
   215 end;
   231 end;
   216 
   232 
   217 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte);
   233 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte);
   218 var tx, ty, i: LongInt;
   234 var tx, ty, i: LongInt;
   219 begin
   235 begin
   220 for i:= 0 to Pred(Count) do
   236 for i:= 0 to Pred(Count) do
   221     begin
   237     begin
   222     for ty:= max(y - Radius, 0) to min(y + Radius, 1023) do
   238     for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do
   223         for tx:= max(0, ar^[i].Left - Radius) to min(2047, ar^[i].Right + Radius) do
   239         for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do
   224             LandPixels[ty, tx]:= 0;
   240             if Land[ty, tx] <> COLOR_INDESTRUCTIBLE then
       
   241                 LandPixels[ty, tx]:= 0;
   225     inc(y, dY)
   242     inc(y, dY)
   226     end;
   243     end;
   227 
   244 
   228 inc(Radius, 4);
   245 inc(Radius, 4);
   229 dec(y, Count * dY);
   246 dec(y, Count * dY);
   230 
   247 
   231 for i:= 0 to Pred(Count) do
   248 for i:= 0 to Pred(Count) do
   232     begin
   249     begin
   233     for ty:= max(y - Radius, 0) to min(y + Radius, 1023) do
   250     for ty:= max(y - Radius, 0) to min(y + Radius, LAND_HEIGHT) do
   234         for tx:= max(0, ar^[i].Left - Radius) to min(2047, ar^[i].Right + Radius) do
   251         for tx:= max(0, ar^[i].Left - Radius) to min(LAND_WIDTH, ar^[i].Right + Radius) do
   235             if Land[ty, tx] = $FFFFFF then
   252             if Land[ty, tx] = COLOR_LAND then
   236                 begin
   253                 begin
   237                 LandPixels[ty, tx]:= cExplosionBorderColor;
   254                 LandPixels[ty, tx]:= cExplosionBorderColor;
   238                 LandDirty[trunc((y + dy)/32), trunc(i/32)]:= 1;
   255                 LandDirty[trunc((y + dy)/32), trunc(i/32)]:= 1;
   239                 end;
   256                 end;
   240     inc(y, dY)
   257     inc(y, dY)
   241     end;
   258     end;
   242 
   259 
   243 
   260 
   244 UpdateLandTexture(0, 1023)
   261 UpdateLandTexture(0, LAND_HEIGHT)
   245 end;
   262 end;
   246 
   263 
   247 //
   264 //
   248 //  - (dX, dY) - direction, vector of length = 0.5
   265 //  - (dX, dY) - direction, vector of length = 0.5
   249 //
   266 //
   280         begin
   297         begin
   281         X:= X + dX;
   298         X:= X + dX;
   282         Y:= Y + dY;
   299         Y:= Y + dY;
   283         tx:= hwRound(X);
   300         tx:= hwRound(X);
   284         ty:= hwRound(Y);
   301         ty:= hwRound(Y);
   285         if ((ty and $FFFFFC00) = 0) and ((tx and $FFFFF800) = 0) then
   302         if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) then
   286          if Land[ty, tx] = COLOR_LAND then
   303          if Land[ty, tx] = COLOR_LAND then
   287            begin
   304            begin
   288            Land[ty, tx]:= 0;
   305            Land[ty, tx]:= 0;
   289            LandPixels[ty, tx]:= 0;
   306            LandPixels[ty, tx]:= 0;
   290            end
   307            end
   304     nx:= nx - dY;
   321     nx:= nx - dY;
   305     ny:= ny + dX;
   322     ny:= ny + dX;
   306     end;
   323     end;
   307 
   324 
   308 t:= max(stY - HalfWidth * 2 - 4 - abs(hwRound(dY * ticks)), 0);
   325 t:= max(stY - HalfWidth * 2 - 4 - abs(hwRound(dY * ticks)), 0);
   309 ty:= min(stY + HalfWidth * 2 + 4 + abs(hwRound(dY * ticks)), 1023) - t;
   326 ty:= min(stY + HalfWidth * 2 + 4 + abs(hwRound(dY * ticks)), 2047) - t;
   310 UpdateLandTexture(t, ty)
   327 UpdateLandTexture(t, ty)
   311 end;
   328 end;
   312 
   329 
   313 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean): boolean;
   330 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean): boolean;
   314 var X, Y, bpp, h, w: LongInt;
   331 var X, Y, bpp, h, w: LongInt;
   330 case bpp of
   347 case bpp of
   331      4: for y:= 0 to Pred(h) do
   348      4: for y:= 0 to Pred(h) do
   332             begin
   349             begin
   333             for x:= 0 to Pred(w) do
   350             for x:= 0 to Pred(w) do
   334                 if PLongword(@(p^[x * 4]))^ <> 0 then
   351                 if PLongword(@(p^[x * 4]))^ <> 0 then
   335                    if (((cpY + y) and $FFFFFC00) <> 0) or
   352                    if (((cpY + y) and LAND_HEIGHT_MASK) <> 0) or
   336                       (((cpX + x) and $FFFFF800) <> 0) or
   353                       (((cpX + x) and LAND_WIDTH_MASK) <> 0) or
   337                       (Land[cpY + y, cpX + x] <> 0) then
   354                       (Land[cpY + y, cpX + x] <> 0) then
   338                       begin
   355                       begin
   339                       if SDL_MustLock(Image) then
   356                       if SDL_MustLock(Image) then
   340                          SDL_UnlockSurface(Image);
   357                          SDL_UnlockSurface(Image);
   341                       exit(false)
   358                       exit(false)
   368      end;
   385      end;
   369 if SDL_MustLock(Image) then
   386 if SDL_MustLock(Image) then
   370    SDL_UnlockSurface(Image);
   387    SDL_UnlockSurface(Image);
   371 
   388 
   372 y:= max(cpY, 0);
   389 y:= max(cpY, 0);
   373 h:= min(cpY + Image^.h, 1023) - y;
   390 h:= min(cpY + Image^.h, LAND_HEIGHT) - y;
   374 UpdateLandTexture(y, h)
   391 UpdateLandTexture(y, h)
   375 end;
   392 end;
   376 
   393 
   377 // was experimenting with applying as damage occurred.
   394 // was experimenting with applying as damage occurred.
   378 function Despeckle(X, Y: LongInt): boolean;
   395 function Despeckle(X, Y: LongInt): boolean;
   379 var nx, ny, i, j, c: LongInt;
   396 var nx, ny, i, j, c: LongInt;
   380 begin
   397 begin
   381 if Land[Y, X] <> 0 then // check neighbours
   398 if (Land[Y, X] <> 0) and (Land[Y, X] <> COLOR_INDESTRUCTIBLE) then // check neighbours
   382 	begin
   399 	begin
   383 	c:= 0;
   400 	c:= 0;
   384 	for i:= -1 to 1 do
   401 	for i:= -1 to 1 do
   385 		for j:= -1 to 1 do
   402 		for j:= -1 to 1 do
   386 			if (i <> 0) or (j <> 0) then
   403 			if (i <> 0) or (j <> 0) then
   387 				begin
   404 				begin
   388 				ny:= Y + i;
   405 				ny:= Y + i;
   389 				nx:= X + j;
   406 				nx:= X + j;
   390 				if ((ny and $FFFFFC00) = 0) and ((nx and $FFFFF800) = 0) then
   407 				if ((ny and LAND_HEIGHT_MASK) = 0) and ((nx and LAND_WIDTH_MASK) = 0) then
   391 					if Land[ny, nx] <> 0 then
   408 					if Land[ny, nx] <> 0 then
   392 						inc(c);
   409 						inc(c);
   393 				end;
   410 				end;
   394 
   411 
   395 	if c < 4 then // 0-3 neighbours
   412 	if c < 4 then // 0-3 neighbours
   404 
   421 
   405 procedure SweepDirty;
   422 procedure SweepDirty;
   406 var x, y, xx, yy: LongInt;
   423 var x, y, xx, yy: LongInt;
   407     updatedRow, updatedCell: boolean;
   424     updatedRow, updatedCell: boolean;
   408 begin
   425 begin
   409 for y:= 0 to 31 do
   426 for y:= 0 to 63 do
   410 	begin
   427 	begin
   411 	updatedRow:= false;
   428 	updatedRow:= false;
   412 	
   429 	
   413 	for x:= 0 to 63 do
   430 	for x:= 0 to 127 do
   414 		begin
   431 		begin
   415 			repeat
   432 			repeat
   416 			updatedCell:= false;
   433 			updatedCell:= false;
   417 			if LandDirty[y, x] <> 0 then
   434 			if LandDirty[y, x] <> 0 then
   418 				begin
   435 				begin
   426 			until not updatedCell;
   443 			until not updatedCell;
   427 		LandDirty[y, x]:= 0;
   444 		LandDirty[y, x]:= 0;
   428 		end;
   445 		end;
   429 	
   446 	
   430 	if updatedRow then
   447 	if updatedRow then
   431 		if y = 31 then
   448 		if y = 63 then
   432 			UpdateLandTexture(992, 31)
   449 			UpdateLandTexture(LAND_HEIGHT-31, 31)
   433 		else
   450 		else
   434 			UpdateLandTexture(y*32, 32);
   451 			UpdateLandTexture(y*32, 32);
   435 	end;
   452 	end;
   436 end;
   453 end;
   437 
   454