Decoupled drawing buffer code from display class

This commit is contained in:
Charles Dang 2017-06-11 09:06:50 +11:00
parent e30a2aa520
commit 8dc661db40
19 changed files with 467 additions and 298 deletions

View file

@ -263,6 +263,8 @@
<Unit filename="../../src/display_chat_manager.hpp" />
<Unit filename="../../src/display_context.cpp" />
<Unit filename="../../src/display_context.hpp" />
<Unit filename="../../src/drawing_buffer.cpp" />
<Unit filename="../../src/drawing_buffer.hpp" />
<Unit filename="../../src/editor/action/action.cpp" />
<Unit filename="../../src/editor/action/action.hpp" />
<Unit filename="../../src/editor/action/action_base.hpp" />

View file

@ -4,6 +4,7 @@ desktop/clipboard.cpp
deprecation.cpp
display.cpp
display_context.cpp
drawing_buffer.cpp
events.cpp
floating_label.cpp
font/font_config.cpp

View file

@ -29,7 +29,7 @@ static lg::log_domain log_arrows("arrows");
#define DBG_ARR LOG_STREAM(debug, log_arrows)
arrow::arrow(bool hidden)
: layer_(display::LAYER_ARROWS)
: layer_(drawing_buffer::LAYER_ARROWS)
, color_("red")
, style_(STYLE_STANDARD)
, path_()

View file

@ -90,7 +90,7 @@ protected:
*/
virtual void update_symbols();
display::drawing_layer layer_;
drawing_buffer::drawing_layer layer_;
std::string color_;
/// represents the subdirectory that holds images for this arrow style

View file

