optimize the drawing loop, apply patch #1952 by VIR

This commit is contained in:
Jérémy Rosen 2010-09-12 13:17:10 +00:00
parent 02c1e610c4
commit 29fe502d8a
8 changed files with 239 additions and 202 deletions

View file

@ -115,6 +115,8 @@ Version 1.9.0+svn:
the objectives are viewed several times.
* Replace "working peasant" (indicating missing images in debug mode) by
half-transparent "Image not found"
* Improved rendering algorithm: reduced memory requirements and a much faster
render loop; very noticable on big maps
Version 1.9.0:
* AI:

View file

@ -162,6 +162,10 @@
name = "Martin Renold (maxy/martinxyz)"
comment = "performance and gui bug fixes"
[/entry]
[entry]
name = "Matthias Kretz"
comment = "optimizations"
[/entry]
[entry]
name = "Moritz Göbelbecker (mog)"
comment = "Work on the terrain engine"

View file

@ -804,28 +804,41 @@ std::vector<surface> display::get_terrain_images(const map_location &loc,
}
void display::drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, const tblit& blit)
const map_location& loc, int x, int y, const surface surf,
const SDL_Rect &clip)
{
tdrawing_layergroup group;
// find in which group the layer belongs
// FIXME: temporary method. Group splitting should be made
// public into the definition of tdrawing_layer
if(layer < LAYER_UNIT_FIRST) {
group = LAYERGROUP_TERRAIN_BG;
} else if(layer < LAYER_UNIT_MOVE_DEFAULT) {
group = LAYERGROUP_UNIT;
} else if(layer < LAYER_REACHMAP) {
group = LAYERGROUP_UNIT_MOVE;
} else {
group = LAYERGROUP_UI;
}
drawing_buffer_[group][loc][layer].push_back(blit);
drawing_buffer_.push_back(tblit(layer, loc, x, y, surf, clip));
}
void display::drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, int x, int y,
const std::vector<surface> &surf,
const SDL_Rect &clip)
{
drawing_buffer_.push_back(tblit(layer, loc, x, y, surf, clip));
}
// FIXME: temporary method. Group splitting should be made
// public into the definition of tdrawing_layer
//
// The drawing is done per layer_group, the range per group is [low, high).
const display::tdrawing_layer display::drawing_buffer_key::layer_groups[] = {
LAYER_TERRAIN_BG,
LAYER_UNIT_FIRST,
LAYER_UNIT_MOVE_DEFAULT,
// Make sure the movement doesn't show above fog and reachmap.
LAYER_REACHMAP,
LAYER_LAST_LAYER
};
// no need to change this if layer_groups above is changed
const unsigned int display::drawing_buffer_key::max_layer_group = sizeof(display::drawing_buffer_key::layer_groups) / sizeof(display::tdrawing_layer) - 2;
void display::drawing_buffer_commit()
{
// std::list::sort() is a stable sort
drawing_buffer_.sort();
SDL_Rect clip_rect = map_area();
const surface screen = get_screen_surface();
clip_rect_setter set_clip_rect(screen, &clip_rect);
@ -841,35 +854,21 @@ void display::drawing_buffer_commit()
*
* This ended in the following priority order:
* layergroup > location > layer > 'tblit' > surface
*/
foreach(const tgroup_map::value_type& group, drawing_buffer_) {
foreach(const tlocation_map::value_type& loc, group.second) {
foreach(const tlayer_map::value_type& layer, loc.second) {
foreach(const tblit& blit, layer.second) {
foreach(const surface& surf, blit.surf) {
// Note that dstrect can be changed by SDL_BlitSurface
// and so a new instance should be initialized
// to pass to each call to SDL_BlitSurface.
SDL_Rect dstrect = create_rect(blit.x, blit.y, 0, 0);
if(blit.clip.x || blit.clip.y
||blit.clip.w ||blit.clip.h) {
SDL_Rect srcrect = blit.clip;
SDL_BlitSurface(surf,
&srcrect, screen, &dstrect);
} else {
SDL_BlitSurface(surf,
NULL, screen, &dstrect);
}
} //for surf
update_rect(blit.x, blit.y, zoom_, zoom_);
} // for blit
} //for layer
} //for loc
} //for group
*/
foreach(const tblit &blit, drawing_buffer_) {
foreach(const surface& surf, blit.surf()) {
// Note that dstrect can be changed by SDL_BlitSurface
// and so a new instance should be initialized
// to pass to each call to SDL_BlitSurface.
SDL_Rect dstrect = create_rect(blit.x(), blit.y(), 0, 0);
SDL_Rect srcrect = blit.clip();
SDL_Rect *srcrectArg = (srcrect.x | srcrect.y | srcrect.w | srcrect.h)
? &srcrect : NULL;
SDL_BlitSurface(surf, srcrectArg, screen, &dstrect);
}
update_rect(blit.x(), blit.y(), zoom_, zoom_);
}
drawing_buffer_clear();
}
@ -1118,11 +1117,11 @@ void display::draw_text_in_hex(const map_location& loc,
for (int dy=-1; dy <= 1; ++dy) {
for (int dx=-1; dx <= 1; ++dx) {
if (dx!=0 || dy!=0) {
drawing_buffer_add(layer, loc, tblit(x + dx, y + dy, back_surf));
drawing_buffer_add(layer, loc, x + dx, y + dy, back_surf);
}
}
}
drawing_buffer_add(layer, loc, tblit(x, y, text_surf));
drawing_buffer_add(layer, loc, x, y, text_surf);
}
void display::render_image(int x, int y, const display::tdrawing_layer drawing_layer,
@ -1172,7 +1171,7 @@ void display::render_image(int x, int y, const display::tdrawing_layer drawing_l
// divide the surface into 2 parts
const int submerge_height = std::max<int>(0, surf->h*(1.0-submerged));
SDL_Rect srcrect = create_rect(0, 0, surf->w, submerge_height);
drawing_buffer_add(drawing_layer, loc, tblit(x, y, surf, srcrect));
drawing_buffer_add(drawing_layer, loc, x, y, surf, srcrect);
if(submerge_height != surf->h) {
//the lower part will be transparent
@ -1182,11 +1181,11 @@ void display::render_image(int x, int y, const display::tdrawing_layer drawing_l
srcrect.h = surf->h-submerge_height;
y += submerge_height;
drawing_buffer_add(drawing_layer, loc, tblit(x, y, surf, srcrect));
drawing_buffer_add(drawing_layer, loc, x, y, surf, srcrect);
}
} else {
// simple blit
drawing_buffer_add(drawing_layer, loc, tblit(x, y, surf));
drawing_buffer_add(drawing_layer, loc, x, y, surf);
}
}
@ -1366,55 +1365,55 @@ void display::draw_border(const map_location& loc, const int xpos, const int ypo
// First handle the corners :
if(loc.x == -1 && loc.y == -1) { // top left corner
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos + zoom_/4, ypos,
image::get_image(theme_.border().corner_image_top_left, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos + zoom_/4, ypos,
image::get_image(theme_.border().corner_image_top_left, image::SCALED_TO_ZOOM));
} else if(loc.x == get_map().w() && loc.y == -1) { // top right corner
// We use the map idea of odd and even, and map coords are internal coords + 1
if(loc.x%2 == 0) {
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos, ypos + zoom_/2,
image::get_image(theme_.border().corner_image_top_right_odd, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos + zoom_/2,
image::get_image(theme_.border().corner_image_top_right_odd, image::SCALED_TO_ZOOM));
} else {
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos, ypos,
image::get_image(theme_.border().corner_image_top_right_even, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_image(theme_.border().corner_image_top_right_even, image::SCALED_TO_ZOOM));
}
} else if(loc.x == -1 && loc.y == get_map().h()) { // bottom left corner
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos + zoom_/4, ypos,
image::get_image(theme_.border().corner_image_bottom_left, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos + zoom_/4, ypos,
image::get_image(theme_.border().corner_image_bottom_left, image::SCALED_TO_ZOOM));
} else if(loc.x == get_map().w() && loc.y == get_map().h()) { // bottom right corner
// We use the map idea of odd and even, and map coords are internal coords + 1
if(loc.x%2 == 1) {
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos, ypos,
image::get_image(theme_.border().corner_image_bottom_right_even, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_image(theme_.border().corner_image_bottom_right_even, image::SCALED_TO_ZOOM));
} else {
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos, ypos,
image::get_image(theme_.border().corner_image_bottom_right_odd, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_image(theme_.border().corner_image_bottom_right_odd, image::SCALED_TO_ZOOM));
}
// Now handle the sides:
} else if(loc.x == -1) { // left side
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos + zoom_/4, ypos,
image::get_image(theme_.border().border_image_left, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos + zoom_/4, ypos,
image::get_image(theme_.border().border_image_left, image::SCALED_TO_ZOOM));
} else if(loc.x == get_map().w()) { // right side
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos + zoom_/4, ypos,
image::get_image(theme_.border().border_image_right, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos + zoom_/4, ypos,
image::get_image(theme_.border().border_image_right, image::SCALED_TO_ZOOM));
} else if(loc.y == -1) { // top side
// We use the map idea of odd and even, and map coords are internal coords + 1
if(loc.x%2 == 1) {
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos, ypos,
image::get_image(theme_.border().border_image_top_even, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_image(theme_.border().border_image_top_even, image::SCALED_TO_ZOOM));
} else {
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos, ypos + zoom_/2,
image::get_image(theme_.border().border_image_top_odd, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos + zoom_/2,
image::get_image(theme_.border().border_image_top_odd, image::SCALED_TO_ZOOM));
}
} else if(loc.y == get_map().h()) { // bottom side
// We use the map idea of odd and even, and map coords are internal coords + 1
if(loc.x%2 == 1) {
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos, ypos,
image::get_image(theme_.border().border_image_bottom_even, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_image(theme_.border().border_image_bottom_even, image::SCALED_TO_ZOOM));
} else {
drawing_buffer_add(LAYER_BORDER, loc, tblit(xpos, ypos + zoom_/2,
image::get_image(theme_.border().border_image_bottom_odd, image::SCALED_TO_ZOOM)));
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos + zoom_/2,
image::get_image(theme_.border().border_image_bottom_odd, image::SCALED_TO_ZOOM));
}
}
}
@ -2039,20 +2038,20 @@ void display::draw_hex(const map_location& loc) {
const time_of_day& tod = get_time_of_day(loc);
if(!shrouded(loc)) {
// unshrouded terrain (the normal case)
drawing_buffer_add(LAYER_TERRAIN_BG, loc, tblit(xpos, ypos,
get_terrain_images(loc,tod.id, image_type, BACKGROUND)));
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos,
get_terrain_images(loc,tod.id, image_type, BACKGROUND));
drawing_buffer_add(LAYER_TERRAIN_FG, loc, tblit(xpos, ypos,
get_terrain_images(loc,tod.id,image_type, FOREGROUND)));
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos,
get_terrain_images(loc,tod.id,image_type, FOREGROUND));
// Draw the grid, if that's been enabled
if(grid_ && on_map && !off_map_tile) {
static const image::locator grid_top(game_config::images::grid_top);
drawing_buffer_add(LAYER_GRID_TOP, loc, tblit(xpos, ypos,
image::get_image(grid_top, image::TOD_COLORED)));
drawing_buffer_add(LAYER_GRID_TOP, loc, xpos, ypos,
image::get_image(grid_top, image::TOD_COLORED));
static const image::locator grid_bottom(game_config::images::grid_bottom);
drawing_buffer_add(LAYER_GRID_BOTTOM, loc, tblit(xpos, ypos,
image::get_image(grid_bottom, image::TOD_COLORED)));
drawing_buffer_add(LAYER_GRID_BOTTOM, loc, xpos, ypos,
image::get_image(grid_bottom, image::TOD_COLORED));
}
}
@ -2060,16 +2059,16 @@ void display::draw_hex(const map_location& loc) {
// tod may differ from tod if hex is illuminated.
const std::string& tod_hex_mask = tod.image_mask;
if(tod_hex_mask1 != NULL || tod_hex_mask2 != NULL) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, tblit(xpos, ypos, tod_hex_mask1));
drawing_buffer_add(LAYER_TERRAIN_FG, loc, tblit(xpos, ypos, tod_hex_mask2));
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask1);
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask2);
} else if(!tod_hex_mask.empty()) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, tblit(xpos, ypos,
image::get_image(tod_hex_mask,image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos,
image::get_image(tod_hex_mask,image::SCALED_TO_HEX));
}
// Paint mouseover overlays
if(loc == mouseoverHex_ && (on_map || (in_editor() && get_map().on_board_with_border(loc))) && mouseover_hex_overlay_ != NULL) {
drawing_buffer_add(LAYER_MOUSEOVER_OVERLAY, loc, tblit(xpos, ypos, mouseover_hex_overlay_));
drawing_buffer_add(LAYER_MOUSEOVER_OVERLAY, loc, xpos, ypos, mouseover_hex_overlay_);
}
// Paint arrows
@ -2085,23 +2084,23 @@ void display::draw_hex(const map_location& loc) {
// We apply void also on off-map tiles
// to shroud the half-hexes too
const std::string& shroud_image = get_variant(shroud_images_, loc);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, tblit(xpos, ypos,
image::get_image(shroud_image, image_type)));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image(shroud_image, image_type));
} else if(fogged(loc)) {
const std::string& fog_image = get_variant(fog_images_, loc);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, tblit(xpos, ypos,
image::get_image(fog_image, image_type)));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image(fog_image, image_type));
}
if(!shrouded(loc)) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, tblit(xpos, ypos, get_fog_shroud_images(loc, image_type)));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos, get_fog_shroud_images(loc, image_type));
}
if(on_map && loc == mouseoverHex_) {
drawing_buffer_add(LAYER_MOUSEOVER_TOP,
loc, tblit(xpos, ypos, image::get_image("misc/hover-hex-top.png", image::SCALED_TO_HEX)));
loc, xpos, ypos, image::get_image("misc/hover-hex-top.png", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM,
loc, tblit(xpos, ypos, image::get_image("misc/hover-hex-bottom.png", image::SCALED_TO_HEX)));
loc, xpos, ypos, image::get_image("misc/hover-hex-bottom.png", image::SCALED_TO_HEX));
}
if (on_map) {
@ -2118,8 +2117,8 @@ void display::draw_hex(const map_location& loc) {
} else {
off_y -= text->h / 2;
}
drawing_buffer_add(LAYER_FOG_SHROUD, loc, tblit(off_x, off_y, bg));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, tblit(off_x, off_y, text));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, text);
}
if (draw_terrain_codes_ && (game_config::debug || !shrouded(loc))) {
int off_x = xpos + hex_size()/2;
@ -2132,14 +2131,14 @@ void display::draw_hex(const map_location& loc) {
if (!draw_coordinates_) {
off_y -= text->h / 2;
}
drawing_buffer_add(LAYER_FOG_SHROUD, loc, tblit(off_x, off_y, bg));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, tblit(off_x, off_y, text));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, text);
}
}
if(debug_foreground) {
drawing_buffer_add(LAYER_UNIT_DEFAULT, loc, tblit(xpos, ypos,
image::get_image("terrain/foreground.png", image_type)));
drawing_buffer_add(LAYER_UNIT_DEFAULT, loc, xpos, ypos,
image::get_image("terrain/foreground.png", image_type));
}
}

