hedgewars/uLandObjects.pas
branchwebgl
changeset 9127 e350500c4edb
parent 8833 c13ebed437cb
parent 9080 9b42757d7e71
child 9521 8054d9d775fd
equal deleted inserted replaced
8860:bde641cf53c8 9127:e350500c4edb
     1 (*
     1 (*
     2  * Hedgewars, a free turn based strategy game
     2  * Hedgewars, a free turn based strategy game
     3  * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
     3  * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; version 2 of the License
     7  * the Free Software Foundation; version 2 of the License
     8  *
     8  *
    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 
    71 
    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;
    72 
    92 
    73 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
    93 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
    74 begin
    94 begin
    75     BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0);
    95     BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0);
    76 end;
    96 end;
   112                 Land[cpY + y, cpX + x]:= lfObject;
   132                 Land[cpY + y, cpX + x]:= lfObject;
   113                 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
   114                 end;
   134                 end;
   115             end;
   135             end;
   116     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])
   117     end;
   178     end;
   118 
   179 
   119 if SDL_MustLock(Image) then
   180 if SDL_MustLock(Image) then
   120     SDL_UnlockSurface(Image);
   181     SDL_UnlockSurface(Image);
   121 WriteLnToConsole(msgOK)
   182 WriteLnToConsole(msgOK)
   326     until x >= LAND_WIDTH - Width;
   387     until x >= LAND_WIDTH - Width;
   327     bRes:= cnt <> 0;
   388     bRes:= cnt <> 0;
   328     if bRes then
   389     if bRes then
   329         begin
   390         begin
   330         i:= getrandom(cnt);
   391         i:= getrandom(cnt);
   331         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);
   332         AddRect(ar[i].x, ar[i].y, Width, Height);
   395         AddRect(ar[i].x, ar[i].y, Width, Height);
   333         dec(Maxcnt)
   396         dec(Maxcnt)
   334         end
   397         end
   335     else Maxcnt:= 0
   398     else Maxcnt:= 0
   336     end;
   399     end;
   555         begin
   618         begin
   556         inc(ThemeObjects.Count);
   619         inc(ThemeObjects.Count);
   557         with ThemeObjects.objs[Pred(ThemeObjects.Count)] do
   620         with ThemeObjects.objs[Pred(ThemeObjects.Count)] do
   558             begin
   621             begin
   559             i:= Pos(',', s);
   622             i:= Pos(',', s);
   560             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);
   561             Width:= Surf^.w;
   624             Width:= Surf^.w;
   562             Height:= Surf^.h;
   625             Height:= Surf^.h;
       
   626             Mask:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i)))+'_mask', ifTransparent or ifIgnoreCaps);
   563             Delete(s, 1, i);
   627             Delete(s, 1, i);
   564             i:= Pos(',', s);
   628             i:= Pos(',', s);
   565             Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i))));
   629             Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i))));
   566             Delete(s, 1, i);
   630             Delete(s, 1, i);
   567             if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then
   631             if (Maxcnt < 1) or (Maxcnt > MAXTHEMEOBJECTS) then