@ -58,10 +58,6 @@
#include <iomanip>
#include <utility>
#ifdef _WIN32
#include <windows.h>
#endif
// Includes for bug #17573
static lg::log_domain log_display("display");
@ -186,7 +182,7 @@ display::display(const display_context * dc, std::weak_ptr<wb::manager> wb, repo
reports_object_(&reports_object),
scroll_event_("scrolled"),
complete_redraw_event_("completely_redrawn"),
frametimes_(50),
nextDraw_(0),
fps_counter_(),
fps_start_(),
fps_actual_(),
@ -259,18 +255,10 @@ display::display(const display_context * dc, std::weak_ptr<wb::manager> wb, repo
create_buttons();
}
#ifdef _WIN32
// Increase timer resolution to prevent delays getting much longer than they should.
timeBeginPeriod(1u);
#endif
}
display::~display()
{
#ifdef _WIN32
timeEndPeriod(1u);
#endif
singleton_ = nullptr;
resources::fake_units = nullptr;
}
@ -1189,126 +1177,19 @@ void display::get_terrain_images(const map_location &loc,
}
}
void display::drawing_buffer_add(const drawing_layer layer,
void display::drawing_buffer_add(const drawing_buffer::drawing_layer layer,
const map_location& loc, int x, int y, const surface& surf,
const SDL_Rect &clip)
{
drawing_buffer_.emplace_back(layer, loc, x, y, surf, clip);
drawing_buffer_.add_item(layer, loc, x, y, surf, clip);
}
void display::drawing_buffer_add(const drawing_layer layer,
void display::drawing_buffer_add(const drawing_buffer::drawing_layer layer,
const map_location& loc, int x, int y,
const std::vector<surface> &surf,
const SDL_Rect &clip)
{
drawing_buffer_.emplace_back(layer, loc, x, y, surf, clip);
}
// FIXME: temporary method. Group splitting should be made
// public into the definition of drawing_layer
//
// The drawing is done per layer_group, the range per group is [low, high).
const std::array<display::drawing_layer, 4> 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
}};
enum {
// you may adjust the following when needed:
// maximum border. 3 should be safe even if a larger border is in use somewhere
MAX_BORDER = 3,
// store x, y, and layer in one 32 bit integer
// 4 most significant bits == layer group => 16
BITS_FOR_LAYER_GROUP = 4,
// 10 second most significant bits == y => 1024
BITS_FOR_Y = 10,
// 1 third most significant bit == x parity => 2
BITS_FOR_X_PARITY = 1,
// 8 fourth most significant bits == layer => 256
BITS_FOR_LAYER = 8,
// 9 least significant bits == x / 2 => 512 (really 1024 for x)
BITS_FOR_X_OVER_2 = 9
};
inline display::drawing_buffer_key::drawing_buffer_key(const map_location &loc, drawing_layer layer)
: key_(0)
{
// Start with the index of last group entry...
unsigned int group_i = layer_groups.size() - 1;
// ...and works backwards until the group containing the specified layer is found.
while(layer < layer_groups[group_i]) {
--group_i;
}
enum {
SHIFT_LAYER = BITS_FOR_X_OVER_2,
SHIFT_X_PARITY = BITS_FOR_LAYER + SHIFT_LAYER,
SHIFT_Y = BITS_FOR_X_PARITY + SHIFT_X_PARITY,
SHIFT_LAYER_GROUP = BITS_FOR_Y + SHIFT_Y
};
static_assert(SHIFT_LAYER_GROUP + BITS_FOR_LAYER_GROUP == sizeof(key_) * 8, "Bit field too small");
// the parity of x must be more significant than the layer but less significant than y.
// Thus basically every row is split in two: First the row containing all the odd x
// then the row containing all the even x. Since thus the least significant bit of x is
// not required for x ordering anymore it can be shifted out to the right.
const unsigned int x_parity = static_cast<unsigned int>(loc.x) & 1;
key_ = (group_i << SHIFT_LAYER_GROUP) | (static_cast<unsigned int>(loc.y + MAX_BORDER) << SHIFT_Y);
key_ |= (x_parity << SHIFT_X_PARITY);
key_ |= (static_cast<unsigned int>(layer) << SHIFT_LAYER) | static_cast<unsigned int>(loc.x + MAX_BORDER) / 2;
}
void display::drawing_buffer_commit()
{
// std::list::sort() is a stable sort
drawing_buffer_.sort();
SDL_Rect clip_rect = map_area();
surface& screen = get_screen_surface();
clip_rect_setter set_clip_rect(screen, &clip_rect);
/*
* Info regarding the rendering algorithm.
*
* 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.
*
* This ended in the following priority order:
* layergroup > location > layer > 'blit_helper' > surface
*/
for (const blit_helper &blit : drawing_buffer_) {
for (const surface& surf : blit.surf()) {
// Note that dstrect can be changed by sdl_blit
// and so a new instance should be initialized
// to pass to each call to sdl_blit.
SDL_Rect dstrect {blit.x(), blit.y(), 0, 0};
SDL_Rect srcrect = blit.clip();
SDL_Rect *srcrectArg = (srcrect.x | srcrect.y | srcrect.w | srcrect.h)
? &srcrect : nullptr;
sdl_blit(surf, srcrectArg, screen, &dstrect);
//NOTE: the screen part should already be marked as 'to update'
}
}
drawing_buffer_clear();
}
void display::drawing_buffer_clear()
{
drawing_buffer_.clear();
drawing_buffer_.add_item(layer, loc, x, y, surf, clip);
}
void display::toggle_benchmark()
@ -1504,7 +1385,7 @@ static void draw_background(surface screen, const SDL_Rect& area, const std::str
}
void display::draw_text_in_hex(const map_location& loc,
const drawing_layer layer, const std::string& text,
const drawing_buffer::drawing_layer layer, const std::string& text,
size_t font_size, color_t color, double x_in_hex, double y_in_hex)
{
if (text.empty()) return;
@ -1528,7 +1409,7 @@ void display::draw_text_in_hex(const map_location& loc,
}
//TODO: convert this to use sdl::ttexture
void display::render_image(int x, int y, const display::drawing_layer drawing_layer,
void display::render_image(int x, int y, const drawing_buffer::drawing_layer drawing_layer,
const map_location& loc, surface image,
bool hreverse, bool greyscale, fixed_t alpha,
color_t blendto, double blend_ratio, double submerged, bool vreverse)
@ -2488,7 +2369,7 @@ void display::draw(bool update,bool force) {
draw_invalidated();
invalidated_.clear();
}
drawing_buffer_commit();
drawing_buffer_.render_buffer();
post_commit();
draw_sidebar();
@ -2564,22 +2445,23 @@ void display::draw_hex(const map_location& loc) {
if(!shrouded(loc)) {
// unshrouded terrain (the normal case)
get_terrain_images(loc, tod.id, BACKGROUND); // updates terrain_image_vector_
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, terrain_image_vector_);
drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_BG, loc, xpos, ypos, terrain_image_vector_);
num_images_bg = terrain_image_vector_.size();
get_terrain_images(loc, tod.id, FOREGROUND); // updates terrain_image_vector_
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, terrain_image_vector_);
drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_FG, loc, xpos, ypos, terrain_image_vector_);
num_images_fg = terrain_image_vector_.size();
// Draw the grid, if that's been enabled
if(grid_) {
static const image::locator grid_top(game_config::images::grid_top);
drawing_buffer_add(LAYER_GRID_TOP, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::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, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_GRID_BOTTOM, loc, xpos, ypos,
image::get_image(grid_bottom, image::TOD_COLORED));
}
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, get_flag(loc));
}
if(!shrouded(loc)) {
@ -2600,7 +2482,7 @@ void display::draw_hex(const map_location& loc) {
const std::string image = overlays.first->second.image;
const surface surf = image.find("~NO_TOD_SHIFT()") == std::string::npos ?
image::get_lighted_image(image, lt, image::SCALED_TO_HEX) : image::get_image(image, image::SCALED_TO_HEX);
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, surf);
drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_BG, loc, xpos, ypos, surf);
}
}
}
@ -2615,17 +2497,17 @@ 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 != nullptr || tod_hex_mask2 != nullptr) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask1);
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask2);
drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask1);
drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask2);
} else if(!tod_hex_mask.empty()) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::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_ != nullptr) {
drawing_buffer_add(LAYER_MOUSEOVER_OVERLAY, loc, xpos, ypos, mouseover_hex_overlay_);
drawing_buffer_add(drawing_buffer::LAYER_MOUSEOVER_OVERLAY, loc, xpos, ypos, mouseover_hex_overlay_);
}
// Paint arrows
@ -2642,16 +2524,16 @@ 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, xpos, ypos,
drawing_buffer_add(drawing_buffer::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, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image(fog_image, image_type));
}
if(!shrouded(loc)) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos, get_fog_shroud_images(loc, image_type));
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, xpos, ypos, get_fog_shroud_images(loc, image_type));
}
if (on_map) {
@ -2670,8 +2552,8 @@ void display::draw_hex(const map_location& loc) {
if (draw_num_of_bitmaps_) {
off_y -= text->h / 2;
}
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, text);
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(drawing_buffer::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;
@ -2687,8 +2569,8 @@ void display::draw_hex(const map_location& loc) {
} else if (draw_num_of_bitmaps_ && !draw_coordinates_) {
off_y -= text->h / 2;
}
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, text);
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, off_x, off_y, text);
}
if (draw_num_of_bitmaps_) {
int off_x = xpos + hex_size()/2;
@ -2705,13 +2587,13 @@ void display::draw_hex(const map_location& loc) {
if (draw_terrain_codes_) {
off_y += text->h / 2;
}
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, text);
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, off_x, off_y, text);
}
}
if(debug_foreground) {
drawing_buffer_add(LAYER_UNIT_DEFAULT, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_UNIT_DEFAULT, loc, xpos, ypos,
image::get_image("terrain/foreground.png", image_type));
}

