hedgewars/uLandObjects.pas
changeset 8848 e9ebd63f8a03
parent 8751 4609823efc94
child 9080 9b42757d7e71
equal deleted inserted replaced
8845:8cf1ed3bae45 8848:e9ebd63f8a03
    25 procedure AddObjects();
    25 procedure AddObjects();
    26 procedure FreeLandObjects();
    26 procedure FreeLandObjects();
    27 procedure LoadThemeConfig;
    27 procedure LoadThemeConfig;
    28 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
    28 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
    29 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word);
    29 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word);
       
    30 procedure BlitImageUsingMask(cpX, cpY: Longword;  Image, Mask: PSDL_Surface);
    30 procedure AddOnLandObjects(Surface: PSDL_Surface);
    31 procedure AddOnLandObjects(Surface: PSDL_Surface);
       
    32 procedure SetLand(var LandWord: Word; Pixel: LongWord); inline;
    31 
    33 
    32 implementation
    34 implementation
    33 uses uStore, uConsts, uConsole, uRandom, uSound, GLunit
    35 uses uStore, uConsts, uConsole, uRandom, uSound, GLunit
    34      , uTypes, uVariables, uUtils, uDebug, SysUtils
    36      , uTypes, uVariables, uUtils, uDebug, SysUtils
    35      , uPhysFSLayer;
    37      , uPhysFSLayer;
    40       cThemeCFGFilename = 'theme.cfg';
    42       cThemeCFGFilename = 'theme.cfg';
    41 
    43 
    42 type TRectsArray = array[0..MaxRects] of TSDL_Rect;
    44 type TRectsArray = array[0..MaxRects] of TSDL_Rect;
    43      PRectArray = ^TRectsArray;
    45      PRectArray = ^TRectsArray;
    44      TThemeObject = record
    46      TThemeObject = record
    45                      Surf: PSDL_Surface;
    47                      Surf, Mask: PSDL_Surface;
    46                      inland: TSDL_Rect;
    48                      inland: TSDL_Rect;
    47                      outland: array[0..Pred(MAXOBJECTRECTS)] of TSDL_Rect;
    49                      outland: array[0..Pred(MAXOBJECTRECTS)] of TSDL_Rect;
    48                      rectcnt: Longword;
    50                      rectcnt: Longword;
    49                      Width, Height: Longword;
    51                      Width, Height: Longword;
    50                      Maxcnt: Longword;
    52                      Maxcnt: Longword;
    66 var Rects: PRectArray;
    68 var Rects: PRectArray;
    67     RectCount: Longword;
    69     RectCount: Longword;
    68     ThemeObjects: TThemeObjects;
    70     ThemeObjects: TThemeObjects;
    69     SprayObjects: TSprayObjects;
    71     SprayObjects: TSprayObjects;
    70 
    72 
       
    73 procedure SetLand(var LandWord: Word; Pixel: LongWord); inline;
       
    74 begin
       
    75     // this an if instead of masking colours to avoid confusing map creators
       
    76     if ((AMask and Pixel) = 0) then
       
    77         LandWord:= 0
       
    78     else if Pixel = $FFFFFFFF then                  // white
       
    79         LandWord:= lfObject
       
    80     else if Pixel = AMask then                      // black
       
    81         begin
       
    82         LandWord:= lfBasic;
       
    83         disableLandBack:= false
       
    84         end
       
    85     else if Pixel = (AMask or RMask) then           // red
       
    86         LandWord:= lfIndestructible
       
    87     else if Pixel = (AMask or BMask) then           // blue
       
    88         LandWord:= lfObject or lfIce
       
    89     else if Pixel = (AMask or GMask) then           // green
       
    90         LandWord:= lfObject or lfBouncy
       
    91 end;
       
    92 
    71 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
    93 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
    72 begin
    94 begin
    73     BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0);
    95     BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0);
    74 end;
    96 end;
    75     
    97     
   110                 Land[cpY + y, cpX + x]:= lfObject;
   132                 Land[cpY + y, cpX + x]:= lfObject;
   111                 Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or extraFlags
   133                 Land[cpY + y, cpX + x]:= Land[cpY + y, cpX + x] or extraFlags
   112                 end;
   134                 end;
   113             end;
   135             end;
   114     p:= @(p^[Image^.pitch shr 2])
   136     p:= @(p^[Image^.pitch shr 2])
       
   137     end;
       
   138 
       
   139 if SDL_MustLock(Image) then
       
   140     SDL_UnlockSurface(Image);
       
   141 WriteLnToConsole(msgOK)
       
   142 end;
       
   143 
       
   144 procedure BlitImageUsingMask(cpX, cpY: Longword;  Image, Mask: PSDL_Surface);
       
   145 var p, mp: PLongwordArray;
       
   146     x, y: Longword;
       
   147     bpp: LongInt;
       
   148 begin
       
   149 WriteToConsole('Generating collision info... ');
       
   150 
       
   151 if SDL_MustLock(Image) then
       
   152     SDLTry(SDL_LockSurface(Image) >= 0, true);
       
   153 
       
   154 bpp:= Image^.format^.BytesPerPixel;
       
   155 TryDo(bpp = 4, 'Land object should be 32bit', true);
       
   156 
       
   157 p:= Image^.pixels;
       
   158 mp:= Mask^.pixels;
       
   159 for y:= 0 to Pred(Image^.h) do
       
   160     begin
       
   161     for x:= 0 to Pred(Image^.w) do
       
   162         begin
       
   163         if (cReducedQuality and rqBlurryLand) = 0 then
       
   164             begin
       
   165             if (LandPixels[cpY + y, cpX + x] = 0)
       
   166             or (((p^[x] and AMask) <> 0) and (((LandPixels[cpY + y, cpX + x] and AMask) shr AShift) < 255)) then
       
   167                 LandPixels[cpY + y, cpX + x]:= p^[x];
       
   168             end
       
   169         else
       
   170             if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then 
       
   171                 LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x];
       
   172 
       
   173         if (Land[cpY + y, cpX + x] <= lfAllObjMask) or (Land[cpY + y, cpX + x] and lfObject <> 0)  then
       
   174             SetLand(Land[cpY + y, cpX + x], mp^[x]);
       
   175         end;
       
   176     p:= @(p^[Image^.pitch shr 2]);
       
   177     mp:= @(mp^[Mask^.pitch shr 2])
   115     end;
   178     end;
   116 
   179 
   117 if SDL_MustLock(Image) then
   180 if SDL_MustLock(Image) then
   118     SDL_UnlockSurface(Image);
   181     SDL_UnlockSurface(Image);
   119 WriteLnToConsole(msgOK)
   182 WriteLnToConsole(msgOK)
   324     until x >= LAND_WIDTH - Width;
   387     until x >= LAND_WIDTH - Width;
   325     bRes:= cnt <> 0;
   388     bRes:= cnt <> 0;
   326     if bRes then
   389     if bRes then
   327         begin
   390         begin
   328         i:= getrandom(cnt);
   391         i:= getrandom(cnt);
   329         BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf);
   392         if Obj.Mask <> nil then
       
   393              BlitImageUsingMask(ar[i].x, ar[i].y, Obj.Surf, Obj.Mask)
       
   394         else BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf);
   330         AddRect(ar[i].x, ar[i].y, Width, Height);
   395         AddRect(ar[i].x, ar[i].y, Width, Height);
   331         dec(Maxcnt)
   396         dec(Maxcnt)
   332         end
   397         end
   333     else Maxcnt:= 0
   398     else Maxcnt:= 0
   334     end;
   399     end;
   553         begin
   618         begin
   554         inc(ThemeObjects.Count);
   619         inc(ThemeObjects.Count);
   555         with ThemeObjects.objs[Pred(ThemeObjects.Count)] do
   620         with ThemeObjects.objs[Pred(ThemeObjects.Count)] do
   556             begin
   621             begin
   557             i:= Pos(',', s);
   622             i:= Pos(',', s);
   558             Surf:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps);
   623             Surf:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps or ifCritical);
   559             Width:= Surf^.w;
   624             Width:= Surf^.w;
   560             Height:= Surf^.h;
   625             Height:= Surf^.h;
       
   626             Mask:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i)))+'_mask', ifTransparent or ifIgnoreCaps);
   561             Delete(s, 1, i);
   627             Delete(s, 1, i);
   562             i:= Pos(',', s);
   628             i:= Pos(',', s);
   563             Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i))));
   629             Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i))));
   564             Delete(s, 1, i);
   630             Delete(s, 1, i);
   565             if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then
   631             if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then