← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/fix_editor_transparency_issue into lp:widelands

 

SirVer has proposed merging lp:~widelands-dev/widelands/fix_editor_transparency_issue into lp:widelands.

Commit message:
- Fix transparency issues with representative_image().
- Refactor RenderTarget::drawanim(rect) into blit_animation and make
  RenderTarget no longer depend on logic/ code.


Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1519361 in widelands: "PlayerColor in Building menu causes render errors"
  https://bugs.launchpad.net/widelands/+bug/1519361

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/fix_editor_transparency_issue/+merge/282874

Fix transparency issues in the editor and some mild refactorings. 
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/fix_editor_transparency_issue into lp:widelands.
=== modified file 'src/graphic/animation.cc'
--- src/graphic/animation.cc	2016-01-08 21:00:39 +0000
+++ src/graphic/animation.cc	2016-01-17 19:57:08 +0000
@@ -37,8 +37,6 @@
 #include "graphic/surface.h"
 #include "graphic/texture.h"
 #include "io/filesystem/layered_filesystem.h"
-#include "logic/map_objects/bob.h"
-#include "logic/map_objects/map_object.h"
 #include "scripting/lua_table.h"
 #include "sound/sound_handler.h"
 
@@ -229,13 +227,11 @@
 	int h = image->height();
 
 	Texture* rv = new Texture(w, h);
-
-	// Initialize the rectangle
-	rv->fill_rect(Rect(Point(0, 0), w, h), RGBAColor(255, 255, 255, 0));
-
 	if (!hasplrclrs_ || clr == nullptr) {
-		rv->blit(Rect(Point(0, 0), w, h), *image, Rect(Point(0, 0), w, h), 1., BlendMode::UseAlpha);
+		// No player color means we simply want an exact copy of the original image.
+		rv->blit(Rect(Point(0, 0), w, h), *image, Rect(Point(0, 0), w, h), 1., BlendMode::Copy);
 	} else {
+		rv->fill_rect(Rect(Point(0, 0), w, h), RGBAColor(0, 0, 0, 0));
 		rv->blit_blended(Rect(Point(0, 0), w, h), *image,
 		                 *g_gr->images().get(pc_mask_image_files_[0]), Rect(Point(0, 0), w, h), *clr);
 	}

=== modified file 'src/graphic/diranimations.h'
--- src/graphic/diranimations.h	2015-02-18 09:07:31 +0000
+++ src/graphic/diranimations.h	2016-01-17 19:57:08 +0000
@@ -26,8 +26,6 @@
 
 #include "logic/widelands.h"
 
-namespace Widelands {struct MapObjectDescr;}
-
 /// Manages a set of 6 animations, one for each possible direction.
 struct DirAnimations {
 	DirAnimations

=== modified file 'src/graphic/game_renderer.cc'
--- src/graphic/game_renderer.cc	2016-01-10 11:36:05 +0000
+++ src/graphic/game_renderer.cc	2016-01-17 19:57:08 +0000
@@ -296,14 +296,14 @@
 				const Player & owner = egbase.player(owner_number[F]);
 				uint32_t const anim_idx = owner.tribe().frontier_animation();
 				if (vision[F])
-					dst.drawanim(pos[F], anim_idx, 0, &owner);
+					dst.blit_animation(pos[F], anim_idx, 0, owner.get_playercolor());
 				for (uint32_t d = 1; d < 4; ++d) {
 					if
 						((vision[F] || vision[d]) &&
 						 isborder[d] &&
 						 (owner_number[d] == owner_number[F] || !owner_number[d]))
 					{
-						dst.drawanim(middle(pos[F], pos[d]), anim_idx, 0, &owner);
+						dst.blit_animation(middle(pos[F], pos[d]), anim_idx, 0, owner.get_playercolor());
 					}
 				}
 			}
@@ -354,8 +354,8 @@
 
 						if (cur_frame) // not the first frame
 							// draw the prev frame from top to where next image will be drawing
-							dst.drawanimrect
-								(pos[F], anim_idx, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
+							dst.blit_animation(pos[F], anim_idx, tanim - FRAME_LENGTH,
+							                   owner->get_playercolor(), Rect(Point(0, 0), w, h - lines));
 						else if (csinf.was) {
 							// Is the first frame, but there was another building here before,
 							// get its last build picture and draw it instead.
@@ -365,11 +365,12 @@
 							} catch (MapObjectDescr::AnimationNonexistent &) {
 								a = csinf.was->get_animation("idle");
 							}
-							dst.drawanimrect
-								(pos[F], a, tanim - FRAME_LENGTH, owner, Rect(Point(0, 0), w, h - lines));
+							dst.blit_animation(pos[F], a, tanim - FRAME_LENGTH, owner->get_playercolor(),
+							                   Rect(Point(0, 0), w, h - lines));
 						}
 						assert(lines <= h);