View file

@ -608,41 +608,6 @@ protected:
bool local_tod_light_;
public:
/** Helper structure for rendering the terrains. */
struct tblit{
tblit(const int x, const int y) :
x(x),
y(y),
surf(),
clip()
{}
tblit(const int x, const int y, const surface& surf,
const SDL_Rect& clip = SDL_Rect()) :
x(x),
y(y),
surf(1, surf),
clip(clip)
{}
tblit(const int x, const int y, const std::vector<surface>& surf,
const SDL_Rect& clip = SDL_Rect()) :
x(x),
y(y),
surf(surf),
clip(clip)
{}
int x; /**< x screen coordinate to render at. */
int y; /**< y screen coordinate to render at. */
std::vector<surface> surf; /**< surface(s) to render. */
SDL_Rect clip; /**<
* The clipping area of the source if
* ommitted the entire source is used.
*/
};
/**
* The layers to render something on. This value should never be stored
* it's the internal drawing order and adding removing and reordering
@ -725,38 +690,102 @@ public:
protected:
/**
* Compare functor for the blitting.
* In order to render a hex properly it needs to be rendered per row. On
* this row several layers need to be drawn at the same time. Mainly the
* unit and the background terrain. This is needed since both can spill
* in the next hex. The foreground terrain needs to be drawn before to
* avoid decapitation a unit.
*
* The blitting order must be sorted on y value first instead of x so added
* another functor since map_location::operator< sorts on x value.
* In other words:
* for every layer
* for every row (starting from the top)
* for every hex in the row
* ...
*
* this is modified to:
* for every layer group
* for every row (starting from the top)
* for every layer in the group
* for every hex in the row
* ...
*
* * Surfaces are rendered per level in a map.
* * Per level the items are rendered per location these locations are
* stored in the drawing order required for units.
* * every location has a vector with surfaces, each with its own screen
* coordinate to render at.
* * every vector element has a vector with surfaces to render.
*/
struct draw_order
class drawing_buffer_key
{
bool operator()(const map_location& lhs, const map_location& rhs) const
private:
// store x, y, and layer in one 32 bit integer
// 4 most significant bits == layer group => 16
// 10 second most significant bits == y => 1024
// 8 third most significant bits == layer => 256
// 10 least significant bits == x => 1024
unsigned int key_;
static const tdrawing_layer layer_groups[];
static const unsigned int max_layer_group;
enum {
MaxBorder = 3
};
public:
drawing_buffer_key(const map_location &loc, tdrawing_layer layer)
{
// use similar y transformation as for on-screen coordinates
int ly = lhs.y*2 + lhs.x%2;
int ry = rhs.y*2 + rhs.x%2;
return ly < ry || (ly == ry && lhs.x < rhs.x);
// max_layer_group + 1 is the last valid entry in layer_groups, but it is always > layer
// thus the first --g is a given => start with max_layer_groups right away
unsigned int g = max_layer_group;
while (layer < layer_groups[g]) {
--g;
}
key_ = (g << 28) | (static_cast<unsigned int>(loc.y + MaxBorder) << 18);
key_ |= (static_cast<unsigned int>(layer) << 10) | static_cast<unsigned int>(loc.x + MaxBorder);
}
bool operator<(const drawing_buffer_key &rhs) const { return key_ < rhs.key_; }
};
/**
* Group of layers:
* layers of a group will always be rendered under layers of the next group
* regardless of the location
*/
enum tdrawing_layergroup{
LAYERGROUP_TERRAIN_BG,
LAYERGROUP_UNIT,
LAYERGROUP_UNIT_MOVE,
LAYERGROUP_UI
/** Helper structure for rendering the terrains. */
class tblit
{
public:
tblit(const tdrawing_layer layer, const map_location& loc,
const int x, const int y, const surface surf,
const SDL_Rect& clip)
: x_(x), y_(y), surf_(1, surf), clip_(clip),
key_(loc, layer)
{}
tblit(const tdrawing_layer layer, const map_location& loc,
const int x, const int y, const std::vector<surface>& surf,
const SDL_Rect& clip)
: x_(x), y_(y), surf_(surf), clip_(clip),
key_(loc, layer)
{}
int x() const { return x_; }
int y() const { return y_; }
const std::vector<surface> &surf() const { return surf_; }
const SDL_Rect &clip() const { return clip_; }
bool operator<(const tblit &rhs) const { return key_ < rhs.key_; }
private:
int x_; /**< x screen coordinate to render at. */
int y_; /**< y screen coordinate to render at. */
std::vector<surface> surf_; /**< surface(s) to render. */
SDL_Rect clip_; /**<
* The clipping area of the source if
* ommitted the entire source is used.
*/
drawing_buffer_key key_;
};
typedef std::map<tdrawing_layer, std::vector<tblit> > tlayer_map;
typedef std::map<map_location, tlayer_map, draw_order > tlocation_map;
typedef std::map<tdrawing_layergroup, tlocation_map> tgroup_map;
tgroup_map drawing_buffer_;
typedef std::list<tblit> tdrawing_buffer;
tdrawing_buffer drawing_buffer_;
public:
@ -769,7 +798,13 @@ public:
* @param blit The structure to blit.
*/
void drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, const tblit& blit);
const map_location& loc, int x, int y, const surface surf,
const SDL_Rect &clip = SDL_Rect());
void drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, int x, int y,
const std::vector<surface> &surf,
const SDL_Rect &clip = SDL_Rect());
protected:

