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 |