View file

@ -50,6 +50,7 @@ namespace wb {
#include "animated.hpp"
#include "display_context.hpp"
#include "drawing_buffer.hpp"
#include "font/standard_colors.hpp"
#include "image.hpp" //only needed for enums (!)
#include "key.hpp"
@ -687,7 +688,7 @@ protected:
virtual void draw_invalidated();
/**
* Hook for actions to take right after draw() calls drawing_buffer_commit
* Hook for actions to take right after draw() renders the drawing buffer.
* No action here by default.
*/
virtual void post_commit() {}
@ -862,7 +863,7 @@ public:
* submerged: the amount of the unit out of 1.0 that is submerged
* (presumably under water) and thus shouldn't be drawn
*/
void render_image(int x, int y, const display::drawing_layer drawing_layer,
void render_image(int x, int y, const drawing_buffer::drawing_layer drawing_layer,
const map_location& loc, surface image,
bool hreverse=false, bool greyscale=false,
fixed_t alpha=ftofxp(1.0), color_t blendto = {0,0,0},
@ -873,7 +874,7 @@ public:
* The font size is adjusted to the zoom factor.
*/
void draw_text_in_hex(const map_location& loc,
const drawing_layer layer, const std::string& text, size_t font_size,
const drawing_buffer::drawing_layer layer, const std::string& text, size_t font_size,
color_t color, double x_in_hex=0.5, double y_in_hex=0.5);
protected:
@ -881,87 +882,6 @@ protected:
//TODO sort
size_t activeTeam_;
/**
* 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.
*
* 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.
*/
class drawing_buffer_key
{
private:
unsigned int key_;
static const std::array<drawing_layer, 4> layer_groups;
public:
drawing_buffer_key(const map_location &loc, drawing_layer layer);
bool operator<(const drawing_buffer_key &rhs) const { return key_ < rhs.key_; }
};
/** Helper structure for rendering the terrains. */
class blit_helper
{
public:
// We don't want to copy this.
// It's expensive when done frequently due to the surface vector.
blit_helper(const blit_helper&) = delete;
blit_helper(const drawing_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)
{}
blit_helper(const drawing_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 blit_helper &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
* omitted the entire source is used.
*/
drawing_buffer_key key_;
};
typedef std::list<blit_helper> drawing_buffer;
drawing_buffer drawing_buffer_;
public:
@ -972,27 +892,19 @@ public:
* @param loc The hex the image belongs to, needed for the
* drawing order.
*/
void drawing_buffer_add(const drawing_layer layer,
void drawing_buffer_add(const drawing_buffer::drawing_layer layer,
const map_location& loc, int x, int y, const surface& surf,
const SDL_Rect &clip = SDL_Rect());
void drawing_buffer_add(const drawing_layer layer,
void drawing_buffer_add(const drawing_buffer::drawing_layer layer,
const map_location& loc, int x, int y,
const std::vector<surface> &surf,
const SDL_Rect &clip = SDL_Rect());
protected:
/** Draws the drawing_buffer_ and clears it. */
void drawing_buffer_commit();
/** Clears the drawing buffer. */
void drawing_buffer_clear();
/** redraw all panels associated with the map display */
void draw_all_panels();
/**
* Initiate a redraw.
*

127
src/drawing_buffer.cpp Normal file
View file

@ -0,0 +1,127 @@
/*
Copyright (C) 2003 - 2017 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "drawing_buffer.hpp"
#include "display.hpp"
#include "sdl/surface.hpp"
#include "video.hpp"
namespace
{
enum {
// You may adjust the following when needed:
// maximum border. 3 should be safe even if a larger border is in use somewhere
MAX_BORDER = 3,
// store x, y, and layer in one 32 bit integer
// 4 most significant bits == layer group => 16
BITS_FOR_LAYER_GROUP = 4,
// 10 second most significant bits == y => 1024
BITS_FOR_Y = 10,
// 1 third most significant bit == x parity => 2
BITS_FOR_X_PARITY = 1,
// 8 fourth most significant bits == layer => 256
BITS_FOR_LAYER = 8,
// 9 least significant bits == x / 2 => 512 (really 1024 for x)
BITS_FOR_X_OVER_2 = 9
};
} // end anon namespace
drawing_buffer::buffer_key::layer_group_array drawing_buffer::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
}};
drawing_buffer::buffer_key::buffer_key(const map_location &loc, drawing_layer layer)
: key_(0)
{
// Start with the index of last group entry...
unsigned int group_i = layer_groups.size() - 1;
// ...and works backwards until the group containing the specified layer is found.
while(layer < layer_groups[group_i]) {
--group_i;
}
enum {
SHIFT_LAYER = BITS_FOR_X_OVER_2,
SHIFT_X_PARITY = BITS_FOR_LAYER + SHIFT_LAYER,
SHIFT_Y = BITS_FOR_X_PARITY + SHIFT_X_PARITY,
SHIFT_LAYER_GROUP = BITS_FOR_Y + SHIFT_Y
};
static_assert(SHIFT_LAYER_GROUP + BITS_FOR_LAYER_GROUP == sizeof(key_) * 8, "Bit field too small");
/* The parity of x must be more significant than the layer but less significant than y.
* Thus basically every row is split in two: First the row containing all the odd x
* then the row containing all the even x. Since thus the least significant bit of x is
* not required for x ordering anymore it can be shifted out to the right.
*/
const unsigned int x_parity = static_cast<unsigned int>(loc.x) & 1;
key_ = (group_i << SHIFT_LAYER_GROUP) | (static_cast<unsigned int>(loc.y + MAX_BORDER) << SHIFT_Y);
key_ |= (x_parity << SHIFT_X_PARITY);
key_ |= (static_cast<unsigned int>(layer) << SHIFT_LAYER) | static_cast<unsigned int>(loc.x + MAX_BORDER) / 2;
}
void drawing_buffer::render_buffer()
{
// std::list::sort() is a stable sort
buffer_.sort();
display* disp = display::get_singleton();
SDL_Rect clip_rect = disp->map_area();
surface& screen = disp->get_screen_surface();
clip_rect_setter set_clip_rect(screen, &clip_rect);
/* Info regarding the rendering algorithm.
*
* 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.
*
* This ended in the following priority order:
* layergroup > location > layer > 'blit_helper' > surface
*/
for(const blit_helper& blit : buffer_) {
for(const surface& surf : blit.surfaces()) {
// Note that dstrect can be changed by sdl_blit
// and so a new instance should be initialized
// to pass to each call to sdl_blit.
SDL_Rect dstrect {blit.x(), blit.y(), 0, 0};
SDL_Rect srcrect = blit.clip();
SDL_Rect* srcrectArg = (srcrect.x | srcrect.y | srcrect.w | srcrect.h) ? &srcrect : nullptr;
sdl_blit(surf, srcrectArg, screen, &dstrect);
// NOTE: the screen part should already be marked as 'to update'
}
}
// Clear the buffer.
buffer_.clear();
}

245
src/drawing_buffer.hpp Normal file
View file

@ -0,0 +1,245 @@
/*
Copyright (C) 2003 - 2017 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once
#include "map/location.hpp"
#include "sdl/texture.hpp"
#include <SDL_rect.h>
#include <array>
#include <list>
#include <vector>
class drawing_buffer
{
public:
drawing_buffer()
: buffer_()
{
}
/** Draws the contents of the buffer to screen and clears it. */
void render_buffer();
/** Adds a new item to the buffer. */
template<typename... T>
void add_item(T&&... args)
{
buffer_.emplace_back(std::forward<T>(args)...);
}
/**
* The various map rendering layers. This controls the internal rendering order.
*/
enum drawing_layer {
/** Layer for the terrain drawn behind units. */
LAYER_TERRAIN_BG,
/** Top half part of grid image */
LAYER_GRID_TOP,
/** Mouseover overlay used by editor*/
LAYER_MOUSEOVER_OVERLAY,
/** Footsteps showing path from unit to mouse */
LAYER_FOOTSTEPS,
/** Top half of image following the mouse */
LAYER_MOUSEOVER_TOP,
/** Reserve layers to be selected for WML. */
LAYER_UNIT_FIRST,
/** Used for the ellipse behind units. */
LAYER_UNIT_BG = LAYER_UNIT_FIRST + 10,
/**default layer for drawing units */
LAYER_UNIT_DEFAULT = LAYER_UNIT_FIRST + 40,
/** Layer for the terrain drawn in front of units. */
LAYER_TERRAIN_FG = LAYER_UNIT_FIRST + 50,
/** Used for the bottom half part of grid image. Should be under moving units to avoid masking south move. */
LAYER_GRID_BOTTOM,
/** Default layer for drawing moving units */
LAYER_UNIT_MOVE_DEFAULT = LAYER_UNIT_FIRST + 60,
/** Used for the ellipse in front of units. */
LAYER_UNIT_FG = LAYER_UNIT_FIRST + 80,
/** Default layer for missile frames*/
LAYER_UNIT_MISSILE_DEFAULT = LAYER_UNIT_FIRST + 90,
LAYER_UNIT_LAST = LAYER_UNIT_FIRST + 100,
/** "Black stripes" on unreachable hexes. */
LAYER_REACHMAP,
/** Bottom half of image following the mouse */
LAYER_MOUSEOVER_BOTTOM,
/** Fog and shroud. */
LAYER_FOG_SHROUD,
/** Arrows from the arrows framework. Used for planned moves display. */
LAYER_ARROWS,
/** Move numbering for the whiteboard. */
LAYER_ACTIONS_NUMBERING,
/** Image on the selected unit */
LAYER_SELECTED_HEX,
/** Layer which holds the attack indicator. */
LAYER_ATTACK_INDICATOR,
/** Unit bars and overlays are drawn at this layer (for testing here). */
LAYER_UNIT_BAR,
/** Movement info (defense %, etc...). */
LAYER_MOVE_INFO,
/** The overlay used for the linger mode. */
LAYER_LINGER_OVERLAY,
/** The map border. */
LAYER_BORDER,
};
private:
/**
* 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.
*
* 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.
*/
class buffer_key
{
public:
buffer_key(const map_location& loc, drawing_layer layer);
bool operator<(const buffer_key& rhs) const
{
return key_ < rhs.key_;
}
private:
unsigned int key_;
using layer_group_array = const std::array<drawing_layer, 4>;
// The drawing is done per layer_group, with the range per group being [low, high].
// FIXME: better documentation.
static layer_group_array layer_groups;
};
/** Helper structure for rendering the buffer contents. */
class blit_helper
{
public:
blit_helper(const drawing_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)
{
}
blit_helper(const drawing_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>& surfaces() const
{
return surf_;
}
const SDL_Rect& clip() const
{
return clip_;
}
bool operator<(const blit_helper& rhs) const
{
return key_ < rhs.key_;
}
private:
/** x screen coordinate to render at. */
int x_;
/** y screen coordinate to render at. */
int y_;
/** surface(s) to render. */
std::vector<surface> surf_;
/** The clipping area of the source. If omitted the entire source is used. */
SDL_Rect clip_;
buffer_key key_;
};
std::list<blit_helper> buffer_;
};

View file

@ -83,13 +83,13 @@ void editor_display::draw_hex(const map_location& loc)
display::draw_hex(loc);
if (map().on_board_with_border(loc)) {
if (map().in_selection(loc)) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::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_SELECTED_HEX, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_SELECTED_HEX, loc, xpos, ypos,
image::get_image(brush, image::SCALED_TO_HEX));
}
}

View file

@ -265,30 +265,30 @@ void game_display::draw_hex(const map_location& loc)
}
if(on_map && loc == mouseoverHex_) {
drawing_layer hex_top_layer = LAYER_MOUSEOVER_BOTTOM;
drawing_buffer::drawing_layer hex_top_layer = drawing_buffer::LAYER_MOUSEOVER_BOTTOM;
const unit *u = resources::gameboard->get_visible_unit(loc, dc_->teams()[viewing_team()] );
if( u != nullptr ) {
hex_top_layer = LAYER_MOUSEOVER_TOP;
hex_top_layer = drawing_buffer::LAYER_MOUSEOVER_TOP;
}
if(u == nullptr) {
drawing_buffer_add( hex_top_layer, loc, xpos, ypos,
image::get_image("misc/hover-hex-top.png~RC(magenta>gold)", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_image("misc/hover-hex-bottom.png~RC(magenta>gold)", image::SCALED_TO_HEX));
} else if(dc_->teams()[currentTeam_].is_enemy(u->side())) {
drawing_buffer_add( hex_top_layer, loc, xpos, ypos,
image::get_image("misc/hover-hex-enemy-top.png~RC(magenta>red)", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_image("misc/hover-hex-enemy-bottom.png~RC(magenta>red)", image::SCALED_TO_HEX));
} else if(dc_->teams()[currentTeam_].side() == u->side()) {
drawing_buffer_add( hex_top_layer, loc, xpos, ypos,
image::get_image("misc/hover-hex-top.png~RC(magenta>green)", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_image("misc/hover-hex-bottom.png~RC(magenta>green)", image::SCALED_TO_HEX));
} else {
drawing_buffer_add( hex_top_layer, loc, xpos, ypos,
image::get_image("misc/hover-hex-top.png~RC(magenta>lightblue)", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_image("misc/hover-hex-bottom.png~RC(magenta>lightblue)", image::SCALED_TO_HEX));
}
}
@ -301,7 +301,7 @@ 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, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_REACHMAP, loc, xpos, ypos,
image::get_image(unreachable,image::SCALED_TO_HEX));
}
@ -312,16 +312,16 @@ void game_display::draw_hex(const map_location& loc)
{
std::vector<surface> footstepImages = footsteps_images(loc, route_, dc_);
if (!footstepImages.empty()) {
drawing_buffer_add(LAYER_FOOTSTEPS, loc, xpos, ypos, footsteps_images(loc, route_, dc_));
drawing_buffer_add(drawing_buffer::LAYER_FOOTSTEPS, loc, xpos, ypos, footsteps_images(loc, route_, dc_));
}
}
}
// Draw the attack direction indicator
if(on_map && loc == attack_indicator_src_) {
drawing_buffer_add(LAYER_ATTACK_INDICATOR, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::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, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_ATTACK_INDICATOR, loc, xpos, ypos,
image::get_image("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX));
}
@ -329,13 +329,13 @@ void game_display::draw_hex(const map_location& loc)
// so it's drawn over the shroud and fog.
if(mode_ != RUNNING) {
static const image::locator linger(game_config::images::linger);
drawing_buffer_add(LAYER_LINGER_OVERLAY, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::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, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_SELECTED_HEX, loc, xpos, ypos,
image::get_image(selected, image::SCALED_TO_HEX));
}
@ -348,7 +348,7 @@ void game_display::draw_hex(const map_location& loc)
int debugH = debugHighlights_[loc];
if (debugH) {
std::string txt = std::to_string(debugH);
draw_text_in_hex(loc, LAYER_MOVE_INFO, txt, 18, font::BAD_COLOR);
draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, txt, 18, font::BAD_COLOR);
}
}
//simulate_delay += 1;
@ -419,22 +419,22 @@ void game_display::draw_movement_info(const map_location& loc)
// simple mark (no turn point) use smaller font
int def_font = w->second.turns > 0 ? 18 : 16;
draw_text_in_hex(loc, LAYER_MOVE_INFO, def_text.str(), def_font, color);
draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, def_text.str(), def_font, color);
int xpos = get_location_x(loc);
int ypos = get_location_y(loc);
if (w->second.invisible) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
drawing_buffer_add(drawing_buffer::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, xpos, ypos,
drawing_buffer_add(drawing_buffer::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, xpos, ypos,
drawing_buffer_add(drawing_buffer::LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_image("misc/capture.png", image::SCALED_TO_HEX));
}
@ -442,7 +442,7 @@ void game_display::draw_movement_info(const map_location& loc)
if (w->second.turns > 1 || (w->second.turns == 1 && loc != route_.steps.back())) {
std::stringstream turns_text;
turns_text << w->second.turns;
draw_text_in_hex(loc, LAYER_MOVE_INFO, turns_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8);
draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, turns_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8);
}
// The hex is full now, so skip the "show enemy moves"
@ -466,7 +466,7 @@ void game_display::draw_movement_info(const map_location& loc)
// use small font
int def_font = 16;
draw_text_in_hex(loc, LAYER_MOVE_INFO, def_text.str(), def_font, color);
draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, def_text.str(), def_font, color);
}
}
@ -474,7 +474,7 @@ void game_display::draw_movement_info(const map_location& loc)
reach_map::iterator reach = reach_map_.find(loc);
if (reach != reach_map_.end() && reach->second > 1) {
const std::string num = std::to_string(reach->second);
draw_text_in_hex(loc, LAYER_MOVE_INFO, num, 16, font::YELLOW_COLOR);
draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, num, 16, font::YELLOW_COLOR);
}
}
}

