hedgewars/uLandGraphics.pas
changeset 10897 8ea636ce120a
parent 10878 963bc20f511c
child 10901 fbf6fbe66092
equal deleted inserted replaced
10895:bce67defd804 10897:8ea636ce120a
    18 
    18 
    19 {$INCLUDE "options.inc"}
    19 {$INCLUDE "options.inc"}
    20 
    20 
    21 unit uLandGraphics;
    21 unit uLandGraphics;
    22 interface
    22 interface
    23 uses uFloat, uConsts, uTypes;
    23 uses uFloat, uConsts, uTypes, Math, uRenderUtils;
    24 
    24 
    25 type
    25 type
    26     fillType = (nullPixel, backgroundPixel, ebcPixel, icePixel, setNotCurrentMask, changePixelSetNotCurrent, setCurrentHog, changePixelNotSetNotCurrent);
    26     fillType = (nullPixel, backgroundPixel, ebcPixel, icePixel, setNotCurrentMask, changePixelSetNotCurrent, setCurrentHog, changePixelNotSetNotCurrent);
    27 
    27 
    28 type TRangeArray = array[0..31] of record
    28 type TRangeArray = array[0..31] of record
    47 function  DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword): Longword;
    47 function  DrawThickLine(X1, Y1, X2, Y2, radius: LongInt; color: Longword): Longword;
    48 procedure DumpLandToLog(x, y, r: LongInt);
    48 procedure DumpLandToLog(x, y, r: LongInt);
    49 procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint);
    49 procedure DrawIceBreak(x, y, iceRadius, iceHeight: Longint);
    50 function TryPlaceOnLandSimple(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean): boolean; inline;
    50 function TryPlaceOnLandSimple(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, indestructible: boolean): boolean; inline;
    51 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline;
    51 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline;
    52 function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word): boolean; inline;
    52 function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; Tint: LongWord; Behind, flipHoriz, flipVert: boolean): boolean; inline;
    53 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force: boolean; LandFlags: Word): boolean;
    53 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force, behind, flipHoriz, flipVert: boolean; LandFlags: Word; Tint: LongWord): boolean;
    54 function GetPlaceCollisionTex(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): PTexture;
    54 function GetPlaceCollisionTex(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt): PTexture;
    55 
    55 
    56 implementation
    56 implementation
    57 uses SDLh, uLandTexture, uTextures, uVariables, uUtils, uDebug, uScript;
    57 uses SDLh, uLandTexture, uTextures, uVariables, uUtils, uDebug, uScript;
    58 
    58 
   677 begin
   677 begin
   678 if indestructible then
   678 if indestructible then
   679     lf:= lfIndestructible
   679     lf:= lfIndestructible
   680 else
   680 else
   681     lf:= 0;
   681     lf:= 0;
   682 TryPlaceOnLandSimple:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, lf);
   682 TryPlaceOnLandSimple:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, false, false, false, lf, $FFFFFFFF);
   683 end;
   683 end;
   684 
   684 
   685 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline;
   685 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace: boolean; LandFlags: Word): boolean; inline;
   686 begin
   686 begin
   687 TryPlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, LandFlags);
   687 TryPlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, doPlace, false, false, false, false, false, LandFlags, $FFFFFFFF);
   688 end;
   688 end;
   689 
   689 
   690 function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word): boolean; inline;
   690 function ForcePlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; LandFlags: Word; Tint: LongWord; Behind, flipHoriz, flipVert: boolean): boolean; inline;
   691 begin
   691 begin
   692     ForcePlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, true, false, true, LandFlags)
   692     ForcePlaceOnLand:= TryPlaceOnLand(cpX, cpY, Obj, Frame, true, false, true, behind, flipHoriz, flipVert, LandFlags, Tint)
   693 end;
   693 end;
   694 
   694 
   695 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force: boolean; LandFlags: Word): boolean;
   695 function TryPlaceOnLand(cpX, cpY: LongInt; Obj: TSprite; Frame: LongInt; doPlace, outOfMap, force, behind, flipHoriz, flipVert: boolean; LandFlags: Word; Tint: LongWord): boolean;
   696 var X, Y, bpp, h, w, row, col, gx, gy, numFramesFirstCol: LongInt;
   696 var X, Y, bpp, h, w, row, col, gx, gy, numFramesFirstCol: LongInt;
   697     p: PByteArray;
   697     p: PByteArray;
   698     Image: PSDL_Surface;
   698     Image: PSDL_Surface;
   699     indestructible: boolean;
   699     pixel: LongWord;
   700 begin
   700 begin
   701 TryPlaceOnLand:= false;
   701 TryPlaceOnLand:= false;
   702 numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height;
   702 numFramesFirstCol:= SpritesData[Obj].imageHeight div SpritesData[Obj].Height;
   703 
   703 
   704 // make land indestructible if lfIndestructible is passed
       
   705 indestructible:= (LandFlags and lfIndestructible <> 0);
       
   706 
       
   707 if outOfMap then doPlace:= false; // just using for a check
   704 if outOfMap then doPlace:= false; // just using for a check
   708 
   705 
   709 TryDo(SpritesData[Obj].Surface <> nil, 'Assert SpritesData[Obj].Surface failed', true);
   706 TryDo(SpritesData[Obj].Surface <> nil, 'Assert SpritesData[Obj].Surface failed', true);
       
   707 
   710 Image:= SpritesData[Obj].Surface;
   708 Image:= SpritesData[Obj].Surface;
   711 w:= SpritesData[Obj].Width;
   709 w:= SpritesData[Obj].Width;
   712 h:= SpritesData[Obj].Height;
   710 h:= SpritesData[Obj].Height;
       
   711 if flipVert then flipSurface(Image, true);
       
   712 if flipHoriz then flipSurface(Image, false);
   713 row:= Frame mod numFramesFirstCol;
   713 row:= Frame mod numFramesFirstCol;
   714 col:= Frame div numFramesFirstCol;
   714 col:= Frame div numFramesFirstCol;
   715 
   715 
   716 if SDL_MustLock(Image) then
   716 if SDL_MustLock(Image) then
   717     SDLTry(SDL_LockSurface(Image) >= 0, true);
   717     SDLTry(SDL_LockSurface(Image) >= 0, true);
   763                     begin
   763                     begin
   764                     gX:= cpX + x;
   764                     gX:= cpX + x;
   765                     gY:= cpY + y;
   765                     gY:= cpY + y;
   766                     end
   766                     end
   767                 else
   767                 else
   768                      begin
   768                     begin
   769                      gX:= (cpX + x) div 2;
   769                     gX:= (cpX + x) div 2;
   770                      gY:= (cpY + y) div 2;
   770                     gY:= (cpY + y) div 2;
   771                     end;
   771                     end;
   772                 if indestructible then
   772 		if not behind or (Land[cpY + y, cpX + x] and lfLandMask = 0) then
   773                     Land[cpY + y, cpX + x]:= {lfIndestructible or }LandFlags
   773                     begin
   774                 else if (LandPixels[gY, gX] and AMask) shr AShift = 255 then  // This test assumes lfBasic and lfObject differ only graphically
   774                     if (LandFlags and lfBasic <> 0) or 
   775                     Land[cpY + y, cpX + x]:= lfBasic or LandFlags
   775                        (((LandPixels[gY, gX] and AMask) shr AShift = 255) and  // This test assumes lfBasic and lfObject differ only graphically
   776                 else
   776                          (LandFlags or lfObject = 0)) then
   777                     Land[cpY + y, cpX + x]:= lfObject or LandFlags;
   777                          Land[cpY + y, cpX + x]:= lfBasic or LandFlags
   778                 LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^
   778                     else Land[cpY + y, cpX + x]:= lfObject or LandFlags
       
   779                     end;
       
   780 		if not behind or (LandPixels[gY, gX] = 0) then
       
   781                     begin
       
   782                     if tint = $FFFFFFFF then
       
   783                         LandPixels[gY, gX]:= PLongword(@(p^[x * 4]))^
       
   784                     else 
       
   785                         begin
       
   786                         pixel:= PLongword(@(p^[x * 4]))^;
       
   787                         LandPixels[gY, gX]:= 
       
   788                            ceil((pixel shr RShift and $FF) * ((tint shr 24) / 255)) shl RShift or
       
   789                            ceil((pixel shr GShift and $FF) * ((tint shr 16 and $ff) / 255)) shl GShift or
       
   790                            ceil((pixel shr BShift and $FF) * ((tint shr  8 and $ff) / 255)) shl BShift or
       
   791                            ceil((pixel shr AShift and $FF) * ((tint and $ff) / 255)) shl AShift;
       
   792                         end
       
   793                     end
   779                 end;
   794                 end;
   780         p:= PByteArray(@(p^[Image^.pitch]));
   795         p:= PByteArray(@(p^[Image^.pitch]));
   781         end;
   796         end;
   782     end;
   797     end;
   783 if SDL_MustLock(Image) then
   798 if SDL_MustLock(Image) then
   784     SDL_UnlockSurface(Image);
   799     SDL_UnlockSurface(Image);
       
   800 
       
   801 if flipVert then flipSurface(Image, true);
       
   802 if flipHoriz then flipSurface(Image, false);
   785 
   803 
   786 x:= Max(cpX, leftX);
   804 x:= Max(cpX, leftX);
   787 w:= Min(cpX + Image^.w, LAND_WIDTH) - x;
   805 w:= Min(cpX + Image^.w, LAND_WIDTH) - x;
   788 y:= Max(cpY, topY);
   806 y:= Max(cpY, topY);
   789 h:= Min(cpY + Image^.h, LAND_HEIGHT) - y;
   807 h:= Min(cpY + Image^.h, LAND_HEIGHT) - y;