diff -r 6c3da4907d00 -r 4f1841929ccc hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Wed Feb 07 17:27:32 2007 +0000 +++ b/hedgewars/uLandGraphics.pas Wed Feb 07 21:36:55 2007 +0000 @@ -18,7 +18,7 @@ unit uLandGraphics; interface -uses uFloat; +uses uFloat, uConsts; {$INCLUDE options.inc} type PRangeArray = ^TRangeArray; @@ -31,8 +31,10 @@ procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt); procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword); +function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): boolean; + implementation -uses SDLh, uMisc, uLand, uConsts; +uses SDLh, uMisc, uLand; procedure FillCircleLines(x, y, dx, dy: LongInt; Value: Longword); var i: LongInt; @@ -72,7 +74,6 @@ begin p:= @PByteArray(LandSurface^.pixels)^[LandSurface^.pitch * y]; case LandSurface^.format^.BytesPerPixel of - 1: ;// not supported 2: PWord(@(p^[x * 2]))^:= 0; 3: begin p^[x * 3 + 0]:= 0; @@ -88,7 +89,6 @@ begin p:= @PByteArray(LandSurface^.pixels)^[LandSurface^.pitch * y]; case LandSurface^.format^.BytesPerPixel of - 1: ;// not supported 2: PWord(@(p^[x * 2]))^:= cExplosionBorderColor; 3: begin p^[x * 3 + 0]:= cExplosionBorderColor and $FF; @@ -268,5 +268,110 @@ SDL_UnlockSurface(LandSurface) end; +function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): boolean; +var Result: boolean; + X, Y, sY, bpp, h, w: LongInt; + p: PByteArray; + r, rr: TSDL_Rect; + Image: PSDL_Surface; +begin +Result:= true; +Image:= SpritesData[Obj].Surface; +w:= SpritesData[Obj].Width; +h:= SpritesData[Obj].Height; + +if SDL_MustLock(Image) then + SDLTry(SDL_LockSurface(Image) >= 0, true); + +bpp:= Image^.format^.BytesPerPixel; +TryDo(bpp <> 1, 'We don''t work with 8 bit surfaces', true); +// Check that sprites fits free space +p:= @(PByteArray(Image^.pixels)^[Image^.pitch * Frame * h]); +case bpp of + 2: for y:= 0 to Pred(h) do + begin + for x:= 0 to Pred(w) do + if PWord(@(p^[x * 2]))^ <> 0 then + if (((cpY + y) and $FFFFFC00) <> 0) or + (((cpX + x) and $FFFFF800) <> 0) or + (Land[cpY + y, cpX + x] <> 0) then + begin + if SDL_MustLock(Image) then + SDL_UnlockSurface(Image); + exit(false) + end; + p:= @(p^[Image^.pitch]); + end; + 3: for y:= 0 to Pred(h) do + begin + for x:= 0 to Pred(w) do + if (p^[x * 3 + 0] <> 0) + or (p^[x * 3 + 1] <> 0) + or (p^[x * 3 + 2] <> 0) then + if (((cpY + y) and $FFFFFC00) <> 0) or + (((cpX + x) and $FFFFF800) <> 0) or + (Land[cpY + y, cpX + x] <> 0) then + begin + if SDL_MustLock(Image) then + SDL_UnlockSurface(Image); + exit(false) + end; + p:= @(p^[Image^.pitch]); + end; + 4: for y:= 0 to Pred(h) do + begin + for x:= 0 to Pred(w) do + if PLongword(@(p^[x * 4]))^ <> 0 then + if (((cpY + y) and $FFFFFC00) <> 0) or + (((cpX + x) and $FFFFF800) <> 0) or + (Land[cpY + y, cpX + x] <> 0) then + begin + if SDL_MustLock(Image) then + SDL_UnlockSurface(Image); + exit(false) + end; + p:= @(p^[Image^.pitch]); + end; + end; + +// Checked, now place +p:= @(PByteArray(Image^.pixels)^[Image^.pitch * Frame * h]); +case bpp of + 2: for y:= 0 to Pred(h) do + begin + for x:= 0 to Pred(w) do + if PWord(@(p^[x * 2]))^ <> 0 then Land[cpY + y, cpX + x]:= COLOR_LAND; + p:= @(p^[Image^.pitch]); + end; + 3: for y:= 0 to Pred(h) do + begin + for x:= 0 to Pred(w) do + if (p^[x * 3 + 0] <> 0) + or (p^[x * 3 + 1] <> 0) + or (p^[x * 3 + 2] <> 0) then Land[cpY + y, cpX + x]:= COLOR_LAND; + p:= @(p^[Image^.pitch]); + end; + 4: for y:= 0 to Pred(h) do + begin + for x:= 0 to Pred(w) do + if PLongword(@(p^[x * 4]))^ <> 0 then Land[cpY + y, cpX + x]:= COLOR_LAND; + p:= @(p^[Image^.pitch]); + end; + end; +if SDL_MustLock(Image) then + SDL_UnlockSurface(Image); + +// Draw sprite on Land surface +r.x:= 0; +r.y:= SpritesData[Obj].Height * Frame; +r.w:= SpritesData[Obj].Width; +r.h:= SpritesData[Obj].Height; +rr.x:= cpX; +rr.y:= cpY; +SDL_UpperBlit(Image, @r, LandSurface, @rr); + +TryPlaceOnLand:= true +end; + end.