Decoupled drawing buffer code from display class
This commit is contained in:
parent
e30a2aa520
commit
8dc661db40
19 changed files with 467 additions and 298 deletions
|
@ -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" />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_()
|
||||
|
|
|
@ -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
|
||||
|
|
174
src/display.cpp
174
src/display.cpp
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
100
src/display.hpp
100
src/display.hpp
|
@ -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
127
src/drawing_buffer.cpp
Normal 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
245
src/drawing_buffer.hpp
Normal 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_;
|
||||
};
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_);
|
||||
|
|
Loading…
Add table
Reference in a new issue