Merge lp:~widelands-dev/widelands/buildicon_playercolors into lp:widelands

Proposed by Jens Beyer
Status: Merged
Merged at revision: 6909
Proposed branch: lp:~widelands-dev/widelands/buildicon_playercolors
Merge into: lp:widelands
Diff against target: 202 lines (+60/-37)
4 files modified
src/constants.h (+3/-0)
src/graphic/animation.h (+4/-3)
src/graphic/image_transformations.cc (+18/-2)
src/wui/fieldaction.cc (+35/-32)
To merge this branch: bzr merge lp:~widelands-dev/widelands/buildicon_playercolors
Reviewer Review Type Date Requested Status
Widelands Developers Pending
Review via email: mp+211401@code.launchpad.net

Description of the change

Ok, new try for the player-colored build-icons. Now with the code merged by the sprite-maps branch.

We now have one main advantage - we really do not need all those menu.png for the buildings anymore.

But there are two disadvantages - some of the icons are really barely distinguishable from the background, like the Barbarian Well; and the details of the large buildings somehow distract the eye in the menu, but this could also only be me.

I can imagine making the menu slightly bigger allowing for bigger buttons (like 50x50px). But the problem with the Well persists.

Before merging, we need to remove all menu.png in the tribes (not done yet, I just want code and design review; if you approve, I will remove those files and the sources related to them).

To post a comment you must log in.
Revision history for this message
SirVer (sirver) wrote :

looks good and works great. I changed the code to use get_animation("idle") instead of main_animation() - which should probably be removed anyways. I also dropped a NOCOM(#qcs) for you.

I would also suggest doing a side by side comparison between the new menu and the old to see if quality has decreased before submitting.

When you remove the menu.png, keep in mind that they sometimes are used as idle animation too - so you'll need to check the conf files real quick too.

I suggest making the images bigger - resolutions have changed over the years. But that can be done separately if you prefer.

Revision history for this message
Jens Beyer (qcumber-some) wrote :

I fixed the NOCOM.
But there is one problem which was not present yesterday: The playercolors in the building menu are completely wrong. I remember that it definitely worked. What could have caused this?

Revision history for this message
Jens Beyer (qcumber-some) wrote :

I am not sure why, but the playercolors in the build menu do not work on the branch, even with trunk merged; but merging this branch into trunk makes the playercolor work in the build menu.
Now I am totally confused.

Revision history for this message
SirVer (sirver) wrote :

const Image& anim_frame = g_gr->animations().get_animation(descr.get_animation("idle"))
.representative_image(RGBColor(0, 0, 0));

well, here was the problem. You construct an image with playercolor black, always. I changed it to use the true player color.

While doing that I also checked the differences in the resized image - and they look awful. The menu.png images are much prettier - especially noticable in the big buildings. I think the zoomSurface method is not cutting it really - we need something fancier that does proper filtering. The plus side is that we then can get rid of the SDLgfx dependency which we only use for resizing. The downside is that we need to add another library or roll our own - keep in mind that we also need to upscale sometimes (menus). I think this is really important, but can be done after this is merged - however if this is merged, it needs to be done and soonish.

This looks sophisticated:
http://www.codeproject.com/Articles/11143/Image-Resizing-outperform-GDI

This should give some ideas:
http://stackoverflow.com/questions/3086770/what-algorithms-to-use-for-image-downsizing

Revision history for this message
SirVer (sirver) wrote :

And there is a bilinear interpolation ready to be copy&pasted: http://www.scratchapixel.com/lessons/3d-advanced-lessons/interpolation/bilinear-interpolation/

That is maybe already good enough.

Revision history for this message
SirVer (sirver) wrote :

I looked around the SDLgfx source code real quick and saw that it provides a shrinking method that gives better quality then just using zoom to shrink. I added a quick hack to shrink the image to ballpark the size, then zoomSurface to get it correct. It still looks worse than menu.png, but much better than before. I think we can ship this and see if somebody complains. Or we enhance the image rescaling later anyways.

Revision history for this message
SirVer (sirver) wrote :

ping?

Revision history for this message
Jens Beyer (qcumber-some) wrote :

Sorry, got distracted by 'the other life'.

I say this is good enough to go on trunk.

Few words:
1) We can not get rid yet of the menu.png files as they are used at other places (Editor, Messages...). Those should be targetted next.
2) I agree that I can live with the current state of the menu images on this branch. Though I did not have a look at them with very low resolution, rather the opposite ;-) But I trust your eyes more than mine.
3) Maybe we should file two new bugs then after merging this: Get rid of menu.png files, and find a better scaling algorithm.