-						dst.drawanimrect(pos[F], anim_idx, tanim, owner, Rect(Point(0, h - lines), w, lines));
+						dst.blit_animation(pos[F], anim_idx, tanim, owner->get_playercolor(),
+						                   Rect(Point(0, h - lines), w, lines));
 					} else if (upcast(const BuildingDescr, building, map_object_descr)) {
 						// this is a building therefore we either draw unoccupied or idle animation
 						uint32_t pic;
@@ -378,11 +379,12 @@
 						} catch (MapObjectDescr::AnimationNonexistent &) {
 							pic = building->get_animation("idle");
 						}
-						dst.drawanim(pos[F], pic, 0, owner);
+						dst.blit_animation(pos[F], pic, 0, owner->get_playercolor());
 					} else if (const uint32_t pic = map_object_descr->main_animation()) {
-						dst.drawanim(pos[F], pic, 0, owner);
+						dst.blit_animation(pos[F], pic, 0, owner->get_playercolor());
 					} else if (map_object_descr->type() == MapObjectType::FLAG) {
-						dst.drawanim(pos[F], owner->tribe().flag_animation(), 0, owner);
+						dst.blit_animation(
+						   pos[F], owner->tribe().flag_animation(), 0, owner->get_playercolor());
 					}
 				}
 			}

=== modified file 'src/graphic/rendertarget.cc'
--- src/graphic/rendertarget.cc	2016-01-10 11:36:05 +0000
+++ src/graphic/rendertarget.cc	2016-01-17 19:57:08 +0000
@@ -19,20 +19,10 @@
 
 #include "graphic/rendertarget.h"
 
-#include "base/log.h"
 #include "base/macros.h"
 #include "graphic/animation.h"
 #include "graphic/graphic.h"
 #include "graphic/surface.h"