View file

@ -75,18 +75,17 @@ void editor_display::draw_hex(const map_location& loc)
{
int xpos = get_location_x(loc);
int ypos = get_location_y(loc);
tblit blit(xpos, ypos);
display::draw_hex(loc);
if (map().on_board_with_border(loc)) {
if (map().in_selection(loc)) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, tblit(xpos, ypos,
image::get_image("editor/selection-overlay.png", image::TOD_COLORED)));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image("editor/selection-overlay.png", image::TOD_COLORED));
}
if (brush_locations_.find(loc) != brush_locations_.end()) {
static const image::locator brush(game_config::images::editor_brush);
drawing_buffer_add(LAYER_MOUSEOVER_OVERLAY, loc, tblit(xpos, ypos,
image::get_image(brush, image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_MOUSEOVER_OVERLAY, loc, xpos, ypos,
image::get_image(brush, image::SCALED_TO_HEX));
}
}
}

View file

@ -335,9 +335,8 @@ void game_display::draw_hex(const map_location& loc)
const bool on_map = get_map().on_board(loc);
const bool is_shrouded = shrouded(loc);
const bool is_fogged = fogged(loc);
int xpos = get_location_x(loc);
int ypos = get_location_y(loc);
tblit blit(xpos, ypos);
const int xpos = get_location_x(loc);
const int ypos = get_location_y(loc);
image::TYPE image_type = get_image_type(loc);
@ -351,12 +350,12 @@ void game_display::draw_hex(const map_location& loc)
overlays.first->second.team_name.find(teams_[playing_team()].team_name()) != std::string::npos)
&& !(is_fogged && !overlays.first->second.visible_in_fog))
{
drawing_buffer_add(LAYER_TERRAIN_BG, loc, tblit(xpos, ypos,
image::get_image(overlays.first->second.image,image_type)));
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos,
image::get_image(overlays.first->second.image,image_type));
}
}
// village-control flags.
drawing_buffer_add(LAYER_TERRAIN_BG, loc, tblit(xpos, ypos, get_flag(loc)));
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, get_flag(loc));
}
// Draw reach_map information.
@ -365,8 +364,8 @@ void game_display::draw_hex(const map_location& loc)
if (!is_shrouded && !reach_map_.empty()
&& reach_map_.find(loc) == reach_map_.end() && loc != attack_indicator_dst_) {
static const image::locator unreachable(game_config::images::unreachable);
drawing_buffer_add(LAYER_REACHMAP, loc, tblit(xpos, ypos,
image::get_image(unreachable,image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_REACHMAP, loc, xpos, ypos,
image::get_image(unreachable,image::SCALED_TO_HEX));
}
resources::whiteboard->draw_hex(loc);
@ -376,31 +375,30 @@ void game_display::draw_hex(const map_location& loc)
// Footsteps indicating a movement path
const std::vector<surface>& footstepImages = footsteps_images(loc);
if (footstepImages.size() != 0) {
drawing_buffer_add(LAYER_FOOTSTEPS, loc, tblit(xpos, ypos, footstepImages));
drawing_buffer_add(LAYER_FOOTSTEPS, loc, xpos, ypos, footstepImages);
}
}
// Draw the attack direction indicator
if(on_map && loc == attack_indicator_src_) {
drawing_buffer_add(LAYER_ATTACK_INDICATOR, loc, tblit(xpos, ypos,
image::get_image("misc/attack-indicator-src-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_ATTACK_INDICATOR, loc, xpos, ypos,
image::get_image("misc/attack-indicator-src-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX));
} else if (on_map && loc == attack_indicator_dst_) {
drawing_buffer_add(LAYER_ATTACK_INDICATOR, loc, tblit(xpos, ypos,
image::get_image("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_ATTACK_INDICATOR, loc, xpos, ypos,
image::get_image("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX));
}
// Linger overlay unconditionally otherwise it might give glitches
// so it's drawn over the shroud and fog.
if(game_mode_ != RUNNING) {
static const image::locator linger(game_config::images::linger);
blit.surf.push_back(image::get_image(linger, image::TOD_COLORED));
drawing_buffer_add(LAYER_LINGER_OVERLAY, loc, blit);
blit.surf.clear();
drawing_buffer_add(LAYER_LINGER_OVERLAY, loc, xpos, ypos,
image::get_image(linger, image::TOD_COLORED));
}
if(on_map && loc == selectedHex_ && !game_config::images::selected.empty()) {
static const image::locator selected(game_config::images::selected);
drawing_buffer_add(LAYER_SELECTED_HEX, loc, tblit(xpos, ypos,
image::get_image(selected, image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_SELECTED_HEX, loc, xpos, ypos,
image::get_image(selected, image::SCALED_TO_HEX));
}
// Show def% and turn to reach infos
@ -567,8 +565,8 @@ void game_display::draw_bar(const std::string& image, int xpos, int ypos,
SDL_Rect bot = create_rect(0, bar_loc.y + skip_rows, surf->w, 0);
bot.h = surf->w - bot.y;
drawing_buffer_add(LAYER_UNIT_BAR, loc, tblit(xpos, ypos, surf, top));
drawing_buffer_add(LAYER_UNIT_BAR, loc, tblit(xpos, ypos + top.h, surf, bot));
drawing_buffer_add(LAYER_UNIT_BAR, loc, xpos, ypos, surf, top);
drawing_buffer_add(LAYER_UNIT_BAR, loc, xpos, ypos + top.h, surf, bot);
size_t unfilled = static_cast<size_t>(height * (1.0 - filled));
@ -577,7 +575,7 @@ void game_display::draw_bar(const std::string& image, int xpos, int ypos,
surface filled_surf = create_compatible_surface(bar_surf, bar_loc.w, height - unfilled);
SDL_Rect filled_area = create_rect(0, 0, bar_loc.w, height-unfilled);
SDL_FillRect(filled_surf,&filled_area,SDL_MapRGBA(bar_surf->format,col.r,col.g,col.b, r_alpha));
drawing_buffer_add(LAYER_UNIT_BAR, loc, tblit(xpos + bar_loc.x, ypos + bar_loc.y + unfilled, filled_surf));
drawing_buffer_add(LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, filled_surf);
}
}
@ -614,23 +612,23 @@ void game_display::draw_movement_info(const map_location& loc)
int ypos = get_location_y(loc);
if (w->second.invisible) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, tblit(xpos, ypos,
image::get_image("misc/hidden.png", image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_image("misc/hidden.png", image::SCALED_TO_HEX));
}
if (w->second.zoc) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, tblit(xpos, ypos,
image::get_image("misc/zoc.png", image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_image("misc/zoc.png", image::SCALED_TO_HEX));
}
if (w->second.capture) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, tblit(xpos, ypos,
image::get_image("misc/capture.png", image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_image("misc/capture.png", image::SCALED_TO_HEX));
}
if (w->second.pass_here) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, tblit(xpos, ypos,
image::get_image("misc/waypoint.png", image::SCALED_TO_HEX)));
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_image("misc/waypoint.png", image::SCALED_TO_HEX));
}
//we display turn info only if different from a simple last "1"

View file

@ -1891,13 +1891,13 @@ void unit::redraw_unit()
if (ellipse_back != NULL) {
//disp.drawing_buffer_add(display::LAYER_UNIT_BG, loc,
disp.drawing_buffer_add(display::LAYER_UNIT_FIRST, loc_,
display::tblit(xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_back));
xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_back);
}
if (ellipse_front != NULL) {
//disp.drawing_buffer_add(display::LAYER_UNIT_FG, loc,
disp.drawing_buffer_add(display::LAYER_UNIT_FIRST, loc_,
display::tblit(xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_front));
xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_front);
}
if(draw_bars) {
const image::locator* orb_img = NULL;
@ -1930,7 +1930,7 @@ void unit::redraw_unit()
surface orb(image::get_image(*orb_img,image::SCALED_TO_ZOOM));
if (orb != NULL) {
disp.drawing_buffer_add(display::LAYER_UNIT_BAR,
loc_, display::tblit(xsrc, ysrc +adjusted_params.y, orb));
loc_, xsrc, ysrc +adjusted_params.y, orb);
}
double unit_energy = 0.0;
@ -1966,7 +1966,7 @@ void unit::redraw_unit()
// crown = adjust_surface_alpha(crown, bar_alpha);
//}
disp.drawing_buffer_add(display::LAYER_UNIT_BAR,
loc_, display::tblit(xsrc, ysrc +adjusted_params.y, crown));
loc_, xsrc, ysrc +adjusted_params.y, crown);
}
}
@ -1974,7 +1974,7 @@ void unit::redraw_unit()
const surface ov_img(image::get_image(*ov, image::SCALED_TO_ZOOM));
if(ov_img != NULL) {
disp.drawing_buffer_add(display::LAYER_UNIT_BAR,
loc_, display::tblit(xsrc, ysrc +adjusted_params.y, ov_img));
loc_, xsrc, ysrc +adjusted_params.y, ov_img);
}
}
}

