So. Some themes have objects that seem to be large natural extensions of the landscape. Masks allow maintaining that. Lemme know if it doesn't look good. If it doesn't, can still use for ice/bounce/indestructible. Indestructible bunker object for example.
authornemo
Thu, 04 Apr 2013 08:10:59 -0400
changeset 8848 e9ebd63f8a03
parent 8845 8cf1ed3bae45
child 8851 e9a97845e4f2
So. Some themes have objects that seem to be large natural extensions of the landscape. Masks allow maintaining that. Lemme know if it doesn't look good. If it doesn't, can still use for ice/bounce/indestructible. Indestructible bunker object for example.
hedgewars/uLand.pas
hedgewars/uLandObjects.pas
hedgewars/uStore.pas
share/hedgewars/Data/Themes/Cave/Stalactite.png
share/hedgewars/Data/Themes/Cave/Stalactite_mask.png
share/hedgewars/Data/Themes/Cave/Stalagmite01.png
share/hedgewars/Data/Themes/Cave/Stalagmite01_mask.png
share/hedgewars/Data/Themes/Cave/Stalagmite02.png
share/hedgewars/Data/Themes/Cave/Stalagmite02_mask.png
share/hedgewars/Data/Themes/Cheese/cheese.png
share/hedgewars/Data/Themes/Cheese/cheese_mask.png
share/hedgewars/Data/Themes/EarthRise/Chunk.png
share/hedgewars/Data/Themes/EarthRise/Rock.png
share/hedgewars/Data/Themes/EarthRise/RockShort.png
share/hedgewars/Data/Themes/EarthRise/RockShort_mask.png
share/hedgewars/Data/Themes/EarthRise/Rock_mask.png
share/hedgewars/Data/Themes/EarthRise/horizontL.png
share/hedgewars/Data/Themes/EarthRise/horizontR.png
share/hedgewars/Data/Themes/EarthRise/icon.png
share/hedgewars/Data/Themes/EarthRise/icon@2x.png
share/hedgewars/Data/Themes/Fruit/Watermelon_mask.png
--- a/hedgewars/uLand.pas	Thu Apr 04 10:44:03 2013 +0300
+++ b/hedgewars/uLand.pas	Thu Apr 04 08:10:59 2013 -0400
@@ -483,28 +483,11 @@
 
         p:= tmpsurf^.pixels;
         for y:= 0 to Pred(tmpsurf^.h) do
-        begin
+            begin
             for x:= 0 to Pred(tmpsurf^.w) do
-            begin
-                // this an if instead of masking colours to avoid confusing map creators
-                if ((AMask and p^[x]) = 0) then 
-                    Land[cpY + y, cpX + x]:= 0
-                else if p^[x] = $FFFFFFFF then                  // white
-                    Land[cpY + y, cpX + x]:= lfObject
-                else if p^[x] = AMask then                      // black
-                    begin
-                    Land[cpY + y, cpX + x]:= lfBasic;
-                    disableLandBack:= false
-                    end
-                else if p^[x] = (AMask or RMask) then           // red
-                    Land[cpY + y, cpX + x]:= lfIndestructible
-                else if p^[x] = (AMask or BMask) then           // blue
-                    Land[cpY + y, cpX + x]:= lfObject or lfIce
-                else if p^[x] = (AMask or GMask) then           // green
-                    Land[cpY + y, cpX + x]:= lfObject or lfBouncy
+                SetLand(Land[cpY + y, cpX + x], p^[x]);
+            p:= @(p^[tmpsurf^.pitch div 4]);
             end;
-            p:= @(p^[tmpsurf^.pitch div 4]);
-        end;
 
     if SDL_MustLock(tmpsurf) then
         SDL_UnlockSurface(tmpsurf);
--- a/hedgewars/uLandObjects.pas	Thu Apr 04 10:44:03 2013 +0300
+++ b/hedgewars/uLandObjects.pas	Thu Apr 04 08:10:59 2013 -0400
@@ -27,7 +27,9 @@
 procedure LoadThemeConfig;
 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface; extraFlags: Word);
+procedure BlitImageUsingMask(cpX, cpY: Longword;  Image, Mask: PSDL_Surface);
 procedure AddOnLandObjects(Surface: PSDL_Surface);
+procedure SetLand(var LandWord: Word; Pixel: LongWord); inline;
 
 implementation
 uses uStore, uConsts, uConsole, uRandom, uSound, GLunit
@@ -42,7 +44,7 @@
 type TRectsArray = array[0..MaxRects] of TSDL_Rect;
      PRectArray = ^TRectsArray;
      TThemeObject = record
-                     Surf: PSDL_Surface;
+                     Surf, Mask: PSDL_Surface;
                      inland: TSDL_Rect;
                      outland: array[0..Pred(MAXOBJECTRECTS)] of TSDL_Rect;
                      rectcnt: Longword;
@@ -68,6 +70,26 @@
     ThemeObjects: TThemeObjects;
     SprayObjects: TSprayObjects;
 
+procedure SetLand(var LandWord: Word; Pixel: LongWord); inline;
+begin
+    // this an if instead of masking colours to avoid confusing map creators
+    if ((AMask and Pixel) = 0) then
+        LandWord:= 0
+    else if Pixel = $FFFFFFFF then                  // white
+        LandWord:= lfObject
+    else if Pixel = AMask then                      // black
+        begin
+        LandWord:= lfBasic;
+        disableLandBack:= false
+        end
+    else if Pixel = (AMask or RMask) then           // red
+        LandWord:= lfIndestructible
+    else if Pixel = (AMask or BMask) then           // blue
+        LandWord:= lfObject or lfIce
+    else if Pixel = (AMask or GMask) then           // green
+        LandWord:= lfObject or lfBouncy
+end;
+
 procedure BlitImageAndGenerateCollisionInfo(cpX, cpY, Width: Longword; Image: PSDL_Surface); inline;
 begin
     BlitImageAndGenerateCollisionInfo(cpX, cpY, Width, Image, 0);
