From aede8582122f8b23d53030d7a534e55c02792dcd Mon Sep 17 00:00:00 2001 From: Charles Dang Date: Sun, 11 Jun 2017 09:06:50 +1100 Subject: [PATCH] Decoupled drawing buffer code from display class --- projectfiles/CodeBlocks/wesnoth.cbp | 2 + source_lists/libwesnoth | 1 + src/arrow.cpp | 2 +- src/arrow.hpp | 2 +- src/display.cpp | 162 +++--------------- src/display.hpp | 96 +---------- src/drawing_buffer.cpp | 127 ++++++++++++++ src/drawing_buffer.hpp | 245 ++++++++++++++++++++++++++++ src/editor/editor_display.cpp | 4 +- src/game_display.cpp | 40 ++--- src/units/animation.cpp | 24 +-- src/units/drawer.cpp | 20 +-- src/units/frame.cpp | 12 +- src/whiteboard/attack.cpp | 2 +- src/whiteboard/manager.cpp | 2 +- src/whiteboard/move.cpp | 2 +- src/whiteboard/recall.cpp | 2 +- src/whiteboard/recruit.cpp | 2 +- src/whiteboard/suppose_dead.cpp | 2 +- 19 files changed, 466 insertions(+), 283 deletions(-) create mode 100644 src/drawing_buffer.cpp create mode 100644 src/drawing_buffer.hpp diff --git a/projectfiles/CodeBlocks/wesnoth.cbp b/projectfiles/CodeBlocks/wesnoth.cbp index 841857b0a95f..92828b52c075 100644 --- a/projectfiles/CodeBlocks/wesnoth.cbp +++ b/projectfiles/CodeBlocks/wesnoth.cbp @@ -256,6 +256,8 @@ + + diff --git a/source_lists/libwesnoth b/source_lists/libwesnoth index 66eba01f134a..c9b44606ffff 100644 --- a/source_lists/libwesnoth +++ b/source_lists/libwesnoth @@ -3,6 +3,7 @@ cursor.cpp desktop/clipboard.cpp display.cpp display_context.cpp +drawing_buffer.cpp events.cpp floating_label.cpp font/font_config.cpp diff --git a/src/arrow.cpp b/src/arrow.cpp index 775d99225916..c9a38c418c52 100644 --- a/src/arrow.cpp +++ b/src/arrow.cpp @@ -32,7 +32,7 @@ static lg::log_domain log_arrows("arrows"); #define SCREEN (static_cast(resources::screen)) arrow::arrow(bool hidden) - : layer_(display::LAYER_ARROWS) + : layer_(drawing_buffer::LAYER_ARROWS) , color_("red") , style_(STYLE_STANDARD) , path_() diff --git a/src/arrow.hpp b/src/arrow.hpp index d86f036709eb..ef051149f33b 100644 --- a/src/arrow.hpp +++ b/src/arrow.hpp @@ -90,7 +90,7 @@ class arrow { */ 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 diff --git a/src/display.cpp b/src/display.cpp index f743f0373361..c81536025ed6 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -1193,126 +1193,19 @@ std::vector display::get_terrain_images(const map_location &loc, return res; } -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_.push_back(blit_helper(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 &surf, const SDL_Rect &clip) { - drawing_buffer_.push_back(blit_helper(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_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(loc.x) & 1; - key_ = (group_i << SHIFT_LAYER_GROUP) | (static_cast(loc.y + MAX_BORDER) << SHIFT_Y); - key_ |= (x_parity << SHIFT_X_PARITY); - key_ |= (static_cast(layer) << SHIFT_LAYER) | static_cast(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() @@ -1494,7 +1387,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; @@ -1518,7 +1411,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) @@ -2444,7 +2337,7 @@ void display::draw(bool update,bool force) { draw_invalidated(); invalidated_.clear(); } - drawing_buffer_commit(); + drawing_buffer_.render_buffer(); post_commit(); draw_sidebar(); @@ -2525,21 +2418,21 @@ void display::draw_hex(const map_location& loc) { num_images_bg = images_bg.size(); // unshrouded terrain (the normal case) - drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, images_bg); + drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_BG, loc, xpos, ypos, images_bg); - drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, images_fg); + drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_FG, loc, xpos, ypos, images_fg); // 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)); } // village-control flags. - drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, get_flag(loc)); + drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_BG, loc, xpos, ypos, get_flag(loc)); } if(!shrouded(loc)) { @@ -2567,7 +2460,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); } } } @@ -2577,17 +2470,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 @@ -2604,16 +2497,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) { @@ -2632,8 +2525,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; @@ -2649,8 +2542,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; @@ -2667,13 +2560,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)); } @@ -3208,4 +3101,3 @@ void display::handle_event(const SDL_Event& event) { } display *display::singleton_ = nullptr; - diff --git a/src/display.hpp b/src/display.hpp index 176f3053a021..41c948ef261b 100644 --- a/src/display.hpp +++ b/src/display.hpp @@ -50,6 +50,7 @@ namespace wb { #include "animated.hpp" #include "display_context.hpp" +#include "drawing_buffer.hpp" #include "filter_context.hpp" #include "font/sdl_ttf.hpp" #include "font/standard_colors.hpp" @@ -664,7 +665,7 @@ class display : public filter_context, public video2::draw_layering 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() {} @@ -837,7 +838,7 @@ class display : public filter_context, public video2::draw_layering * 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}, @@ -848,7 +849,7 @@ class display : public filter_context, public video2::draw_layering * 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: @@ -856,83 +857,6 @@ class display : public filter_context, public video2::draw_layering //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 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: - 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& 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 &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 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 drawing_buffer; drawing_buffer drawing_buffer_; public: @@ -943,27 +867,19 @@ class display : public filter_context, public video2::draw_layering * @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 &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. * diff --git a/src/drawing_buffer.cpp b/src/drawing_buffer.cpp new file mode 100644 index 000000000000..db5d98e3d6db --- /dev/null +++ b/src/drawing_buffer.cpp @@ -0,0 +1,127 @@ +/* + Copyright (C) 2003 - 2017 by David White + 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(loc.x) & 1; + + key_ = (group_i << SHIFT_LAYER_GROUP) | (static_cast(loc.y + MAX_BORDER) << SHIFT_Y); + key_ |= (x_parity << SHIFT_X_PARITY); + key_ |= (static_cast(layer) << SHIFT_LAYER) | static_cast(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(); +} diff --git a/src/drawing_buffer.hpp b/src/drawing_buffer.hpp new file mode 100644 index 000000000000..b6f00333fd4a --- /dev/null +++ b/src/drawing_buffer.hpp @@ -0,0 +1,245 @@ +/* + Copyright (C) 2003 - 2017 by David White + 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 + +#include +#include +#include + +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 + void add_item(T&&... args) + { + buffer_.emplace_back(std::forward(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; + + // 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& 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& 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 surf_; + + /** The clipping area of the source. If omitted the entire source is used. */ + SDL_Rect clip_; + + buffer_key key_; + }; + + std::list buffer_; +}; diff --git a/src/editor/editor_display.cpp b/src/editor/editor_display.cpp index 879005ef4520..9bbe3e7a6221 100644 --- a/src/editor/editor_display.cpp +++ b/src/editor/editor_display.cpp @@ -110,13 +110,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)); } } diff --git a/src/game_display.cpp b/src/game_display.cpp index 54d39c48af61..342d71f07284 100644 --- a/src/game_display.cpp +++ b/src/game_display.cpp @@ -286,30 +286,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)); } } @@ -322,7 +322,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)); } @@ -333,16 +333,16 @@ void game_display::draw_hex(const map_location& loc) { std::vector 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)); } @@ -350,13 +350,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)); } @@ -369,7 +369,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; @@ -438,22 +438,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)); } @@ -461,7 +461,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" @@ -483,7 +483,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); } } @@ -491,7 +491,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); } } } diff --git a/src/units/animation.cpp b/src/units/animation.cpp index 0a026499d1ba..750bf4eb49ba 100644 --- a/src/units/animation.cpp +++ b/src/units/animation.cpp @@ -543,7 +543,7 @@ void unit_animation::fill_initial_animations(std::vector& 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" }; @@ -557,7 +557,7 @@ void unit_animation::fill_initial_animations(std::vector& 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"; @@ -606,7 +606,7 @@ void unit_animation::fill_initial_animations(std::vector& animat static void add_simple_anim(std::vector& 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)) { @@ -619,7 +619,7 @@ static void add_simple_anim(std::vector& 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)); } @@ -631,15 +631,15 @@ void unit_animation::add_anims( std::vector & 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"); @@ -735,7 +735,7 @@ void unit_animation::add_anims( std::vector & 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(); @@ -752,7 +752,7 @@ void unit_animation::add_anims( std::vector & 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(); @@ -798,8 +798,8 @@ void unit_animation::add_anims( std::vector & 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(); diff --git a/src/units/drawer.cpp b/src/units/drawer.cpp index 92ceb779b1b7..29ad41ff7c31 100644 --- a/src/units/drawer.cpp +++ b/src/units/drawer.cpp @@ -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) { @@ -272,7 +272,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); } @@ -303,7 +303,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); } } @@ -311,7 +311,7 @@ void unit_drawer::redraw_unit (const unit & u) const for(std::vector::const_iterator ov = u.overlays().begin(); ov != u.overlays().end(); ++ov) { 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); } } @@ -390,8 +390,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(height * (1.0 - filled)); @@ -400,7 +400,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); } } diff --git a/src/units/frame.cpp b/src/units/frame.cpp index bedff8ddd08c..a2cebb8d5510 100644 --- a/src/units/frame.cpp +++ b/src/units/frame.cpp @@ -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) @@ -315,7 +315,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; } @@ -554,7 +554,7 @@ void unit_frame::redraw(const int frame_time, bool on_start_time, bool in_scope_ } game_display::get_singleton()->render_image(my_x, my_y, - static_cast(display::LAYER_UNIT_FIRST + current_data.drawing_layer), + static_cast(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); @@ -868,8 +868,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; diff --git a/src/whiteboard/attack.cpp b/src/whiteboard/attack.cpp index 6591454c232a..47ebcb6aa21f 100644 --- a/src/whiteboard/attack.cpp +++ b/src/whiteboard/attack.cpp @@ -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( diff --git a/src/whiteboard/manager.cpp b/src/whiteboard/manager.cpp index 5f54aebf9c8d..640cb7f4a336 100644 --- a/src/whiteboard/manager.cpp +++ b/src/whiteboard/manager.cpp @@ -462,7 +462,7 @@ static void draw_numbers(map_location const& hex, side_actions::numbers_t number color_t color = team::get_side_color(static_cast(team_numbers[i]+1)); const double x_in_hex = x_origin + x_offset; const double y_in_hex = y_origin + y_offset; - resources::screen->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING, + resources::screen->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; diff --git a/src/whiteboard/move.cpp b/src/whiteboard/move.cpp index 2ce623ae9c7b..ed34f7405f84 100644 --- a/src/whiteboard/move.cpp +++ b/src/whiteboard/move.cpp @@ -391,7 +391,7 @@ void move::draw_hex(map_location const& hex) { std::stringstream turn_text; turn_text << turn_number_; - resources::screen->draw_text_in_hex(hex, display::LAYER_MOVE_INFO, turn_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8); + resources::screen->draw_text_in_hex(hex, drawing_buffer::LAYER_MOVE_INFO, turn_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8); } } diff --git a/src/whiteboard/recall.cpp b/src/whiteboard/recall.cpp index 5c223b864300..4aef3e777595 100644 --- a/src/whiteboard/recall.cpp +++ b/src/whiteboard/recall.cpp @@ -191,7 +191,7 @@ void recall::draw_hex(map_location const& hex) } size_t font_size = 16; color_t color {255, 0, 0}; //red - resources::screen->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING, + resources::screen->draw_text_in_hex(hex, drawing_buffer::LAYER_ACTIONS_NUMBERING, number_text.str(), font_size, color, x_offset, y_offset); } } diff --git a/src/whiteboard/recruit.cpp b/src/whiteboard/recruit.cpp index a2172f45c0bb..3b35b5ac78c5 100644 --- a/src/whiteboard/recruit.cpp +++ b/src/whiteboard/recruit.cpp @@ -155,7 +155,7 @@ void recruit::draw_hex(map_location const& hex) number_text << font::unicode_minus << cost_; size_t font_size = 16; color_t color {255, 0, 0}; //red - resources::screen->draw_text_in_hex(hex, display::LAYER_ACTIONS_NUMBERING, + resources::screen->draw_text_in_hex(hex, drawing_buffer::LAYER_ACTIONS_NUMBERING, number_text.str(), font_size, color, x_offset, y_offset); } } diff --git a/src/whiteboard/suppose_dead.cpp b/src/whiteboard/suppose_dead.cpp index 370a52b5c109..cc1db53fe713 100644 --- a/src/whiteboard/suppose_dead.cpp +++ b/src/whiteboard/suppose_dead.cpp @@ -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 = resources::screen->get_location_x(loc_); int ypos = resources::screen->get_location_y(loc_);