View file

@ -160,16 +160,16 @@ void attack::draw_hex(const map_location& hex)
int xpos = resources::screen->get_location_x(get_dest_hex());
int ypos = resources::screen->get_location_y(get_dest_hex());
resources::screen->drawing_buffer_add(layer, get_dest_hex(), display::tblit(xpos, ypos,
image::get_image("whiteboard/attack-indicator-src-" + direction_text + ".png", image::SCALED_TO_HEX)));
resources::screen->drawing_buffer_add(layer, get_dest_hex(), xpos, ypos,
image::get_image("whiteboard/attack-indicator-src-" + direction_text + ".png", image::SCALED_TO_HEX));
}
else if (hex == target_hex_) //add symbol to defender hex
{
int xpos = resources::screen->get_location_x(target_hex_);
int ypos = resources::screen->get_location_y(target_hex_);
resources::screen->drawing_buffer_add(layer, target_hex_, display::tblit(xpos, ypos,
image::get_image("whiteboard/attack-indicator-dst-" + direction_text + ".png", image::SCALED_TO_HEX)));
resources::screen->drawing_buffer_add(layer, target_hex_, xpos, ypos,
image::get_image("whiteboard/attack-indicator-dst-" + direction_text + ".png", image::SCALED_TO_HEX));
}
}
}