View file

@ -544,7 +544,7 @@ void unit_animation::fill_initial_animations(std::vector<unit_animation>& animat
animations.push_back(base);
animations.back().event_ = { "movement" };
animations.back().unit_anim_.override(0, 200,
particle::NO_CYCLE, "", "", {0,0,0}, "0~1:200", std::to_string(display::LAYER_UNIT_MOVE_DEFAULT - display::LAYER_UNIT_FIRST));
particle::NO_CYCLE, "", "", {0,0,0}, "0~1:200", std::to_string(drawing_buffer::LAYER_UNIT_MOVE_DEFAULT - drawing_buffer::LAYER_UNIT_FIRST));
animations.push_back(base);
animations.back().event_ = { "defend" };
@ -558,7 +558,7 @@ void unit_animation::fill_initial_animations(std::vector<unit_animation>& animat
animations.push_back(base);
animations.back().event_ = { "attack" };
animations.back().unit_anim_.override(-150, 300, particle::NO_CYCLE, "", "", {0,0,0}, "0~0.6:150,0.6~0:150", std::to_string(display::LAYER_UNIT_MOVE_DEFAULT-display::LAYER_UNIT_FIRST));
animations.back().unit_anim_.override(-150, 300, particle::NO_CYCLE, "", "", {0,0,0}, "0~0.6:150,0.6~0:150", std::to_string(drawing_buffer::LAYER_UNIT_MOVE_DEFAULT-drawing_buffer::LAYER_UNIT_FIRST));
animations.back().primary_attack_filter_.push_back(config());
animations.back().primary_attack_filter_.back()["range"] = "melee";
@ -607,7 +607,7 @@ void unit_animation::fill_initial_animations(std::vector<unit_animation>& animat
static void add_simple_anim(std::vector<unit_animation>& animations,
const config& cfg, char const* tag_name, char const* apply_to,
display::drawing_layer layer = display::LAYER_UNIT_DEFAULT,
drawing_buffer::drawing_layer layer = drawing_buffer::LAYER_UNIT_DEFAULT,
bool offscreen = true)
{
for(const animation_branch& ab : prepare_animation(cfg, tag_name)) {
@ -620,7 +620,7 @@ static void add_simple_anim(std::vector<unit_animation>& animations,
}
config::attribute_value& v = anim["layer"];
if(v.empty()) v = layer - display::LAYER_UNIT_FIRST;
if(v.empty()) v = layer - drawing_buffer::LAYER_UNIT_FIRST;
animations.push_back(unit_animation(anim));
}
@ -632,15 +632,15 @@ void unit_animation::add_anims( std::vector<unit_animation> & animations, const
animations.push_back(unit_animation(ab.merge()));
}
const int default_layer = display::LAYER_UNIT_DEFAULT - display::LAYER_UNIT_FIRST;
const int move_layer = display::LAYER_UNIT_MOVE_DEFAULT - display::LAYER_UNIT_FIRST;
const int missile_layer = display::LAYER_UNIT_MISSILE_DEFAULT - display::LAYER_UNIT_FIRST;
const int default_layer = drawing_buffer::LAYER_UNIT_DEFAULT - drawing_buffer::LAYER_UNIT_FIRST;
const int move_layer = drawing_buffer::LAYER_UNIT_MOVE_DEFAULT - drawing_buffer::LAYER_UNIT_FIRST;
const int missile_layer = drawing_buffer::LAYER_UNIT_MISSILE_DEFAULT - drawing_buffer::LAYER_UNIT_FIRST;
add_simple_anim(animations, cfg, "resistance_anim", "resistance");
add_simple_anim(animations, cfg, "leading_anim", "leading");
add_simple_anim(animations, cfg, "recruit_anim", "recruited");
add_simple_anim(animations, cfg, "recruiting_anim", "recruiting");
add_simple_anim(animations, cfg, "idle_anim", "idling", display::LAYER_UNIT_DEFAULT, false);
add_simple_anim(animations, cfg, "idle_anim", "idling", drawing_buffer::LAYER_UNIT_DEFAULT, false);
add_simple_anim(animations, cfg, "levelin_anim", "levelin");
add_simple_anim(animations, cfg, "levelout_anim", "levelout");
@ -736,7 +736,7 @@ void unit_animation::add_anims( std::vector<unit_animation> & animations, const
animations.back().sub_anims_["_poison_sound"].add_frame(1,frame_builder().sound(game_config::sounds::status::poisoned),true);
}
add_simple_anim(animations, cfg, "pre_movement_anim", "pre_movement", display::LAYER_UNIT_MOVE_DEFAULT);
add_simple_anim(animations, cfg, "pre_movement_anim", "pre_movement", drawing_buffer::LAYER_UNIT_MOVE_DEFAULT);
for(const animation_branch& ab : prepare_animation(cfg, "movement_anim")) {
config anim = ab.merge();
@ -753,7 +753,7 @@ void unit_animation::add_anims( std::vector<unit_animation> & animations, const
animations.push_back(unit_animation(anim));
}
add_simple_anim(animations, cfg, "post_movement_anim", "post_movement", display::LAYER_UNIT_MOVE_DEFAULT);
add_simple_anim(animations, cfg, "post_movement_anim", "post_movement", drawing_buffer::LAYER_UNIT_MOVE_DEFAULT);
for(const animation_branch& ab : prepare_animation(cfg, "defend")) {
config anim = ab.merge();
@ -799,8 +799,8 @@ void unit_animation::add_anims( std::vector<unit_animation> & animations, const
}
}
add_simple_anim(animations, cfg, "draw_weapon_anim", "draw_weapon", display::LAYER_UNIT_MOVE_DEFAULT);
add_simple_anim(animations, cfg, "sheath_weapon_anim", "sheath_weapon", display::LAYER_UNIT_MOVE_DEFAULT);
add_simple_anim(animations, cfg, "draw_weapon_anim", "draw_weapon", drawing_buffer::LAYER_UNIT_MOVE_DEFAULT);
add_simple_anim(animations, cfg, "sheath_weapon_anim", "sheath_weapon", drawing_buffer::LAYER_UNIT_MOVE_DEFAULT);
for(const animation_branch& ab : prepare_animation(cfg, "attack_anim")) {
config anim = ab.merge();

View file

@ -212,14 +212,14 @@ void unit_drawer::redraw_unit (const unit & u) const
}
}
if (ellipse_back != nullptr) {
//disp.drawing_buffer_add(display::LAYER_UNIT_BG, loc,
disp.drawing_buffer_add(display::LAYER_UNIT_FIRST, loc,
//disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_BG, loc,
disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_FIRST, loc,
xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_back);
}
if (ellipse_front != nullptr) {
//disp.drawing_buffer_add(display::LAYER_UNIT_FG, loc,
disp.drawing_buffer_add(display::LAYER_UNIT_FIRST, loc,
//disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_FG, loc,
disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_FIRST, loc,
xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_front);
}
if(draw_bars) {
@ -285,7 +285,7 @@ void unit_drawer::redraw_unit (const unit & u) const
if (orb_img != nullptr) {
surface orb(image::get_image(*orb_img,image::SCALED_TO_ZOOM));
disp.drawing_buffer_add(display::LAYER_UNIT_BAR,
disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_BAR,
loc, xsrc + xoff, ysrc + yoff + adjusted_params.y, orb);
}
@ -316,7 +316,7 @@ void unit_drawer::redraw_unit (const unit & u) const
//if(bar_alpha != ftofxp(1.0)) {
// crown = adjust_surface_alpha(crown, bar_alpha);
//}
disp.drawing_buffer_add(display::LAYER_UNIT_BAR,
disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_BAR,
loc, xsrc+xoff, ysrc+yoff+adjusted_params.y, crown);
}
}
@ -324,7 +324,7 @@ void unit_drawer::redraw_unit (const unit & u) const
for(const std::string& ov : u.overlays()) {
const surface ov_img(image::get_image(ov, image::SCALED_TO_ZOOM));
if(ov_img != nullptr) {
disp.drawing_buffer_add(display::LAYER_UNIT_BAR,
disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_BAR,
loc, xsrc+xoff, ysrc+yoff+adjusted_params.y, ov_img);
}
}
@ -403,8 +403,8 @@ void unit_drawer::draw_bar(const std::string& image, int xpos, int ypos,
SDL_Rect bot = sdl::create_rect(0, bar_loc.y + skip_rows, surf->w, 0);
bot.h = surf->w - bot.y;
disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos, surf, top);
disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos + top.h, surf, bot);
disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_BAR, loc, xpos, ypos, surf, top);
disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_BAR, loc, xpos, ypos + top.h, surf, bot);
size_t unfilled = static_cast<size_t>(height * (1.0 - filled));
@ -413,7 +413,7 @@ void unit_drawer::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 = sdl::create_rect(0, 0, bar_loc.w, height-unfilled);
sdl::fill_surface_rect(filled_surf,&filled_area,SDL_MapRGBA(bar_surf->format,col.r,col.g,col.b, r_alpha));
disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, filled_surf);
disp.drawing_buffer_add(drawing_buffer::LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, filled_surf);
}
}