-#include "logic/player.h"
-
-using Widelands::BaseImmovable;
-using Widelands::Coords;
-using Widelands::FCoords;
-using Widelands::Map;
-using Widelands::MapObjectDescr;
-using Widelands::Player;
-using Widelands::TCoords;
 
 /**
  * Build a render target for the given surface.
@@ -330,38 +320,45 @@
 // TODO(unknown): Correctly calculate the stereo position for sound effects
 // TODO(unknown): The chosen semantics of animation sound effects is problematic:
 // What if the game runs very slowly or very quickly?
-void RenderTarget::drawanim
-	(const Point& dst, uint32_t animation, uint32_t time, const Player* player)
-{
-	const Animation& anim = g_gr->animations().get_animation(animation);
-
-	Point destination_point = dst - anim.hotspot();
-
-	Rect srcrc(Point(0, 0), anim.width(), anim.height());
-
-	if (to_surface_geometry(&destination_point, &srcrc))
-		anim.blit(time, destination_point, srcrc, player ? &player->get_playercolor() : NULL, m_surface);
-
-	//  Look if there is a sound effect registered for this frame and trigger
-	//  the effect (see SoundHandler::stereo_position).
-	anim.trigger_soundfx(time, 128);
-}
-
-/**
- * Draws a part of a frame of an animation at the given location
- */
-void RenderTarget::drawanimrect
-	(const Point& dst, uint32_t animation, uint32_t time, const Player* player, const Rect& gsrcrc)
-{
-	const Animation& anim = g_gr->animations().get_animation(animation);
-
-	Point destination_point = dst - anim.hotspot();
-	destination_point += gsrcrc.origin();
-
-	Rect srcrc(gsrcrc);
-
-	if (to_surface_geometry(&destination_point, &srcrc))
-		anim.blit(time, destination_point, srcrc, player ? &player->get_playercolor() : NULL, m_surface);
+void RenderTarget::blit_animation(const Point& dst, uint32_t animation, uint32_t time) {
+	const Animation& anim = g_gr->animations().get_animation(animation);
+	do_blit_animation(dst, anim, time, nullptr, Rect(Point(0, 0), anim.width(), anim.height()));
+}
+
+void RenderTarget::blit_animation(const Point& dst,
+                                  uint32_t animation,
+                                  uint32_t time,
+                                  const RGBColor& player_color) {
+	const Animation& anim = g_gr->animations().get_animation(animation);
+	do_blit_animation(dst, anim, time, &player_color, Rect(Point(0, 0), anim.width(), anim.height()));
+}
+
+void RenderTarget::blit_animation(const Point& dst,
+                                  uint32_t animation,
+                                  uint32_t time,
+                                  const RGBColor& player_color,
+                                  const Rect& source_rect) {
+	do_blit_animation(
+	   dst, g_gr->animations().get_animation(animation), time, &player_color, source_rect);
+}
+
+void RenderTarget::do_blit_animation(const Point& dst,
+                                     const Animation& animation,
+                                     uint32_t time,
+                                     const RGBColor* player_color,
+                                     const Rect& source_rect) {
+	Point destination_point = dst - animation.hotspot();
+	destination_point += source_rect.origin();
+
+	Rect srcrc(source_rect);
+	if (to_surface_geometry(&destination_point, &srcrc))
+		animation.blit(time, destination_point, srcrc, player_color, m_surface);
+
+	// Look if there is a sound effect registered for this frame and trigger the
+	// effect (see SoundHandler::stereo_position).
+	// TODO(sirver): Playing a sound effect in here is rather silly. What if
+	// this animation is used in the menus?
+	animation.trigger_soundfx(time, 128);
 }
 
 /**

=== modified file 'src/graphic/rendertarget.h'
--- src/graphic/rendertarget.h	2015-11-28 11:04:12 +0000
+++ src/graphic/rendertarget.h	2016-01-17 19:57:08 +0000
@@ -28,12 +28,9 @@
 #include "graphic/color.h"
 #include "graphic/image.h"
 
+class Animation;
 class Surface;
 
-namespace Widelands {
-class Player;
-}
-
 /**
  * This class represents anything that can be rendered to.
  *
@@ -103,9 +100,15 @@
 	          const Point& ofs,
 	          BlendMode blend_mode = BlendMode::UseAlpha);
 
-	void drawanim(const Point& dst, uint32_t animation, uint32_t time, const Widelands::Player* = 0);
-	void drawanimrect
-		(const Point& dst, uint32_t animation, uint32_t time, const Widelands::Player*, const Rect& srcrc);
+	// Draw the 'animation' as it should appear at 'time' in this target ad 'dst'. Optionally, the animation is
+	// tinted with 'player_color' and cropped to 'source_rect'.
+	void blit_animation(const Point& dst, uint32_t animation, uint32_t time);
+	void blit_animation(const Point& dst, uint32_t animation, uint32_t time, const RGBColor& player_color);
+	void blit_animation(const Point& dst,
+	                    uint32_t animation,
+	                    uint32_t time,
+	                    const RGBColor& player_color,
+	                    const Rect& source_rect);
 
 	void reset();
 
@@ -117,6 +120,13 @@
 	bool clip(Rect & r) const;
 	bool to_surface_geometry(Point* dst, Rect* srcrc) const;
 
+	// Does the actual blitting.
+	void do_blit_animation(const Point& dst,
+	                       const Animation& animation,
+	                       uint32_t time,
+	                       const RGBColor* player_color,
+	                       const Rect& source_rect);
+
 	///The target surface
 	Surface* m_surface;
 	///The current clip rectangle

=== modified file 'src/logic/map_objects/bob.cc'
--- src/logic/map_objects/bob.cc	2016-01-06 19:11:20 +0000
+++ src/logic/map_objects/bob.cc	2016-01-17 19:57:08 +0000
@@ -850,12 +850,15 @@
 void Bob::draw
 	(const EditorGameBase & egbase, RenderTarget & dst, const Point& pos) const
 {
-	if (m_anim)
-		dst.drawanim
-			(calc_drawpos(egbase, pos),
-			 m_anim,
-			 egbase.get_gametime() - m_animstart,
-			 get_owner());
+	if (m_anim) {
+		auto* const owner = get_owner();
+		if (owner != nullptr) {
+			dst.blit_animation(calc_drawpos(egbase, pos), m_anim, egbase.get_gametime() - m_animstart,
+			                   owner->get_playercolor());
+		} else {
+			dst.blit_animation(calc_drawpos(egbase, pos), m_anim, egbase.get_gametime() - m_animstart);
+		}
+	}
 }
 
 

=== modified file 'src/logic/map_objects/immovable.cc'
--- src/logic/map_objects/immovable.cc	2015-12-11 19:06:50 +0000
+++ src/logic/map_objects/immovable.cc	2016-01-17 19:57:08 +0000
@@ -441,7 +441,7 @@
 {
 	if (m_anim) {
 		if (!m_anim_construction_total)
-			dst.drawanim(pos, m_anim, game.get_gametime() - m_animstart, nullptr);
+			dst.blit_animation(pos, m_anim, game.get_gametime() - m_animstart);
 		else
 			draw_construction(game, dst, pos);
 	}
@@ -477,14 +477,16 @@
 
 	uint32_t lines = ((done % units_per_frame) * curh) / units_per_frame;
 
+	assert(get_owner() != nullptr);  // Who would build something they do not own?
+	const RGBColor& player_color = get_owner()->get_playercolor();
 	if (current_frame > 0) {
 		// Not the first pic, so draw the previous one in the back
-		dst.drawanim(pos, m_anim, (current_frame - 1) * frametime, get_owner());
+		dst.blit_animation(pos, m_anim, (current_frame - 1) * frametime, player_color);
 	}
 
 	assert(lines <= curh);
-	dst.drawanimrect
-		(pos, m_anim, current_frame * frametime, get_owner(), Rect(Point(0, curh - lines), curw, lines));
+	dst.blit_animation(pos, m_anim, current_frame * frametime, player_color,
+	                   Rect(Point(0, curh - lines), curw, lines));
 
 	// Additionally, if statistics are enabled, draw a progression string
 	if (game.get_ibase()->get_display_flags() & InteractiveBase::dfShowStatistics) {

=== modified file 'src/logic/map_objects/tribes/building.cc'
--- src/logic/map_objects/tribes/building.cc	2015-12-11 19:06:50 +0000
+++ src/logic/map_objects/tribes/building.cc	2016-01-17 19:57:08 +0000
@@ -686,8 +686,8 @@
 	(const EditorGameBase& game, RenderTarget& dst, const FCoords& coords, const Point& pos)
 {
 	if (coords == m_position) { // draw big buildings only once
-		dst.drawanim
-			(pos, m_anim, game.get_gametime() - m_animstart, get_owner());
+		dst.blit_animation(
+		   pos, m_anim, game.get_gametime() - m_animstart, get_owner()->get_playercolor());
 
 		//  door animation?
 

=== modified file 'src/logic/map_objects/tribes/constructionsite.cc'
--- src/logic/map_objects/tribes/constructionsite.cc	2015-11-28 22:29:26 +0000
+++ src/logic/map_objects/tribes/constructionsite.cc	2016-01-17 19:57:08 +0000
@@ -329,7 +329,8 @@
 		return; // draw big buildings only once
 
 	// Draw the construction site marker
-	dst.drawanim(pos, m_anim, tanim, get_owner());
+	const RGBColor& player_color = get_owner()->get_playercolor();
+	dst.blit_animation(pos, m_anim, tanim, player_color);
 
 	// Draw the partially finished building
 
@@ -371,10 +372,11 @@
 	assert(h * cur_frame <= lines);
 	lines -= h * cur_frame; //  This won't work if pictures have various sizes.
 
-	if (cur_frame) //  not the first pic
+	if (cur_frame) { //  not the first pic
 		//  draw the prev pic from top to where next image will be drawing
-		dst.drawanimrect(pos, anim_idx, tanim - FRAME_LENGTH, get_owner(), Rect(Point(0, 0), w, h - lines));
-	else if (!m_old_buildings.empty()) {
+		dst.blit_animation(pos, anim_idx, tanim - FRAME_LENGTH, player_color,
+		                   Rect(Point(0, 0), w, h - lines));
+	} else if (!m_old_buildings.empty()) {
 		DescriptionIndex prev_idx = m_old_buildings.back();
 		const BuildingDescr* prev_building = owner().tribe().get_building_descr(prev_idx);
 		//  Is the first picture but there was another building here before,
@@ -386,14 +388,13 @@
 			prev_building_anim_idx = prev_building->get_animation("idle");
 		}
 		const Animation& prev_building_anim = g_gr->animations().get_animation(prev_building_anim_idx);
-		dst.drawanimrect
-			(pos, prev_building_anim_idx, tanim - FRAME_LENGTH, get_owner(),
-			 Rect
-			 (Point(0, 0), prev_building_anim.width(), std::min<int>(prev_building_anim.height(), h - lines)));
+		dst.blit_animation(pos, prev_building_anim_idx, tanim - FRAME_LENGTH, player_color,
+		                   Rect(Point(0, 0), prev_building_anim.width(),
+		                        std::min<int>(prev_building_anim.height(), h - lines)));
 	}
 
 	assert(lines <= h);
-	dst.drawanimrect(pos, anim_idx, tanim, get_owner(), Rect(Point(0, h - lines), w, lines));
+	dst.blit_animation(pos, anim_idx, tanim, player_color, Rect(Point(0, h - lines), w, lines));
 
 	// Draw help strings
 	draw_help(game, dst, coords, pos);

=== modified file 'src/logic/map_objects/tribes/dismantlesite.cc'
--- src/logic/map_objects/tribes/dismantlesite.cc	2015-11-28 22:29:26 +0000
+++ src/logic/map_objects/tribes/dismantlesite.cc	2016-01-17 19:57:08 +0000
@@ -238,8 +238,10 @@
 	if (coords != m_position)
 		return; // draw big buildings only once
 
+	const RGBColor& player_color = get_owner()->get_playercolor();
+
 	// Draw the construction site marker
-	dst.drawanim(pos, m_anim, tanim, get_owner());
+	dst.blit_animation(pos, m_anim, tanim, player_color);
 
 	// Draw the partially dismantled building
 	static_assert(0 <= DISMANTLESITE_STEP_TIME, "assert(0 <= DISMANTLESITE_STEP_TIME) failed.");
@@ -261,7 +263,7 @@
 
 	uint32_t lines = h * completed_time / total_time;
 
-	dst.drawanimrect(pos, anim_idx, tanim, get_owner(), Rect(Point(0, lines), w, h - lines));
+	dst.blit_animation(pos, anim_idx, tanim, player_color, Rect(Point(0, lines), w, h - lines));
 
 	// Draw help strings
 	draw_help(game, dst, coords, pos);

=== modified file 'src/logic/map_objects/tribes/worker.cc'
--- src/logic/map_objects/tribes/worker.cc	2016-01-14 22:09:24 +0000
+++ src/logic/map_objects/tribes/worker.cc	2016-01-17 19:57:08 +0000
@@ -2925,18 +2925,16 @@
 	(const EditorGameBase& game, RenderTarget& dst, const Point& drawpos)
 	const
 {
-	dst.drawanim
-		(drawpos,
-		 get_current_anim(),
-		 game.get_gametime() - get_animstart(),
-		 get_owner());
-
-	if (WareInstance const * const carried_ware = get_carried_ware(game))
-		dst.drawanim
-			(drawpos - descr().get_ware_hotspot(),
-			 carried_ware->descr().get_animation("idle"),
-			 0,
-			 get_owner());
+	assert(get_owner() != nullptr);
+	const RGBColor& player_color = get_owner()->get_playercolor();
+
+	dst.blit_animation(
+	   drawpos, get_current_anim(), game.get_gametime() - get_animstart(), player_color);
+
+	if (WareInstance const* const carried_ware = get_carried_ware(game)) {
+		dst.blit_animation(drawpos - descr().get_ware_hotspot(),
+		                   carried_ware->descr().get_animation("idle"), 0, player_color);
+	}
 }
 
 

=== modified file 'src/wui/itemwaresdisplay.cc'
--- src/wui/itemwaresdisplay.cc	2015-11-28 22:29:26 +0000
+++ src/wui/itemwaresdisplay.cc	2016-01-17 19:57:08 +0000
@@ -119,9 +119,9 @@
 
 		if (it.worker) {
 			y += IWD_WorkerBaseline;
-			dst.drawanim
-				(Point(x + (IWD_ItemWidth / 2), y + (IWD_ItemHeight / 2)),
-				 tribe.get_worker_descr(it.index)->main_animation(), 0, &player());
+			dst.blit_animation(Point(x + (IWD_ItemWidth / 2), y + (IWD_ItemHeight / 2)),
+			                   tribe.get_worker_descr(it.index)->main_animation(), 0,
+			                   player().get_playercolor());
 		} else {
 			y += IWD_WareBaseLine;
 			if (tribe.get_ware_descr(it.index)->icon())

=== modified file 'src/wui/transport_draw.cc'
--- src/wui/transport_draw.cc	2014-09-10 08:55:04 +0000
+++ src/wui/transport_draw.cc	2016-01-17 19:57:08 +0000
@@ -40,8 +40,9 @@
 		{8, -3}
 	};
 
-	dst.drawanim
-		(pos, owner().tribe().flag_animation(), game.get_gametime() - m_animstart, &owner());
+	const RGBColor& player_color = owner().get_playercolor();
+	dst.blit_animation(
+	   pos, owner().tribe().flag_animation(), game.get_gametime() - m_animstart, player_color);
 
 	const uint32_t ware_filled = m_ware_filled;
 	for (uint32_t i = 0; i < ware_filled; ++i) { //  draw wares
@@ -51,11 +52,7 @@
 			warepos.y += ware_offsets[i].y;
 		} else
 			warepos.y -= 6 + (i - 8) * 3;
-		dst.drawanim
-			(warepos,
-			 m_wares[i].ware->descr().get_animation("idle"),
-			 0,
-			 get_owner());
+		dst.blit_animation(warepos, m_wares[i].ware->descr().get_animation("idle"), 0, player_color);
 	}
 }
 


Follow ups