summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt4
-rw-r--r--src/tile.cpp49
2 files changed, 53 insertions, 0 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index d25cd741c..74487edee 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -258,6 +258,10 @@ Advanced texture modifiers:
Crops the texture to a frame of a vertical animation.
Example: default_torch_animated.png^[verticalframe:16:8
+ [mask:<file>
+ Apply a mask to the base image.
+ The mask is applied using binary AND.
+
Sounds
-------
Only OGG Vorbis files are supported.
diff --git a/src/tile.cpp b/src/tile.cpp
index d16d135f5..06d89393c 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -537,6 +537,10 @@ static void blit_with_alpha(video::IImage *src, video::IImage *dst,
static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
v2s32 src_pos, v2s32 dst_pos, v2u32 size);
+// Apply a mask to an image
+static void apply_mask(video::IImage *mask, video::IImage *dst,
+ v2s32 mask_pos, v2s32 dst_pos, v2u32 size);
+
// Draw or overlay a crack
static void draw_crack(video::IImage *crack, video::IImage *dst,
bool use_overlay, s32 frame_count, s32 progression,
@@ -1557,6 +1561,31 @@ bool TextureSource::generateImagePart(std::string part_of_name,
baseimg->drop();
baseimg = img;
}
+ /*
+ [mask:filename
+ Applies a mask to an image
+ */
+ else if(part_of_name.substr(0,6) == "[mask:")
+ {
+ if (baseimg == NULL) {
+ errorstream << "generateImage(): baseimg == NULL "
+ << "for part_of_name=\"" << part_of_name
+ << "\", cancelling." << std::endl;
+ return false;
+ }
+ Strfnd sf(part_of_name);
+ sf.next(":");
+ std::string filename = sf.next(":");
+
+ video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
+ if (img) {
+ apply_mask(img, baseimg, v2s32(0, 0), v2s32(0, 0),
+ img->getDimension());
+ } else {
+ errorstream << "generateImage(): Failed to load \""
+ << filename << "\".";
+ }
+ }
else
{
errorstream<<"generateImagePart(): Invalid "
@@ -1615,6 +1644,26 @@ static void blit_with_alpha_overlay(video::IImage *src, video::IImage *dst,
}
}
+/*
+ Apply mask to destination
+*/
+static void apply_mask(video::IImage *mask, video::IImage *dst,
+ v2s32 mask_pos, v2s32 dst_pos, v2u32 size)
+{
+ for(u32 y0 = 0; y0 < size.Y; y0++) {
+ for(u32 x0 = 0; x0 < size.X; x0++) {
+ s32 mask_x = x0 + mask_pos.X;
+ s32 mask_y = y0 + mask_pos.Y;
+ s32 dst_x = x0 + dst_pos.X;
+ s32 dst_y = y0 + dst_pos.Y;
+ video::SColor mask_c = mask->getPixel(mask_x, mask_y);
+ video::SColor dst_c = dst->getPixel(dst_x, dst_y);
+ dst_c.color &= mask_c.color;
+ dst->setPixel(dst_x, dst_y, dst_c);
+ }
+ }
+}
+
static void draw_crack(video::IImage *crack, video::IImage *dst,
bool use_overlay, s32 frame_count, s32 progression,
video::IVideoDriver *driver)