diff --git a/src/bitmap.cpp b/src/bitmap.cpp index d7154b988c8..0bd1ccac84a 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -130,6 +130,8 @@ Bitmap::Bitmap(Filesystem_Stream::InputStream stream, bool transparent, uint32_t ConvertImage(w, h, pixels, transparent); CheckPixels(flags); + + filename = ToString(stream.GetName()); } Bitmap::Bitmap(const uint8_t* data, unsigned bytes, bool transparent, uint32_t flags) { diff --git a/src/bitmap.h b/src/bitmap.h index f13404b0341..681a520f645 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -215,6 +215,14 @@ class Bitmap { */ Color GetShadowColor() const; + /** + * Gets the filename this bitmap was loaded from. + * This will be empty when the origin was not a file. + * + * @return filename + */ + StringView GetFilename() const; + void CheckPixels(uint32_t flags); /** @@ -578,6 +586,8 @@ class Bitmap { TileOpacity tile_opacity; Color bg_color, sh_color; + std::string filename; + /** Bitmap data. */ PixmanImagePtr bitmap; pixman_format_code_t pixman_format; @@ -647,4 +657,8 @@ inline bool Bitmap::GetTransparent() const { return format.alpha_type != PF::NoAlpha; } +inline StringView Bitmap::GetFilename() const { + return filename; +} + #endif diff --git a/src/sprite.cpp b/src/sprite.cpp index 16203e9fc15..377c03819cc 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -114,11 +114,43 @@ BitmapRef Sprite::Refresh(Rect& rect) { } void Sprite::SetBitmap(BitmapRef const& nbitmap) { + if (nbitmap == bitmap) { + return; + } + bitmap = nbitmap; if (!bitmap) { src_rect = Rect(); } else { src_rect = bitmap->GetRect(); + + // EasyRPG Extension: Set the Blend Mode based on the filename, e.g. ".add.png" for "Additive" + SetBlendType(0); + StringView filename = bitmap->GetFilename(); + if (filename.size() >= 8 && filename[filename.size() - 4] == '.' && filename[filename.size() - 8] == '.') { + filename = filename.substr(filename.size() - 7, 3); + constexpr std::array, 13> exts = {{ + {"add", Bitmap::BlendMode::Additive}, + {"clb", Bitmap::BlendMode::ColorBurn}, + {"cld", Bitmap::BlendMode::ColorDodge}, + {"dif", Bitmap::BlendMode::Difference}, + {"drk", Bitmap::BlendMode::Darken}, + {"exc", Bitmap::BlendMode::Exclusion}, + {"hlg", Bitmap::BlendMode::HardLight}, + {"lgh", Bitmap::BlendMode::Lighten}, + {"mul", Bitmap::BlendMode::Multiply}, + {"ove", Bitmap::BlendMode::Overlay}, + {"sat", Bitmap::BlendMode::Saturate}, + {"slg", Bitmap::BlendMode::SoftLight}, + {"xor", Bitmap::BlendMode::XOR} + }}; + auto it = std::lower_bound(exts.begin(), exts.end(), filename, [](const auto& e, const auto& fname) { + return e.first < fname; + }); + if (it != exts.end() && it->first == filename) { + SetBlendType((int)it->second); + } + } } src_rect_effect = src_rect; diff --git a/src/sprite_picture.cpp b/src/sprite_picture.cpp index 58f09413234..8c005c371be 100644 --- a/src/sprite_picture.cpp +++ b/src/sprite_picture.cpp @@ -144,7 +144,9 @@ void Sprite_Picture::Draw(Bitmap& dst) { SetFlipX(data.easyrpg_flip_horizontal); SetFlipY(data.easyrpg_flip_vertical); - SetBlendType(data.easyrpg_blend_mode); + if (static_cast(data.easyrpg_blend_mode) != Bitmap::BlendMode::Default) { + SetBlendType(data.easyrpg_blend_mode); + } Sprite::Draw(dst); }