Unfortunately I can not contribute to widelands development for the next few weeks.

Revision history for this message
SirVer (sirver) wrote :

Merged.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/constants.h'
--- src/constants.h 2013-10-14 07:20:46 +0000
+++ src/constants.h 2014-03-18 19:28:13 +0000
@@ -38,6 +38,9 @@
38#define TEXTURE_HEIGHT TEXTURE_WIDTH38#define TEXTURE_HEIGHT TEXTURE_WIDTH
39//@}39//@}
4040
41//sizes for the images in the build menu (containing building icons)
42#define BUILDMENU_IMAGE_SIZE 30. // used for width and height
43
41#define XRES 800 ///< Fullscreen Menu Width44#define XRES 800 ///< Fullscreen Menu Width
42#define YRES 600 ///< Fullscreen Menu Height45#define YRES 600 ///< Fullscreen Menu Height
4346
4447
=== modified file 'src/graphic/animation.h'
--- src/graphic/animation.h 2014-03-16 20:55:15 +0000
+++ src/graphic/animation.h 2014-03-18 19:28:13 +0000
@@ -63,9 +63,10 @@
63 /// so the caller has to adjust for the hotspot himself.63 /// so the caller has to adjust for the hotspot himself.
64 virtual const Point& hotspot() const = 0;64 virtual const Point& hotspot() const = 0;
6565
66 /// An image frame that shows a singular animation frame. This can be used in66 // An image frame that shows the first animation frame, colored using the
67 /// the UI (e.g. buildingwindow to represent this image.67 // 'player_clr'. This can be used in the UI (e.g. buildingwindow) to
68 virtual const Image& representative_image(const RGBColor& clr) const = 0;68 // represent this image.
69 virtual const Image& representative_image(const RGBColor& player_clr) const = 0;
6970
70 /// Blit the animation frame that should be displayed at the given time index71 /// Blit the animation frame that should be displayed at the given time index
71 /// so that the given point is at the top left of the frame. Srcrc defines72 /// so that the given point is at the top left of the frame. Srcrc defines
7273
=== modified file 'src/graphic/image_transformations.cc'
--- src/graphic/image_transformations.cc 2014-02-22 18:04:02 +0000
+++ src/graphic/image_transformations.cc 2014-03-18 19:28:13 +0000
@@ -97,9 +97,25 @@
97 srcsdl = extract_sdl_surface(*src, srcrect);97 srcsdl = extract_sdl_surface(*src, srcrect);
98 }98 }
9999
100 // If we actually shrink a surface, ballpark the zoom so that the shrinking
101 // effect is weakened.
102 int factor = 1;
103 while ((static_cast<double>(w) * factor / srcsdl->w) < 1. ||
104 (static_cast<double>(h) * factor / srcsdl->h) < 1.) {
105 ++factor;
106 }
107 if (factor > 2) {
108 SDL_Surface* temp = shrinkSurface(srcsdl, factor - 1, factor - 1);
109 if (free_source) {
110 SDL_FreeSurface(srcsdl);
111 }
112 srcsdl = temp;
113 free_source = true;
114 }
115
100 // Third step: perform the zoom and placement116 // Third step: perform the zoom and placement
101 SDL_Surface * zoomed = zoomSurface117 SDL_Surface* zoomed = zoomSurface(srcsdl, double(w) / srcsdl->w, double(h) / srcsdl->h, 1);
102 (srcsdl, double(w) / srcsdl->w, double(h) / srcsdl->h, 1);118
103 if (free_source)119 if (free_source)
104 SDL_FreeSurface(srcsdl);120 SDL_FreeSurface(srcsdl);
105121
106122
=== modified file 'src/wui/fieldaction.cc'
--- src/wui/fieldaction.cc 2014-03-07 19:12:24 +0000
+++ src/wui/fieldaction.cc 2014-03-18 19:28:13 +0000
@@ -23,6 +23,7 @@
23#include "economy/flag.h"23#include "economy/flag.h"
24#include "economy/road.h"24#include "economy/road.h"
25#include "graphic/graphic.h"25#include "graphic/graphic.h"
26#include "graphic/image_transformations.h"
26#include "i18n.h"27#include "i18n.h"
27#include "logic/attackable.h"28#include "logic/attackable.h"
28#include "logic/cmd_queue.h"29#include "logic/cmd_queue.h"
@@ -59,15 +60,16 @@
5960
60// The BuildGrid presents a selection of buildable buildings61// The BuildGrid presents a selection of buildable buildings
61struct BuildGrid : public UI::Icon_Grid {62struct BuildGrid : public UI::Icon_Grid {
62 BuildGrid63 BuildGrid(UI::Panel* parent,
63 (UI::Panel * parent,64 const RGBColor& player_color,
64 const Widelands::Tribe_Descr & tribe,65 const Widelands::Tribe_Descr& tribe,
65 int32_t x, int32_t y,66 int32_t x,
66 int32_t cols);67 int32_t y,
68 int32_t cols);
6769
68 boost::signals2::signal<void (Widelands::Building_Index::value_t)> buildclicked;70 boost::signals2::signal<void(Widelands::Building_Index::value_t)> buildclicked;
69 boost::signals2::signal<void (Widelands::Building_Index::value_t)> buildmouseout;71 boost::signals2::signal<void(Widelands::Building_Index::value_t)> buildmouseout;
70 boost::signals2::signal<void (Widelands::Building_Index::value_t)> buildmousein;72 boost::signals2::signal<void(Widelands::Building_Index::value_t)> buildmousein;
7173
72 void add(Widelands::Building_Index::value_t);74 void add(Widelands::Building_Index::value_t);
7375
@@ -77,26 +79,22 @@
77 void mouseinslot(int32_t idx);79 void mouseinslot(int32_t idx);
7880
79private:81private:
80 const Widelands::Tribe_Descr & m_tribe;82 const RGBColor player_color_;
83 const Widelands::Tribe_Descr& tribe_;
81};84};
8285
8386BuildGrid::BuildGrid(
84BuildGrid::BuildGrid87 UI::Panel* parent, const RGBColor& player_color, const Widelands::Tribe_Descr& tribe,
85 (UI::Panel * parent,88 int32_t x, int32_t y, int32_t cols) :
86 const Widelands::Tribe_Descr & tribe,89 UI::Icon_Grid(parent, x, y, BG_CELL_WIDTH, BG_CELL_HEIGHT, cols),
87 int32_t x, int32_t y,90 player_color_(player_color),
88 int32_t cols)91 tribe_(tribe)
89:
90 UI::Icon_Grid
91 (parent, x, y, BG_CELL_WIDTH, BG_CELL_HEIGHT, cols),
92 m_tribe(tribe)
93{92{
94 clicked.connect(boost::bind(&BuildGrid::clickslot, this, _1));93 clicked.connect(boost::bind(&BuildGrid::clickslot, this, _1));
95 mouseout.connect(boost::bind(&BuildGrid::mouseoutslot, this, _1));94 mouseout.connect(boost::bind(&BuildGrid::mouseoutslot, this, _1));
96 mousein.connect(boost::bind(&BuildGrid::mouseinslot, this, _1));95 mousein.connect(boost::bind(&BuildGrid::mouseinslot, this, _1));
97}96}
9897
99
100/*98/*
101===============99===============
102Add a new building to the list of buildable buildings100Add a new building to the list of buildable buildings
@@ -105,13 +103,18 @@
105void BuildGrid::add(Widelands::Building_Index::value_t id)103void BuildGrid::add(Widelands::Building_Index::value_t id)
106{104{
107 const Widelands::Building_Descr & descr =105 const Widelands::Building_Descr & descr =
108 *m_tribe.get_building_descr(Widelands::Building_Index(id));106 *tribe_.get_building_descr(Widelands::Building_Index(id));
107 const Image& anim_frame = g_gr->animations().get_animation(descr.get_animation("idle"))
108 .representative_image(player_color_);
109 const uint16_t image_w = anim_frame.width();
110 const uint16_t image_h = anim_frame.height();
111 double ratio = BUILDMENU_IMAGE_SIZE / std::max(image_w, image_h);
112 const Image* menu_image = ImageTransformations::resize(&anim_frame, image_w * ratio, image_h * ratio);
109 UI::Icon_Grid::add113 UI::Icon_Grid::add
110 (descr.name(), descr.get_buildicon(),114 (descr.name(), menu_image,
111 reinterpret_cast<void *>(id),115 reinterpret_cast<void *>(id),
112 descr.descname() + "<br><font size=11>" + _("Construction costs:") + "</font><br>" +116 descr.descname() + "<br><font size=11>" + _("Construction costs:") + "</font><br>" +
113 waremap_to_richtext(m_tribe, descr.buildcost()));117 waremap_to_richtext(tribe_, descr.buildcost()));
114;
115}118}
116119
117120
@@ -181,7 +184,7 @@
181184
182 void init();185 void init();
183 void add_buttons_auto();186 void add_buttons_auto();
184 void add_buttons_build(int32_t buildcaps);187 void add_buttons_build(int32_t buildcaps, const RGBColor& player_color);
185 void add_buttons_road(bool flag);188 void add_buttons_road(bool flag);
186 void add_buttons_attack();189 void add_buttons_attack();
187190
@@ -396,11 +399,11 @@
396 const int32_t buildcaps = m_plr ? m_plr->get_buildcaps(m_node) : 0;399 const int32_t buildcaps = m_plr ? m_plr->get_buildcaps(m_node) : 0;
397400
398 // Add house building401 // Add house building
399 if402 if ((buildcaps & Widelands::BUILDCAPS_SIZEMASK) ||
400 ((buildcaps & Widelands::BUILDCAPS_SIZEMASK)403 (buildcaps & Widelands::BUILDCAPS_MINE)) {
401 ||404 assert(igbase->get_player());
402 (buildcaps & Widelands::BUILDCAPS_MINE))405 add_buttons_build(buildcaps, igbase->get_player()->get_playercolor());
403 add_buttons_build(buildcaps);406 }
404407
405 // Add build actions408 // Add build actions
406 if ((m_fastclick = buildcaps & Widelands::BUILDCAPS_FLAG))409 if ((m_fastclick = buildcaps & Widelands::BUILDCAPS_FLAG))
@@ -508,7 +511,7 @@
508Add buttons for house building.511Add buttons for house building.
509===============512===============
510*/513*/
511void FieldActionWindow::add_buttons_build(int32_t buildcaps)514void FieldActionWindow::add_buttons_build(int32_t buildcaps, const RGBColor& player_color)
512{515{
513 if (not m_plr)516 if (not m_plr)
514 return;517 return;
@@ -558,7 +561,7 @@
558561
559 // Allocate the tab's grid if necessary562 // Allocate the tab's grid if necessary
560 if (!*ppgrid) {563 if (!*ppgrid) {
561 *ppgrid = new BuildGrid(&m_tabpanel, tribe, 0, 0, 5);564 *ppgrid = new BuildGrid(&m_tabpanel, player_color, tribe, 0, 0, 5);
562 (*ppgrid)->buildclicked.connect(boost::bind(&FieldActionWindow::act_build, this, _1));565 (*ppgrid)->buildclicked.connect(boost::bind(&FieldActionWindow::act_build, this, _1));
563 (*ppgrid)->buildmouseout.connect566 (*ppgrid)->buildmouseout.connect
564 (boost::bind(&FieldActionWindow::building_icon_mouse_out, this, _1));567 (boost::bind(&FieldActionWindow::building_icon_mouse_out, this, _1));

Subscribers

People subscribed via source and target branches

to status/vote changes: