diff -r bce67defd804 -r 8ea636ce120a hedgewars/uLandGraphics.pas --- a/hedgewars/uLandGraphics.pas Sun Apr 05 16:41:39 2015 -0400 +++ b/hedgewars/uLandGraphics.pas Wed Apr 08 15:04:48 2015 -0400 @@ -20,7 +20,7 @@ unit uLandGraphics; interface -uses uFloat, uConsts, uTypes; +uses uFloat, uConsts, uTypes, Math, uRenderUtils; type fillType = (nullPixel, backgroundPixel, ebcPixel, icePixel, setNotCurrentMask, changePixelSetNotCurrent, setCurrentHog, changePixelNotSetNotCurrent); @@ -49,8 +49,8 @@ procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint); function TryPlaceOnLandSimple(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean): boolean; inline; function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline; -function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word): boolean; inline; -function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force: boolean; LandFlags: Word): boolean; +function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; Tint: LongWord; Behind, flipHoriz, flipVert: boolean): boolean; inline; +function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force, behind, flipHoriz, flipVert: boolean; LandFlags: Word; Tint: LongWord): boolean; function GetPlaceCollisionTex(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): PTexture; implementation @@ -679,37 +679,37 @@ lf:= lfIndestructible else lf:= 0; -TryPlaceOnLandSimple:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, lf); +TryPlaceOnLandSimple:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, false, false, false, lf, $FFFFFFFF); end; function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline; begin -TryPlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, LandFlags); +TryPlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, false, false, false, LandFlags, $FFFFFFFF); end; -function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word): boolean; inline; +function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; Tint: LongWord; Behind, flipHoriz, flipVert: boolean): boolean; inline; begin - ForcePlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, true, false, true, LandFlags) + ForcePlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, true, false, true, behind, flipHoriz, flipVert, LandFlags, Tint) end; -function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force: boolean; LandFlags: Word): boolean; +function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force, behind, flipHoriz, flipVert: boolean; LandFlags: Word; Tint: LongWord): boolean; var X, Y, bpp, h, w, row, col, gx, gy, numFramesFirstCol: LongInt; p: PByteArray; Image: PSDL_Surface; - indestructible: boolean; + pixel: LongWord; begin TryPlaceOnLand:= false; numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height; -// make land indestructible if lfIndestructible is passed -indestructible:= (LandFlags and lfIndestructible <> 0); - if outOfMap then doPlace:= false; // just using for a check TryDo(SpritesData[Obj].Surface <> nil, 'Assert SpritesData[Obj].Surface failed', true); + Image:= SpritesData[Obj].Surface; w:= SpritesData[Obj].Width; h:= SpritesData[Obj].Height; +if flipVert then flipSurface(Image, true); +if flipHoriz then flipSurface(Image, false); row:= Frame mod numFramesFirstCol; col:= Frame div numFramesFirstCol; @@ -765,17 +765,32 @@ gY:= cpY + y; end else - begin - gX:= (cpX + x) div 2; - gY:= (cpY + y) div 2; + begin + gX:= (cpX + x) div 2; + gY:= (cpY + y) div 2; + end; + if not behind or (Land[cpY + y, cpX + x] and lfLandMask = 0) then + begin + if (LandFlags and lfBasic <> 0) or + (((LandPixels[gY, gX] and AMask) shr AShift = 255) and // This test assumes lfBasic and lfObject differ only graphically + (LandFlags or lfObject = 0)) then + Land[cpY + y, cpX + x]:= lfBasic or LandFlags + else Land[cpY + y, cpX + x]:= lfObject or LandFlags end; - if indestructible then - Land[cpY + y, cpX + x]:= {lfIndestructible or }LandFlags - else if (LandPixels[gY, gX] and AMask) shr AShift = 255 then // This test assumes lfBasic and lfObject differ only graphically - Land[cpY + y, cpX + x]:= lfBasic or LandFlags - else - Land[cpY + y, cpX + x]:= lfObject or LandFlags; - LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^ + if not behind or (LandPixels[gY, gX] = 0) then + begin + if tint = $FFFFFFFF then + LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^ + else + begin + pixel:= PLongword(@(p^[x * 4]))^; + LandPixels[gY, gX]:= + ceil((pixel shr RShift and $FF) * ((tint shr 24) / 255)) shl RShift or + ceil((pixel shr GShift and $FF) * ((tint shr 16 and $ff) / 255)) shl GShift or + ceil((pixel shr BShift and $FF) * ((tint shr 8 and $ff) / 255)) shl BShift or + ceil((pixel shr AShift and $FF) * ((tint and $ff) / 255)) shl AShift; + end + end end; p:= PByteArray(@(p^[Image^.pitch])); end; @@ -783,6 +798,9 @@ if SDL_MustLock(Image) then SDL_UnlockSurface(Image); +if flipVert then flipSurface(Image, true); +if flipHoriz then flipSurface(Image, false); + x:= Max(cpX, leftX); w:= Min(cpX + Image^.w, LAND_WIDTH) - x; y:= Max(cpY, topY);