From 7e5872f4f1b4b46041b9464a7b027c49273c5f08 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Wed, 1 Sep 2021 18:34:45 +0200 Subject: [PATCH] Add an additional abstraction between pixman_op_t and the Blend Mode --- src/bitmap.cpp | 59 ++++++++++++++++++++++++++++++--------- src/bitmap.h | 60 ++++++++++++++++++++++++++-------------- src/game_interpreter.cpp | 12 ++++---- src/game_pictures.h | 2 +- src/sprite.cpp | 2 +- src/sprite.h | 2 +- 6 files changed, 94 insertions(+), 43 deletions(-) diff --git a/src/bitmap.cpp b/src/bitmap.cpp index 5264efd9fb4..d7154b988c8 100644 --- a/src/bitmap.cpp +++ b/src/bitmap.cpp @@ -569,7 +569,7 @@ namespace { } } // anonymous namespace -void Bitmap::Blit(int x, int y, Bitmap const& src, Rect const& src_rect, Opacity const& opacity, int blend_mode) { +void Bitmap::Blit(int x, int y, Bitmap const& src, Rect const& src_rect, Opacity const& opacity, Bitmap::BlendMode blend_mode) { if (opacity.IsTransparent()) { return; } @@ -605,11 +605,11 @@ PixmanImagePtr Bitmap::GetSubimage(Bitmap const& src, const Rect& src_rect) { (uint32_t*) pixels, src.pitch()) }; } -void Bitmap::TiledBlit(Rect const& src_rect, Bitmap const& src, Rect const& dst_rect, Opacity const& opacity, int blend_mode) { +void Bitmap::TiledBlit(Rect const& src_rect, Bitmap const& src, Rect const& dst_rect, Opacity const& opacity, Bitmap::BlendMode blend_mode) { TiledBlit(0, 0, src_rect, src, dst_rect, opacity, blend_mode); } -void Bitmap::TiledBlit(int ox, int oy, Rect const& src_rect, Bitmap const& src, Rect const& dst_rect, Opacity const& opacity, int blend_mode) { +void Bitmap::TiledBlit(int ox, int oy, Rect const& src_rect, Bitmap const& src, Rect const& dst_rect, Opacity const& opacity, Bitmap::BlendMode blend_mode) { if (opacity.IsTransparent()) { return; } @@ -633,11 +633,11 @@ void Bitmap::TiledBlit(int ox, int oy, Rect const& src_rect, Bitmap const& src, dst_rect.width, dst_rect.height); } -void Bitmap::StretchBlit(Bitmap const& src, Rect const& src_rect, Opacity const& opacity, int blend_mode) { +void Bitmap::StretchBlit(Bitmap const& src, Rect const& src_rect, Opacity const& opacity, Bitmap::BlendMode blend_mode) { StretchBlit(GetRect(), src, src_rect, opacity, blend_mode); } -void Bitmap::StretchBlit(Rect const& dst_rect, Bitmap const& src, Rect const& src_rect, Opacity const& opacity, int blend_mode) { +void Bitmap::StretchBlit(Rect const& dst_rect, Bitmap const& src, Rect const& src_rect, Opacity const& opacity, Bitmap::BlendMode blend_mode) { if (opacity.IsTransparent()) { return; } @@ -661,7 +661,7 @@ void Bitmap::StretchBlit(Rect const& dst_rect, Bitmap const& src, Rect const& sr pixman_image_set_transform(src.bitmap.get(), nullptr); } -void Bitmap::WaverBlit(int x, int y, double zoom_x, double zoom_y, Bitmap const& src, Rect const& src_rect, int depth, double phase, Opacity const& opacity, int blend_mode) { +void Bitmap::WaverBlit(int x, int y, double zoom_x, double zoom_y, Bitmap const& src, Rect const& src_rect, int depth, double phase, Opacity const& opacity, Bitmap::BlendMode blend_mode) { if (opacity.IsTransparent()) { return; } @@ -946,7 +946,7 @@ void Bitmap::BlendBlit(int x, int y, Bitmap const& src, Rect const& src_rect, co src_rect.width, src_rect.height); } -void Bitmap::FlipBlit(int x, int y, Bitmap const& src, Rect const& src_rect, bool horizontal, bool vertical, Opacity const& opacity, int blend_mode) { +void Bitmap::FlipBlit(int x, int y, Bitmap const& src, Rect const& src_rect, bool horizontal, bool vertical, Opacity const& opacity, Bitmap::BlendMode blend_mode) { if (opacity.IsTransparent()) { return; } @@ -1043,7 +1043,7 @@ void Bitmap::EffectsBlit(int x, int y, int ox, int oy, Bitmap const& src, Rect const& src_rect, Opacity const& opacity, double zoom_x, double zoom_y, double angle, - int waver_depth, double waver_phase, int blend_mode) { + int waver_depth, double waver_phase, Bitmap::BlendMode blend_mode) { if (opacity.IsTransparent()) { return; } @@ -1069,7 +1069,7 @@ void Bitmap::EffectsBlit(int x, int y, int ox, int oy, void Bitmap::RotateZoomOpacityBlit(int x, int y, int ox, int oy, Bitmap const& src, Rect const& src_rect, - double angle, double zoom_x, double zoom_y, Opacity const& opacity, int blend_mode) + double angle, double zoom_x, double zoom_y, Opacity const& opacity, Bitmap::BlendMode blend_mode) { if (opacity.IsTransparent()) { return; @@ -1114,7 +1114,7 @@ void Bitmap::RotateZoomOpacityBlit(int x, int y, int ox, int oy, void Bitmap::ZoomOpacityBlit(int x, int y, int ox, int oy, Bitmap const& src, Rect const& src_rect, double zoom_x, double zoom_y, - Opacity const& opacity, int blend_mode) + Opacity const& opacity, Bitmap::BlendMode blend_mode) { if (opacity.IsTransparent()) { return; @@ -1128,9 +1128,42 @@ void Bitmap::ZoomOpacityBlit(int x, int y, int ox, int oy, StretchBlit(dst_rect, src, src_rect, opacity, blend_mode); } -pixman_op_t Bitmap::GetOperator(pixman_image_t* mask, int blend_mode) const { - if (blend_mode >= 0) { - return (pixman_op_t)blend_mode; +pixman_op_t Bitmap::GetOperator(pixman_image_t* mask, Bitmap::BlendMode blend_mode) const { + if (blend_mode != BlendMode::Default) { + switch (blend_mode) { + case BlendMode::Normal: + return PIXMAN_OP_OVER; + case BlendMode::NormalWithoutAlpha: + return PIXMAN_OP_SRC; + case BlendMode::XOR: + return PIXMAN_OP_XOR; + case BlendMode::Additive: + return PIXMAN_OP_ADD; + case BlendMode::Multiply: + return PIXMAN_OP_MULTIPLY; + case BlendMode::Overlay: + return PIXMAN_OP_OVERLAY; + case BlendMode::Saturate: + return PIXMAN_OP_SATURATE; + case BlendMode::Darken: + return PIXMAN_OP_DARKEN; + case BlendMode::Lighten: + return PIXMAN_OP_LIGHTEN; + case BlendMode::ColorDodge: + return PIXMAN_OP_COLOR_DODGE; + case BlendMode::ColorBurn: + return PIXMAN_OP_COLOR_BURN; + case BlendMode::Difference: + return PIXMAN_OP_DIFFERENCE; + case BlendMode::Exclusion: + return PIXMAN_OP_EXCLUSION; + case BlendMode::SoftLight: + return PIXMAN_OP_SOFT_LIGHT; + case BlendMode::HardLight: + return PIXMAN_OP_HARD_LIGHT; + default: + return PIXMAN_OP_CLEAR; + } } if (!mask && (!GetTransparent() || GetImageOpacity() == ImageOpacity::Opaque)) { diff --git a/src/bitmap.h b/src/bitmap.h index 6b8e33b02f3..f13404b0341 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -153,6 +153,24 @@ class Bitmap { Flag_ReadOnly = 1 << 16 }; + enum class BlendMode { + Default, // SRC or OVER depending on the image + Normal, // OP_OVER + NormalWithoutAlpha, // OP_SRC + XOR, + Additive, + Multiply, + Overlay, + Saturate, + Darken, + Lighten, + ColorDodge, + ColorBurn, + Difference, + Exclusion, + SoftLight, + HardLight + }; /** * Provides opacity information about the image. @@ -248,10 +266,10 @@ class Bitmap { * @param src source bitmap. * @param src_rect source bitmap rect. * @param opacity opacity for blending with bitmap. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void Blit(int x, int y, Bitmap const& src, Rect const& src_rect, - Opacity const& opacity, int blend_mode = -1); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Default); /** * Blits source bitmap to this one ignoring alpha (faster) @@ -272,10 +290,10 @@ class Bitmap { * @param src source bitmap. * @param dst_rect destination rect. * @param opacity opacity for blending with bitmap. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void TiledBlit(Rect const& src_rect, Bitmap const& src, Rect const& dst_rect, - Opacity const& opacity, int blend_mode = -1); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Default); /** * Blits source bitmap in tiles to this one. @@ -286,10 +304,10 @@ class Bitmap { * @param src source bitmap. * @param dst_rect destination rect. * @param opacity opacity for blending with bitmap. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void TiledBlit(int ox, int oy, Rect const& src_rect, Bitmap const& src, Rect const& dst_rect, - Opacity const& opacity, int blend_mode = -1); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Default); /** * Blits source bitmap to this one, making clones across the edges if src crossed a boundary of this. @@ -310,10 +328,10 @@ class Bitmap { * @param src source bitmap. * @param src_rect source bitmap rect. * @param opacity opacity for blending with bitmap. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void StretchBlit(Bitmap const& src, Rect const& src_rect, - Opacity const& opacity, int blend_mode = -1); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Default); /** * Blits source bitmap stretched to this one. @@ -322,10 +340,10 @@ class Bitmap { * @param src source bitmap. * @param src_rect source bitmap rect. * @param opacity opacity for blending with bitmap. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void StretchBlit(Rect const& dst_rect, Bitmap const& src, Rect const& src_rect, - Opacity const& opacity, int blend_mode = -1); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Default); /** * Blit source bitmap flipped. @@ -337,10 +355,10 @@ class Bitmap { * @param horizontal flip horizontally. * @param vertical flip vertically. * @param opacity opacity to apply. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void FlipBlit(int x, int y, Bitmap const& src, Rect const& src_rect, bool horizontal, bool vertical, - Opacity const& opacity, int blend_mode = -1); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Default); /** * Blits source bitmap with waver, zoom, and opacity effects. @@ -354,10 +372,10 @@ class Bitmap { * @param depth wave magnitude. * @param phase wave phase. * @param opacity opacity. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void WaverBlit(int x, int y, double zoom_x, double zoom_y, Bitmap const& src, Rect const& src_rect, int depth, double phase, - Opacity const& opacity, int blend_mode = -1); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Default); /** * Blits source bitmap with rotation, zoom, and opacity effects. @@ -372,12 +390,12 @@ class Bitmap { * @param zoom_x x scale factor. * @param zoom_y y scale factor. * @param opacity opacity. - * @param blend_mode Blend mode to use. default: OP_OVER + * @param blend_mode Blend mode to use. */ void RotateZoomOpacityBlit(int x, int y, int ox, int oy, Bitmap const& src, Rect const& src_rect, double angle, double zoom_x, double zoom_y, - Opacity const& opacity, int blend_mode = PIXMAN_OP_OVER); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Normal); /** * Blits source bitmap with zoom and opacity scaling. @@ -391,12 +409,12 @@ class Bitmap { * @param zoom_x x scale factor. * @param zoom_y y scale factor. * @param opacity opacity. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void ZoomOpacityBlit(int x, int y, int ox, int oy, Bitmap const& src, Rect const& src_rect, double zoom_x, double zoom_y, - Opacity const& opacity, int blend_mode = -1); + Opacity const& opacity, BlendMode blend_mode = BlendMode::Default); /** * Fills entire bitmap with color. @@ -526,14 +544,14 @@ class Bitmap { * @param angle rotation angle. * @param waver_depth wave magnitude. * @param waver_phase wave phase. - * @param blend_mode Blend mode to use. default: OP_SRC/OP_OVER; depends on the image + * @param blend_mode Blend mode to use. */ void EffectsBlit(int x, int y, int ox, int oy, Bitmap const& src, Rect const& src_rect, Opacity const& opacity, double zoom_x, double zoom_y, double angle, int waver_depth, double waver_phase, - int blend_mode = -1); + BlendMode blend_mode = BlendMode::Default); static DynamicFormat ChooseFormat(const DynamicFormat& format); static void SetFormat(const DynamicFormat& format); @@ -593,7 +611,7 @@ class Bitmap { * @param blend_mode When >= 0: Force this blend mode as operator * @return blend mode */ - pixman_op_t GetOperator(pixman_image_t* mask = nullptr, int blend_mode = -1) const; + pixman_op_t GetOperator(pixman_image_t* mask = nullptr, BlendMode blend_mode = BlendMode::Default) const; bool read_only = false; }; diff --git a/src/game_interpreter.cpp b/src/game_interpreter.cpp index 585e2c27e0d..58c862d31f8 100644 --- a/src/game_interpreter.cpp +++ b/src/game_interpreter.cpp @@ -2616,11 +2616,11 @@ bool Game_Interpreter::CommandShowPicture(lcf::rpg::EventCommand const& com) { / int flags = com.parameters[14] >> 8; int blend_mode = flags & 3; if (blend_mode == 1) { - params.blend_mode = PIXMAN_OP_MULTIPLY; + params.blend_mode = (int)Bitmap::BlendMode::Multiply; } else if (blend_mode == 2) { - params.blend_mode = PIXMAN_OP_ADD; + params.blend_mode = (int)Bitmap::BlendMode::Additive; } else if (blend_mode == 3) { - params.blend_mode = PIXMAN_OP_OVERLAY; + params.blend_mode = (int)Bitmap::BlendMode::Overlay; } params.flip_horizontal = (flags & 16) == 16; params.flip_vertical = (flags & 32) == 32; @@ -2690,11 +2690,11 @@ bool Game_Interpreter::CommandMovePicture(lcf::rpg::EventCommand const& com) { / int flags = com.parameters[16] >> 8; int blend_mode = flags & 3; if (blend_mode == 1) { - params.blend_mode = PIXMAN_OP_MULTIPLY; + params.blend_mode = (int)Bitmap::BlendMode::Multiply; } else if (blend_mode == 2) { - params.blend_mode = PIXMAN_OP_ADD; + params.blend_mode = (int)Bitmap::BlendMode::Additive; } else if (blend_mode == 3) { - params.blend_mode = PIXMAN_OP_OVERLAY; + params.blend_mode = (int)Bitmap::BlendMode::Overlay; } params.flip_horizontal = (flags & 16) == 16; params.flip_vertical = (flags & 32) == 32; diff --git a/src/game_pictures.h b/src/game_pictures.h index 75192d7715c..940e24b31a0 100644 --- a/src/game_pictures.h +++ b/src/game_pictures.h @@ -57,7 +57,7 @@ class Game_Pictures { // Extensions bool flip_horizontal = false; bool flip_vertical = false; - int blend_mode = -1; + int blend_mode = 0; }; struct ShowParams : Params { std::string name; diff --git a/src/sprite.cpp b/src/sprite.cpp index cc502821952..16203e9fc15 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -67,7 +67,7 @@ void Sprite::BlitScreenIntern(Bitmap& dst, Bitmap const& draw_bitmap, Rect const dst.EffectsBlit(x, y, ox, oy, draw_bitmap, src_rect, Opacity(opacity_top_effect, opacity_bottom_effect, bush_effect), zoom_x, zoom_y, angle_effect, - waver_effect_depth, waver_effect_phase, blend_type_effect); + waver_effect_depth, waver_effect_phase, static_cast(blend_type_effect)); } BitmapRef Sprite::Refresh(Rect& rect) { diff --git a/src/sprite.h b/src/sprite.h index 6129965bdbe..3e0857f8d37 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -119,7 +119,7 @@ class Sprite : public Drawable { double zoom_x_effect = 1.0; double zoom_y_effect = 1.0; double angle_effect = 0.0; - int blend_type_effect = -1; + int blend_type_effect = 0; Color blend_color_effect; int waver_effect_depth = 0; double waver_effect_phase = 0.0;