View file

@ -37,7 +37,7 @@ frame_parameters::frame_parameters()
, auto_vflip(boost::logic::indeterminate)
, auto_hflip(boost::logic::indeterminate)
, primary_frame(boost::logic::indeterminate)
, drawing_layer(display::LAYER_UNIT_DEFAULT - display::LAYER_UNIT_FIRST)
, drawing_layer(drawing_buffer::LAYER_UNIT_DEFAULT - drawing_buffer::LAYER_UNIT_FIRST)
{}
frame_builder::frame_builder()
@ -45,7 +45,7 @@ frame_builder::frame_builder()
, auto_vflip_(boost::logic::indeterminate)
, auto_hflip_(boost::logic::indeterminate)
, primary_frame_(boost::logic::indeterminate)
, drawing_layer_(std::to_string(display::LAYER_UNIT_DEFAULT - display::LAYER_UNIT_FIRST))
, drawing_layer_(std::to_string(drawing_buffer::LAYER_UNIT_DEFAULT - drawing_buffer::LAYER_UNIT_FIRST))
{}
frame_builder::frame_builder(const config& cfg,const std::string& frame_string)
@ -313,7 +313,7 @@ const frame_parameters frame_parsed_parameters::parameters(int current_time) con
result.auto_vflip = auto_vflip_;
result.auto_hflip = auto_hflip_;
result.primary_frame = primary_frame_;
result.drawing_layer = drawing_layer_.get_current_element(current_time,display::LAYER_UNIT_DEFAULT-display::LAYER_UNIT_FIRST);
result.drawing_layer = drawing_layer_.get_current_element(current_time,drawing_buffer::LAYER_UNIT_DEFAULT-drawing_buffer::LAYER_UNIT_FIRST);
return result;
}
@ -552,7 +552,7 @@ void unit_frame::redraw(const int frame_time, bool on_start_time, bool in_scope_
}
display::get_singleton()->render_image(my_x, my_y,
static_cast<display::drawing_layer>(display::LAYER_UNIT_FIRST + current_data.drawing_layer),
static_cast<drawing_buffer::drawing_layer>(drawing_buffer::LAYER_UNIT_FIRST + current_data.drawing_layer),
src, image, facing_west, false,
ftofxp(current_data.highlight_ratio), current_data.blend_with ? *current_data.blend_with : color_t(),
current_data.blend_ratio, current_data.submerge, !facing_north);
@ -866,8 +866,8 @@ const frame_parameters unit_frame::merge_parameters(int current_time, const fram
assert(engine_val.directional_y == 0);
result.directional_y = current_val.directional_y ? current_val.directional_y : animation_val.directional_y;
assert(engine_val.drawing_layer == display::LAYER_UNIT_DEFAULT - display::LAYER_UNIT_FIRST);
result.drawing_layer = current_val.drawing_layer != display::LAYER_UNIT_DEFAULT-display::LAYER_UNIT_FIRST
assert(engine_val.drawing_layer == drawing_buffer::LAYER_UNIT_DEFAULT - drawing_buffer::LAYER_UNIT_FIRST);
result.drawing_layer = current_val.drawing_layer != drawing_buffer::LAYER_UNIT_DEFAULT-drawing_buffer::LAYER_UNIT_FIRST
? current_val.drawing_layer
: animation_val.drawing_layer;

View file

@ -192,7 +192,7 @@ void attack::draw_hex(const map_location& hex)
{
//@todo: replace this by either the use of transparency + LAYER_ATTACK_INDICATOR,
//or a dedicated layer
const display::drawing_layer layer = display::LAYER_FOOTSTEPS;
const drawing_buffer::drawing_layer layer = drawing_buffer::LAYER_FOOTSTEPS;
//calculate direction (valid for both hexes)
std::string direction_text = map_location::write_direction(

View file

@ -469,7 +469,7 @@ static void draw_numbers(const map_location& hex, side_actions::numbers_t number
color_t color = team::get_side_color(static_cast<int>(team_numbers[i]+1));
const double x_in_hex = x_origin + x_offset;
const double y_in_hex = y_origin + y_offset;
display::get_singleton()->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING,
display::get_singleton()->draw_text_in_hex(hex, drawing_buffer::LAYER_ACTIONS_NUMBERING,
number_text, font_size, color, x_in_hex, y_in_hex);
x_offset += x_offset_base;
y_offset += y_offset_base;

View file

@ -391,7 +391,7 @@ void move::draw_hex(const map_location& hex)
{
std::stringstream turn_text;
turn_text << turn_number_;
display::get_singleton()->draw_text_in_hex(hex, display::LAYER_MOVE_INFO, turn_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8);
display::get_singleton()->draw_text_in_hex(hex, drawing_buffer::LAYER_MOVE_INFO, turn_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8);
}
}

View file

@ -191,7 +191,7 @@ void recall::draw_hex(const map_location& hex)
}
size_t font_size = 16;
color_t color {255, 0, 0}; //red
display::get_singleton()->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING,
display::get_singleton()->draw_text_in_hex(hex, drawing_buffer::LAYER_ACTIONS_NUMBERING,
number_text.str(), font_size, color, x_offset, y_offset);
}
}

View file

@ -155,7 +155,7 @@ void recruit::draw_hex(const map_location& hex)
number_text << font::unicode_minus << cost_;
size_t font_size = 16;
color_t color {255, 0, 0}; //red
display::get_singleton()->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING,
display::get_singleton()->draw_text_in_hex(hex, drawing_buffer::LAYER_ACTIONS_NUMBERING,
number_text.str(), font_size, color, x_offset, y_offset);
}
}

View file

@ -138,7 +138,7 @@ void suppose_dead::draw_hex(const map_location& hex)
if(hex == loc_) //add symbol to hex
{
//@todo: Possibly use a different layer
const display::drawing_layer layer = display::LAYER_ARROWS;
const drawing_buffer::drawing_layer layer = drawing_buffer::LAYER_ARROWS;
int xpos = display::get_singleton()->get_location_x(loc_);
int ypos = display::get_singleton()->get_location_y(loc_);