hedgewars/uLandGraphics.pas
branchqmlfrontend
changeset 10748 dc587913987c
parent 10677 328f526c95b6
child 10864 9cf20f487ee9
equal deleted inserted replaced
10616:20a2d5e6930a 10748:dc587913987c
   525             LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
   525             LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor
   526         end
   526         end
   527     end;
   527     end;
   528 end;
   528 end;
   529 
   529 
       
   530 type TWrapNeeded = (wnNone, wnLeft, wnRight);
   530 
   531 
   531 //
   532 //
   532 //  - (dX, dY) - direction, vector of length = 0.5
   533 //  - (dX, dY) - direction, vector of length = 0.5
   533 //
   534 //
   534 procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt);
   535 function DrawTunnel_real(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt): TWrapNeeded;
   535 var nx, ny, dX8, dY8: hwFloat;
   536 var nx, ny, dX8, dY8: hwFloat;
   536     i, t, tx, ty, by, bx, stX, stY, ddy, ddx: Longint;
   537     i, t, tx, ty, by, bx, stX, stY, ddy, ddx: Longint;
   537     despeckle : Boolean;
   538     despeckle : Boolean;
   538 begin  // (-dY, dX) is (dX, dY) rotated by PI/2
   539 begin  // (-dY, dX) is (dX, dY) rotated by PI/2
       
   540 DrawTunnel_real:= wnNone;
       
   541 
   539 stY:= hwRound(Y);
   542 stY:= hwRound(Y);
   540 stX:= hwRound(X);
   543 stX:= hwRound(X);
   541 
   544 
   542 despeckle:= HalfWidth > 1;
   545 despeckle:= HalfWidth > 1;
   543 
   546 
   635     end;
   638     end;
   636     nx:= nx - dY;
   639     nx:= nx - dY;
   637     ny:= ny + dX;
   640     ny:= ny + dX;
   638     end;
   641     end;
   639 
   642 
   640 tx:= Max(stX - HalfWidth * 2 - 4 - abs(hwRound(dX * ticks)), 0);
   643 tx:= stX - HalfWidth * 2 - 4 - abs(hwRound(dX * ticks));
       
   644 ddx:= stX + HalfWidth * 2 + 4 + abs(hwRound(dX * ticks));
       
   645 
       
   646 if WorldEdge = weWrap then
       
   647     begin
       
   648     if (tx < leftX) or (ddx < leftX) then
       
   649         DrawTunnel_real:= wnLeft
       
   650     else if (tx > rightX) or (ddx > rightX) then
       
   651         DrawTunnel_real:= wnRight;
       
   652     end;
       
   653 
       
   654 tx:= Max(tx, 0);
   641 ty:= Max(stY - HalfWidth * 2 - 4 - abs(hwRound(dY * ticks)), 0);
   655 ty:= Max(stY - HalfWidth * 2 - 4 - abs(hwRound(dY * ticks)), 0);
   642 ddx:= Min(stX + HalfWidth * 2 + 4 + abs(hwRound(dX * ticks)), LAND_WIDTH) - tx;
   656 ddx:= Min(ddx, LAND_WIDTH) - tx;
   643 ddy:= Min(stY + HalfWidth * 2 + 4 + abs(hwRound(dY * ticks)), LAND_HEIGHT) - ty;
   657 ddy:= Min(stY + HalfWidth * 2 + 4 + abs(hwRound(dY * ticks)), LAND_HEIGHT) - ty;
   644 
   658 
   645 UpdateLandTexture(tx, ddx, ty, ddy, false)
   659 UpdateLandTexture(tx, ddx, ty, ddy, false)
       
   660 end;
       
   661 
       
   662 procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt);
       
   663 var wn: TWrapNeeded;
       
   664 begin
       
   665 wn:= DrawTunnel_real(X, Y, dX, dY, ticks, HalfWidth);
       
   666 if wn <> wnNone then
       
   667     begin
       
   668     if wn = wnLeft then
       
   669         DrawTunnel_real(X + int2hwFloat(playWidth), Y, dX, dY, ticks, HalfWidth)
       
   670     else
       
   671         DrawTunnel_real(X - int2hwFloat(playWidth), Y, dX, dY, ticks, HalfWidth);
       
   672     end;
   646 end;
   673 end;
   647 
   674 
   648 function TryPlaceOnLandSimple(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean): boolean; inline;
   675 function TryPlaceOnLandSimple(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean): boolean; inline;
   649 var lf: Word;
   676 var lf: Word;
   650 begin
   677 begin
   770 
   797 
   771 end;
   798 end;
   772 
   799 
   773 function GetPlaceCollisionTex(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): PTexture;
   800 function GetPlaceCollisionTex(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): PTexture;
   774 var X, Y, bpp, h, w, row, col, numFramesFirstCol: LongInt;
   801 var X, Y, bpp, h, w, row, col, numFramesFirstCol: LongInt;
   775     p, pt: PByteArray;
   802     p, pt: PLongWordArray;
   776     Image, finalSurface: PSDL_Surface;
   803     Image, finalSurface: PSDL_Surface;
   777 begin
   804 begin
   778 GetPlaceCollisionTex:= nil;
   805 GetPlaceCollisionTex:= nil;
   779 numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height;
   806 numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height;
   780 
   807 
   798 TryDo(finalSurface <> nil, 'GetPlaceCollisionTex: fail to create surface', true);
   825 TryDo(finalSurface <> nil, 'GetPlaceCollisionTex: fail to create surface', true);
   799 
   826 
   800 if SDL_MustLock(finalSurface) then
   827 if SDL_MustLock(finalSurface) then
   801     SDLTry(SDL_LockSurface(finalSurface) >= 0, true);
   828     SDLTry(SDL_LockSurface(finalSurface) >= 0, true);
   802 
   829 
   803 // draw on surface based on collisions
   830 p:= PLongWordArray(@(PLongWordArray(Image^.pixels)^[ (Image^.pitch div 4) * row * h + col * w ]));
   804 p:= PByteArray(@(PByteArray(Image^.pixels)^[ Image^.pitch * row * h + col * w * 4 ]));
   831 pt:= PLongWordArray(finalSurface^.pixels);
   805 pt:= PByteArray(@(PByteArray(finalSurface^.pixels)^));
   832 
   806 
   833 for y:= 0 to Pred(h) do
   807 case bpp of
   834     begin
   808     4: for y:= 0 to Pred(h) do
   835     for x:= 0 to Pred(w) do
   809         begin
   836         if ((p^[x] and AMask) <> 0)
   810         for x:= 0 to Pred(w) do
   837             and (((cpY + y) < Longint(topY)) or ((cpY + y) >= LAND_HEIGHT) or
   811             if (((PLongword(@(p^[x * 4]))^) and AMask) <> 0)
   838             ((cpX + x) < Longint(leftX)) or ((cpX + x) > Longint(rightX)) or (Land[cpY + y, cpX + x] <> 0)) then
   812                 and (((cpY + y) <= Longint(topY)) or ((cpY + y) >= LAND_HEIGHT) or
   839                 pt^[x]:= cWhiteColor
   813                    ((cpX + x) <= Longint(leftX)) or ((cpX + x) >= Longint(rightX)) or (Land[cpY + y, cpX + x] <> 0)) then
   840         else
   814                     (PLongword(@(pt^[x * 4]))^):= cWhiteColor
   841             (pt^[x]):= cWhiteColor and (not AMask);
   815             else
   842     p:= PLongWordArray(@(p^[Image^.pitch div 4]));
   816                 (PLongword(@(pt^[x * 4]))^):= 0;
   843     pt:= PLongWordArray(@(pt^[finalSurface^.pitch div 4]));
   817         p:= PByteArray(@(p^[Image^.pitch]));
       
   818         pt:= PByteArray(@(pt^[finalSurface^.pitch]));
       
   819         end;
       
   820     end;
   844     end;
   821 
   845 
   822 if SDL_MustLock(Image) then
   846 if SDL_MustLock(Image) then
   823     SDL_UnlockSurface(Image);
   847     SDL_UnlockSurface(Image);
   824 
   848