hedgewars/uLandGraphics.pas
changeset 57 e1a77ae57065
parent 54 839fd258ae6f
child 64 9df467527ae5
equal deleted inserted replaced
56:a29135563e94 57:e1a77ae57065
    45      inc(dx)
    45      inc(dx)
    46      end;
    46      end;
    47   if (dx = dy) then FillCircleLines(x, y, dx, dy, Value);
    47   if (dx = dy) then FillCircleLines(x, y, dx, dy, Value);
    48 end;
    48 end;
    49 
    49 
    50 procedure DrawExplosion(X, Y, Radius: integer);
    50 procedure ClearLandPixel(y, x: integer);
    51 var ty, tx, p: integer;
    51 var p: integer;
    52 begin
    52 begin
    53 FillRoundInLand(X, Y, Radius, 0);
       
    54 
       
    55 if SDL_MustLock(LandSurface) then
       
    56    SDLTry(SDL_LockSurface(LandSurface) >= 0, true);
       
    57 
       
    58 p:= integer(LandSurface.pixels);
    53 p:= integer(LandSurface.pixels);
    59 case LandSurface.format.BytesPerPixel of
    54 case LandSurface.format.BytesPerPixel of
    60      1: ;// not supported
    55      1: ;// not supported
    61      2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
    56      2: PWord(p + LandSurface.pitch*y + x * 2)^:= 0;
    62             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
    57      3: begin
    63                 PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= 0;
    58         PByte(p + LandSurface.pitch*y + x * 3 + 0)^:= 0;
    64      3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
    59         PByte(p + LandSurface.pitch*y + x * 3 + 1)^:= 0;
    65             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
    60         PByte(p + LandSurface.pitch*y + x * 3 + 2)^:= 0;
    66                 begin
    61         end;
    67                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= 0;
    62      4: PLongword(p + LandSurface.pitch*y + x * 4)^:= 0;
    68                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= 0;
    63      end;
    69                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^:= 0;
    64 end;
    70                 end;
    65 
    71      4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
    66 procedure SetLandPixel(y, x: integer);
    72             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
    67 var p: integer;
    73                 PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= 0;
    68 begin
    74      end;
    69 p:= integer(LandSurface.pixels);
    75 
       
    76 inc(Radius, 4);
       
    77 
       
    78 case LandSurface.format.BytesPerPixel of
    70 case LandSurface.format.BytesPerPixel of
    79      1: ;// not supported
    71      1: ;// not supported
    80      2: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
    72      2: PWord(p + LandSurface.pitch*y + x * 2)^:= cExplosionBorderColor;
    81             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
    73      3: begin
    82                if Land[y + ty, tx] = $FFFFFF then
    74      PByte(p + LandSurface.pitch*y + x * 3 + 0)^:= cExplosionBorderColor and $FF;
    83                   PWord(p + LandSurface.pitch*(y + ty) + tx * 2)^:= cExplosionBorderColor;
    75      PByte(p + LandSurface.pitch*y + x * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF;
    84      3: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
    76      PByte(p + LandSurface.pitch*y + x * 3 + 2)^:= (cExplosionBorderColor shr 16);
    85             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
    77         end;
    86                if Land[y + ty, tx] = $FFFFFF then
    78      4: PLongword(p + LandSurface.pitch*y + x * 4)^:= cExplosionBorderColor;
    87                 begin
    79      end;
    88                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 0)^:= cExplosionBorderColor and $FF;
    80 end;
    89                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 1)^:= (cExplosionBorderColor shr 8) and $FF;
    81 
    90                 PByte(p + LandSurface.pitch*(y + ty) + tx * 3 + 2)^:= (cExplosionBorderColor shr 16);
    82 procedure FillLandCircleLines0(x, y, dx, dy: integer);
    91                 end;
    83 var i: integer;
    92      4: for ty:= max(-Radius, -y) to min(Radius, 1023 - y) do
    84 begin
    93             for tx:= max(0, round(x-radius*sqrt(1-sqr(ty/radius)))) to min(2047, round(x+radius*sqrt(1-sqr(ty/radius)))) do
    85 if ((y + dy) and $FFFFFC00) = 0 then
    94                if Land[y + ty, tx] = $FFFFFF then
    86    for i:= max(x - dx, 0) to min(x + dx, 2047) do ClearLandPixel(y + dy, i);
    95                    PLongword(p + LandSurface.pitch*(y + ty) + tx * 4)^:= cExplosionBorderColor;
    87 if ((y - dy) and $FFFFFC00) = 0 then
    96      end;
    88    for i:= max(x - dx, 0) to min(x + dx, 2047) do ClearLandPixel(y - dy, i);
    97 
    89 if ((y + dx) and $FFFFFC00) = 0 then
       
    90    for i:= max(x - dy, 0) to min(x + dy, 2047) do ClearLandPixel(y + dx, i);
       
    91 if ((y - dx) and $FFFFFC00) = 0 then
       
    92    for i:= max(x - dy, 0) to min(x + dy, 2047) do ClearLandPixel(y - dx, i);
       
    93 end;
       
    94 
       
    95 procedure FillLandCircleLinesEBC(x, y, dx, dy: integer);
       
    96 var i: integer;
       
    97 begin
       
    98 if ((y + dy) and $FFFFFC00) = 0 then
       
    99    for i:= max(x - dx, 0) to min(x + dx, 2047) do
       
   100        if Land[y + dy, i] <> 0 then SetLandPixel(y + dy, i);
       
   101 if ((y - dy) and $FFFFFC00) = 0 then
       
   102    for i:= max(x - dx, 0) to min(x + dx, 2047) do
       
   103        if Land[y - dy, i] <> 0 then SetLandPixel(y - dy, i);
       
   104 if ((y + dx) and $FFFFFC00) = 0 then
       
   105    for i:= max(x - dy, 0) to min(x + dy, 2047) do
       
   106        if Land[y + dx, i] <> 0 then SetLandPixel(y + dx, i);
       
   107 if ((y - dx) and $FFFFFC00) = 0 then
       
   108    for i:= max(x - dy, 0) to min(x + dy, 2047) do
       
   109        if Land[y - dx, i] <> 0 then SetLandPixel(y - dx, i);
       
   110 end;
       
   111 
       
   112 procedure DrawExplosion(X, Y, Radius: integer);
       
   113 var dx, dy, d: integer;
       
   114 begin
       
   115 FillRoundInLand(X, Y, Radius, 0);
       
   116 
       
   117 if SDL_MustLock(LandSurface) then
       
   118    SDLTry(SDL_LockSurface(LandSurface) >= 0, true);
       
   119 
       
   120   dx:= 0;
       
   121   dy:= Radius;
       
   122   d:= 3 - 2 * Radius;
       
   123   while (dx < dy) do
       
   124      begin
       
   125      FillLandCircleLines0(x, y, dx, dy);
       
   126      if (d < 0)
       
   127      then d:= d + 4 * dx + 6
       
   128      else begin
       
   129           d:= d + 4 * (dx - dy) + 10;
       
   130           dec(dy)
       
   131           end;
       
   132      inc(dx)
       
   133      end;
       
   134   if (dx = dy) then FillLandCircleLines0(x, y, dx, dy);
       
   135   inc(Radius, 4);
       
   136   dx:= 0;
       
   137   dy:= Radius;
       
   138   d:= 3 - 2 * Radius;
       
   139   while (dx < dy) do
       
   140      begin
       
   141      FillLandCircleLinesEBC(x, y, dx, dy);
       
   142      if (d < 0)
       
   143      then d:= d + 4 * dx + 6
       
   144      else begin
       
   145           d:= d + 4 * (dx - dy) + 10;
       
   146           dec(dy)
       
   147           end;
       
   148      inc(dx)
       
   149      end;
       
   150   if (dx = dy) then FillLandCircleLinesEBC(x, y, dx, dy);  
       
   151   
    98 if SDL_MustLock(LandSurface) then
   152 if SDL_MustLock(LandSurface) then
    99    SDL_UnlockSurface(LandSurface);
   153    SDL_UnlockSurface(LandSurface);
   100 
       
   101 SDL_UpdateRect(LandSurface, X - Radius, Y - Radius, Radius * 2, Radius * 2)
       
   102 end;
   154 end;
   103 
   155 
   104 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: Longword; y, dY: integer; Count: Byte);
   156 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: Longword; y, dY: integer; Count: Byte);
   105 var tx, ty, i, p: integer;
   157 var tx, ty, i, p: integer;
   106 begin
   158 begin