@@ -119,6 +141,47 @@
 WriteLnToConsole(msgOK)
 end;
 
+procedure BlitImageUsingMask(cpX, cpY: Longword;  Image, Mask: PSDL_Surface);
+var p, mp: PLongwordArray;
+    x, y: Longword;
+    bpp: LongInt;
+begin
+WriteToConsole('Generating collision info... ');
+
+if SDL_MustLock(Image) then
+    SDLTry(SDL_LockSurface(Image) >= 0, true);
+
+bpp:= Image^.format^.BytesPerPixel;
+TryDo(bpp = 4, 'Land object should be 32bit', true);
+
+p:= Image^.pixels;
+mp:= Mask^.pixels;
+for y:= 0 to Pred(Image^.h) do
+    begin
+    for x:= 0 to Pred(Image^.w) do
+        begin
+        if (cReducedQuality and rqBlurryLand) = 0 then
+            begin
+            if (LandPixels[cpY + y, cpX + x] = 0)
+            or (((p^[x] and AMask) <> 0) and (((LandPixels[cpY + y, cpX + x] and AMask) shr AShift) < 255)) then
+                LandPixels[cpY + y, cpX + x]:= p^[x];
+            end
+        else
+            if LandPixels[(cpY + y) div 2, (cpX + x) div 2] = 0 then 
+                LandPixels[(cpY + y) div 2, (cpX + x) div 2]:= p^[x];
+
+        if (Land[cpY + y, cpX + x] <= lfAllObjMask) or (Land[cpY + y, cpX + x] and lfObject <> 0)  then
+            SetLand(Land[cpY + y, cpX + x], mp^[x]);
+        end;
+    p:= @(p^[Image^.pitch shr 2]);
+    mp:= @(mp^[Mask^.pitch shr 2])
+    end;
+
+if SDL_MustLock(Image) then
+    SDL_UnlockSurface(Image);
+WriteLnToConsole(msgOK)
+end;
+
 procedure AddRect(x1, y1, w1, h1: LongInt);
 begin
 with Rects^[RectCount] do
@@ -326,7 +389,9 @@
     if bRes then
         begin
         i:= getrandom(cnt);
-        BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf);
+        if Obj.Mask <> nil then
+             BlitImageUsingMask(ar[i].x, ar[i].y, Obj.Surf, Obj.Mask)
+        else BlitImageAndGenerateCollisionInfo(ar[i].x, ar[i].y, 0, Obj.Surf);
         AddRect(ar[i].x, ar[i].y, Width, Height);
         dec(Maxcnt)
         end
@@ -555,9 +620,10 @@
         with ThemeObjects.objs[Pred(ThemeObjects.Count)] do
             begin
             i:= Pos(',', s);
-            Surf:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps);
+            Surf:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i))), ifTransparent or ifIgnoreCaps or ifCritical);
             Width:= Surf^.w;
             Height:= Surf^.h;
+            Mask:= LoadDataImage(ptCurrTheme, Trim(Copy(s, 1, Pred(i)))+'_mask', ifTransparent or ifIgnoreCaps);
             Delete(s, 1, i);
             i:= Pos(',', s);
             Maxcnt:= StrToInt(Trim(Copy(s, 1, Pred(i))));
--- a/hedgewars/uStore.pas	Thu Apr 04 10:44:03 2013 +0300
+++ b/hedgewars/uStore.pas	Thu Apr 04 08:10:59 2013 -0400
@@ -575,19 +575,19 @@
     tmpsurf:= IMG_Load_RW(rwopsOpenRead(s), true);
 
     if tmpsurf = nil then
-    begin
+        begin
         OutError(msgFailed, (imageFlags and ifCritical) <> 0);
         exit;
-    end;
+        end;
 
     if ((imageFlags and ifIgnoreCaps) = 0) and ((tmpsurf^.w > MaxTextureSize) or (tmpsurf^.h > MaxTextureSize)) then
-    begin
+        begin
         SDL_FreeSurface(tmpsurf);
         OutError(msgFailedSize, ((not cOnlyStats) and ((imageFlags and ifCritical) <> 0)));
         // dummy surface to replace non-critical textures that failed to load due to their size
         LoadImage:= SDL_CreateRGBSurface(SDL_SWSURFACE, 2, 2, 32, RMask, GMask, BMask, AMask);
         exit;
-    end;
+        end;
 
     tmpsurf:= doSurfaceConversion(tmpsurf);
 
Binary file share/hedgewars/Data/Themes/Cave/Stalactite.png has changed
Binary file share/hedgewars/Data/Themes/Cave/Stalactite_mask.png has changed
Binary file share/hedgewars/Data/Themes/Cave/Stalagmite01.png has changed
Binary file share/hedgewars/Data/Themes/Cave/Stalagmite01_mask.png has changed
Binary file share/hedgewars/Data/Themes/Cave/Stalagmite02.png has changed
Binary file share/hedgewars/Data/Themes/Cave/Stalagmite02_mask.png has changed
Binary file share/hedgewars/Data/Themes/Cheese/cheese.png has changed
Binary file share/hedgewars/Data/Themes/Cheese/cheese_mask.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/Chunk.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/Rock.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/RockShort.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/RockShort_mask.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/Rock_mask.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/horizontL.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/horizontR.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/icon.png has changed
Binary file share/hedgewars/Data/Themes/EarthRise/icon@2x.png has changed
Binary file share/hedgewars/Data/Themes/Fruit/Watermelon_mask.png has changed