Initial SDL_gpu support in the game display.

This commit is contained in:
Boldizsár Lipka 2014-07-10 05:45:49 +02:00
parent ae0f4b0e9b
commit 0acb2e1529
7 changed files with 547 additions and 10 deletions

View file

@ -337,6 +337,29 @@ void display::init_flags_for_side_internal(size_t n, const std::string& side_col
f.start_animation(rand() % f.get_end_time(), true);
}
#ifdef SDL_GPU
sdl::ttexture display::get_flag(const map_location& loc)
{
t_translation::t_terrain terrain = get_map().get_terrain(loc);
if(!get_map().is_village(terrain)) {
return surface(NULL);
}
for(size_t i = 0; i != dc_->teams().size(); ++i) {
if(dc_->teams()[i].owns_village(loc) &&
(!fogged(loc) || !dc_->teams()[currentTeam_].is_enemy(i+1)))
{
flags_[i].update_last_draw_time();
const image::locator &image_flag = animate_map_ ?
flags_[i].get_current_frame() : flags_[i].get_first_frame();
return image::get_texture(image_flag, image::TOD_COLORED);
}
}
return sdl::ttexture();
}
#else
surface display::get_flag(const map_location& loc)
{
t_translation::t_terrain terrain = get_map().get_terrain(loc);
@ -358,6 +381,7 @@ surface display::get_flag(const map_location& loc)
return surface(NULL);
}
#endif
void display::set_team(size_t teamindex, bool show_everything)
{
@ -924,7 +948,11 @@ static const std::string& get_direction(size_t n)
return dirs[n >= sizeof(dirs)/sizeof(*dirs) ? 0 : n];
}
#ifdef SDL_GPU
std::vector<sdl::ttexture> display::get_fog_shroud_images(const map_location& loc, image::TYPE image_type)
#else
std::vector<surface> display::get_fog_shroud_images(const map_location& loc, image::TYPE image_type)
#endif
{
std::vector<std::string> names;
@ -1002,23 +1030,46 @@ std::vector<surface> display::get_fog_shroud_images(const map_location& loc, ima
}
// now get the surfaces
#ifdef SDL_GPU
std::vector<sdl::ttexture> res;
#else
std::vector<surface> res;
#endif
BOOST_FOREACH(std::string& name, names) {
#ifdef SDL_GPU
const sdl::ttexture img(image::get_texture(name, image_type));
if (!img.null())
res.push_back(img);
#else
const surface surf(image::get_image(name, image_type));
if (surf)
res.push_back(surf);
#endif
}
return res;
}
// TODO: proper SDL_gpu implementation
#ifdef SDL_GPU
std::vector<sdl::ttexture> display::get_terrain_images(
const map_location &loc,
const std::string& timeid,
image::TYPE image_type,
TERRAIN_TYPE terrain_type)
#else
std::vector<surface> display::get_terrain_images(const map_location &loc,
const std::string& timeid,
image::TYPE image_type,
TERRAIN_TYPE terrain_type)
#endif
{
#ifdef SDL_GPU
std::vector<sdl::ttexture> res;
#else
std::vector<surface> res;
#endif
terrain_builder::TERRAIN_TYPE builder_terrain_type =
(terrain_type == FOREGROUND ?
@ -1091,7 +1142,11 @@ std::vector<surface> display::get_terrain_images(const map_location &loc,
}
if (!surf.null()) {
#ifdef SDL_GPU
res.push_back(sdl::ttexture(surf));
#else
res.push_back(surf);
#endif
}
}
}
@ -1099,6 +1154,21 @@ std::vector<surface> display::get_terrain_images(const map_location &loc,
return res;
}
#ifdef SDL_GPU
void display::drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, int x, int y,
const sdl::ttexture &img)
{
drawing_buffer_.push_back(tblit(layer, loc, x, y, img));
}
void display::drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, int x, int y,
const std::vector<sdl::ttexture> &imgs)
{
drawing_buffer_.push_back(tblit(layer, loc, x, y, imgs));
}
#else
void display::drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, int x, int y, const surface& surf,
const SDL_Rect &clip)
@ -1113,6 +1183,7 @@ void display::drawing_buffer_add(const tdrawing_layer layer,
{
drawing_buffer_.push_back(tblit(layer, loc, x, y, surf, clip));
}
#endif
// FIXME: temporary method. Group splitting should be made
// public into the definition of tdrawing_layer
@ -1186,6 +1257,34 @@ void display::drawing_buffer_commit()
// std::list::sort() is a stable sort
drawing_buffer_.sort();
#ifdef SDL_GPU
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 > 'tblit' > surface
*/
BOOST_FOREACH(tblit &blit, drawing_buffer_) {
BOOST_FOREACH(sdl::ttexture& img, blit.images()) {
if (!img.null()) {
screen_.draw_texture(img, blit.x(), blit.y());
}
}
}
flip();
drawing_buffer_clear();
#else
SDL_Rect clip_rect = map_area();
surface screen = get_screen_surface();
clip_rect_setter set_clip_rect(screen, &clip_rect);
@ -1217,6 +1316,7 @@ void display::drawing_buffer_commit()
}
}
drawing_buffer_clear();
#endif
}
void display::drawing_buffer_clear()
@ -1429,6 +1529,7 @@ static void draw_background(surface screen, const SDL_Rect& area, const std::str
}
}
//TODO: convert this to use sdl::ttexture
void display::draw_text_in_hex(const map_location& loc,
const tdrawing_layer layer, const std::string& text,
size_t font_size, SDL_Color color, double x_in_hex, double y_in_hex)
@ -1443,7 +1544,19 @@ void display::draw_text_in_hex(const map_location& loc,
+ static_cast<int>(x_in_hex* hex_size());
const int y = get_location_y(loc) - text_surf->h/2
+ static_cast<int>(y_in_hex* hex_size());
#ifdef SDL_GPU
sdl::ttexture text_img(text_surf);
sdl::ttexture back_img(back_surf);
for (int dy=-1; dy <= 1; ++dy) {
for (int dx=-1; dx <= 1; ++dx) {
if (dx!=0 || dy!=0) {
drawing_buffer_add(layer, loc, x + dx, y + dy, back_img);
}
}
}
drawing_buffer_add(layer, loc, x, y, text_img);
#else
for (int dy=-1; dy <= 1; ++dy) {
for (int dx=-1; dx <= 1; ++dx) {
if (dx!=0 || dy!=0) {
@ -1452,8 +1565,10 @@ void display::draw_text_in_hex(const map_location& loc,
}
}
drawing_buffer_add(layer, loc, x, y, text_surf);
#endif
}
//TODO: convert this to use sdl::ttexture
void display::render_image(int x, int y, const display::tdrawing_layer drawing_layer,
const map_location& loc, surface image,
bool hreverse, bool greyscale, fixed_t alpha,
@ -1496,7 +1611,37 @@ void display::render_image(int x, int y, const display::tdrawing_layer drawing_l
ERR_DP << "surface lost..." << std::endl;
return;
}
#ifdef SDL_GPU
sdl::ttexture img(surf);
if(submerged > 0.0) {
// divide the surface into 2 parts
const int submerge_height = std::max<int>(0, surf->h*(1.0-submerged));
//const int depth = surf->h - submerge_height;
SDL_Rect srcrect = sdl::create_rect(0, 0, surf->w, submerge_height);
img.set_clip(srcrect);
drawing_buffer_add(drawing_layer, loc, x, y, img);
if(submerge_height != surf->h) {
//the lower part will be transparent
//float alpha_base = 0.3f; // 30% alpha at surface of water
float alpha_delta = 0.015f; // lose 1.5% per pixel depth
alpha_delta *= zoom_ / DefaultZoom; // adjust with zoom
//TODO: submerging
//surf = submerge_alpha(surf, depth, alpha_base, alpha_delta, false);
srcrect.y = submerge_height;
srcrect.h = surf->h-submerge_height;
y += submerge_height;
img.set_clip(srcrect);
drawing_buffer_add(drawing_layer, loc, x, y, img);
}
} else {
// simple blit
drawing_buffer_add(drawing_layer, loc, x, y, img);
}
#else
if(submerged > 0.0) {
// divide the surface into 2 parts
const int submerge_height = std::max<int>(0, surf->h*(1.0-submerged));
@ -1521,6 +1666,7 @@ void display::render_image(int x, int y, const display::tdrawing_layer drawing_l
// simple blit
drawing_buffer_add(drawing_layer, loc, x, y, surf);
}
#endif
}
@ -1696,8 +1842,70 @@ void display::announce(const std::string& message, const SDL_Color& color)
font::add_floating_label(flabel);
}
void display::draw_border(const map_location& loc, const int xpos, const int ypos)
{
#ifdef SDL_GPU
/**
* at the moment the border must be between 0.0 and 0.5
* and the image should always be prepared for a 0.5 border.
* This way this code doesn't need modifications for other border sizes.
*/
// First handle the corners :
if(loc.x == -1 && loc.y == -1) { // top left corner
drawing_buffer_add(LAYER_BORDER, loc, xpos + zoom_/4, ypos,
image::get_texture(theme_.border().corner_image_top_left, image::SCALED_TO_ZOOM));
} else if(loc.x == get_map().w() && loc.y == -1) { // top right corner
// We use the map idea of odd and even, and map coords are internal coords + 1
if(loc.x%2 == 0) {
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos + zoom_/2,
image::get_texture(theme_.border().corner_image_top_right_odd, image::SCALED_TO_ZOOM));
} else {
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_texture(theme_.border().corner_image_top_right_even, image::SCALED_TO_ZOOM));
}
} else if(loc.x == -1 && loc.y == get_map().h()) { // bottom left corner
drawing_buffer_add(LAYER_BORDER, loc, xpos + zoom_/4, ypos,
image::get_texture(theme_.border().corner_image_bottom_left, image::SCALED_TO_ZOOM));
} else if(loc.x == get_map().w() && loc.y == get_map().h()) { // bottom right corner
// We use the map idea of odd and even, and map coords are internal coords + 1
if(loc.x%2 == 1) {
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_texture(theme_.border().corner_image_bottom_right_even, image::SCALED_TO_ZOOM));
} else {
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_texture(theme_.border().corner_image_bottom_right_odd, image::SCALED_TO_ZOOM));
}
// Now handle the sides:
} else if(loc.x == -1) { // left side
drawing_buffer_add(LAYER_BORDER, loc, xpos + zoom_/4, ypos,
image::get_texture(theme_.border().border_image_left, image::SCALED_TO_ZOOM));
} else if(loc.x == get_map().w()) { // right side
drawing_buffer_add(LAYER_BORDER, loc, xpos + zoom_/4, ypos,
image::get_texture(theme_.border().border_image_right, image::SCALED_TO_ZOOM));
} else if(loc.y == -1) { // top side
// We use the map idea of odd and even, and map coords are internal coords + 1
if(loc.x%2 == 1) {
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_texture(theme_.border().border_image_top_even, image::SCALED_TO_ZOOM));
} else {
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos + zoom_/2,
image::get_texture(theme_.border().border_image_top_odd, image::SCALED_TO_ZOOM));
}
} else if(loc.y == get_map().h()) { // bottom side
// We use the map idea of odd and even, and map coords are internal coords + 1
if(loc.x%2 == 1) {
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos,
image::get_texture(theme_.border().border_image_bottom_even, image::SCALED_TO_ZOOM));
} else {
drawing_buffer_add(LAYER_BORDER, loc, xpos, ypos + zoom_/2,
image::get_texture(theme_.border().border_image_bottom_odd, image::SCALED_TO_ZOOM));
}
}
#else
/**
* at the moment the border must be between 0.0 and 0.5
* and the image should always be prepared for a 0.5 border.
@ -1757,6 +1965,7 @@ void display::draw_border(const map_location& loc, const int xpos, const int ypo
image::get_image(theme_.border().border_image_bottom_odd, image::SCALED_TO_ZOOM));
}
}
#endif
}
void display::draw_minimap()
@ -2475,6 +2684,7 @@ void display::draw_invalidated() {
}
//TODO: proper SDL_gpu implementation
void display::draw_hex(const map_location& loc) {
int xpos = get_location_x(loc);
int ypos = get_location_y(loc);
@ -2490,6 +2700,19 @@ void display::draw_hex(const map_location& loc) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos,
get_terrain_images(loc,tod.id,image_type, FOREGROUND));
#ifdef SDL_GPU
// Draw the grid, if that's been enabled
if(grid_ && on_map && !off_map_tile) {
static const image::locator grid_top(game_config::images::grid_top);
drawing_buffer_add(LAYER_GRID_TOP, loc, xpos, ypos,
image::get_texture(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,
image::get_texture(grid_bottom, image::TOD_COLORED));
}
// village-control flags.
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, get_flag(loc));
#else
// Draw the grid, if that's been enabled
if(grid_ && on_map && !off_map_tile) {
static const image::locator grid_top(game_config::images::grid_top);
@ -2501,6 +2724,7 @@ void display::draw_hex(const map_location& loc) {
}
// village-control flags.
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, get_flag(loc));
#endif
}
if(!shrouded(loc)) {
@ -2531,11 +2755,15 @@ void display::draw_hex(const map_location& loc) {
overlays.first->second.team_name.find(dc_->teams()[viewing_team()].team_name()) != std::string::npos)
&& !(fogged(loc) && !overlays.first->second.visible_in_fog))
{
const surface surf = use_local_light
? image::get_lighted_image(overlays.first->second.image, lt, image::SCALED_TO_HEX)
: image::get_image(overlays.first->second.image, image_type);
#ifdef SDL_GPU
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, sdl::ttexture(surf));
#else
drawing_buffer_add(LAYER_TERRAIN_BG, loc, xpos, ypos, surf);
#endif
}
}
}
@ -2543,6 +2771,15 @@ void display::draw_hex(const map_location& loc) {
// Draw the time-of-day mask on top of the terrain in the hex.
// tod may differ from tod if hex is illuminated.
const std::string& tod_hex_mask = tod.image_mask;
#ifdef SDL_GPU
if(!tod_hex_mask1.null() || !tod_hex_mask2.null()) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask1);
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask2);
} else if(!tod_hex_mask.empty()) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos,
image::get_texture(tod_hex_mask,image::SCALED_TO_HEX));
}
#else
if(tod_hex_mask1 != NULL || tod_hex_mask2 != NULL) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask1);
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos, tod_hex_mask2);
@ -2550,10 +2787,15 @@ void display::draw_hex(const map_location& loc) {
drawing_buffer_add(LAYER_TERRAIN_FG, loc, xpos, ypos,
image::get_image(tod_hex_mask,image::SCALED_TO_HEX));
}
#endif
// Paint mouseover overlays
if(loc == mouseoverHex_ && (on_map || (in_editor() && get_map().on_board_with_border(loc)))
#ifdef SDL_GPU
&& !mouseover_hex_overlay_.null()) {
#else
&& mouseover_hex_overlay_ != NULL) {
#endif
drawing_buffer_add(LAYER_MOUSEOVER_OVERLAY, loc, xpos, ypos, mouseover_hex_overlay_);
}
@ -2567,6 +2809,19 @@ void display::draw_hex(const map_location& loc) {
// Apply shroud, fog and linger overlay
#ifdef SDL_GPU
if(shrouded(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,
image::get_texture(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,
image::get_texture(fog_image, image_type));
}
#else
if(shrouded(loc)) {
// We apply void also on off-map tiles
// to shroud the half-hexes too
@ -2578,6 +2833,7 @@ void display::draw_hex(const map_location& loc) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image(fog_image, image_type));
}
#endif
if(!shrouded(loc)) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos, get_fog_shroud_images(loc, image_type));
@ -2597,8 +2853,13 @@ void display::draw_hex(const map_location& loc) {
} else {
off_y -= text->h / 2;
}
#ifdef SDL_GPU
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, sdl::ttexture(bg));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, sdl::ttexture(text));
#else
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, text);
#endif
}
if (draw_terrain_codes_ && (game_config::debug || !shrouded(loc))) {
int off_x = xpos + hex_size()/2;
@ -2611,14 +2872,24 @@ void display::draw_hex(const map_location& loc) {
if (!draw_coordinates_) {
off_y -= text->h / 2;
}
#ifdef SDL_GPU
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, sdl::ttexture(bg));
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, sdl::ttexture(text));
#else
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, bg);
drawing_buffer_add(LAYER_FOG_SHROUD, loc, off_x, off_y, text);
#endif
}
}
if(debug_foreground) {
#ifdef SDL_GPU
drawing_buffer_add(LAYER_UNIT_DEFAULT, loc, xpos, ypos,
image::get_texture("terrain/foreground.png", image_type));
#else
drawing_buffer_add(LAYER_UNIT_DEFAULT, loc, xpos, ypos,
image::get_image("terrain/foreground.png", image_type));
#endif
}
}

View file

@ -56,6 +56,7 @@ namespace wb {
#include "team.hpp"
#include "time_of_day.hpp"
#include "sdl/rect.hpp"
#include "sdl/texture.hpp"
#include "theme.hpp"
#include "video.hpp"
#include "widgets/button.hpp"
@ -433,6 +434,17 @@ public:
*/
void invalidate_animations_location(const map_location& loc);
#ifdef SDL_GPU
/**
* mouseover_hex_overlay_ require a prerendered surface
* and is drawn underneath the mouse's location
*/
void set_mouseover_hex_overlay(const sdl::ttexture& image)
{ mouseover_hex_overlay_ = image; }
void clear_mouseover_hex_overlay()
{ mouseover_hex_overlay_ = sdl::ttexture(); }
#else
/**
* mouseover_hex_overlay_ require a prerendered surface
* and is drawn underneath the mouse's location
@ -442,6 +454,7 @@ public:
void clear_mouseover_hex_overlay()
{ mouseover_hex_overlay_ = NULL; }
#endif
/**
* Debug function to toggle the "sunset" mode.
@ -712,12 +725,21 @@ protected:
enum TERRAIN_TYPE { BACKGROUND, FOREGROUND};
#ifdef SDL_GPU
std::vector<sdl::ttexture> get_terrain_images(const map_location &loc,
const std::string& timeid,
image::TYPE type,
TERRAIN_TYPE terrain_type);
std::vector<sdl::ttexture> get_fog_shroud_images(const map_location& loc, image::TYPE image_type);
#else
std::vector<surface> get_terrain_images(const map_location &loc,
const std::string& timeid,
image::TYPE type,
TERRAIN_TYPE terrain_type);
std::vector<surface> get_fog_shroud_images(const map_location& loc, image::TYPE image_type);
#endif
void draw_image_for_report(surface& img, SDL_Rect& rect);
@ -775,10 +797,17 @@ protected:
std::vector<gui::slider> sliders_;
std::set<map_location> invalidated_;
std::set<map_location> previous_invalidated_;
#ifdef SDL_GPU
sdl::ttexture mouseover_hex_overlay_;
// If we're transitioning from one time of day to the next,
// then we will use these two masks on top of all hexes when we blit.
sdl::ttexture tod_hex_mask1, tod_hex_mask2;
#else
surface mouseover_hex_overlay_;
// If we're transitioning from one time of day to the next,
// then we will use these two masks on top of all hexes when we blit.
surface tod_hex_mask1, tod_hex_mask2;
#endif
std::vector<std::string> fog_images_;
std::vector<std::string> shroud_images_;
@ -794,8 +823,13 @@ protected:
private:
#ifdef SDL_GPU
// This surface must be freed by the caller
sdl::ttexture get_flag(const map_location& loc);
#else
// This surface must be freed by the caller
surface get_flag(const map_location& loc);
#endif
/** Animated flags for each team */
std::vector<animated<image::locator> > flags_;
@ -930,6 +964,18 @@ protected:
class tblit
{
public:
#ifdef SDL_GPU
tblit(const tdrawing_layer layer, const map_location& loc,
const int x, const int y, const sdl::ttexture& image)
: x_(x), y_(y), images_(1, image), key_(loc, layer)
{}
tblit(const tdrawing_layer layer, const map_location& loc,
const int x, const int y,
const std::vector<sdl::ttexture>& images)
: x_(x), y_(y), images_(images), key_(loc, layer)
{}
#else
tblit(const tdrawing_layer layer, const map_location& loc,
const int x, const int y, const surface& surf,
const SDL_Rect& clip)
@ -943,22 +989,31 @@ protected:
: x_(x), y_(y), surf_(surf), clip_(clip),
key_(loc, layer)
{}
#endif
int x() const { return x_; }
int y() const { return y_; }
#ifdef SDL_GPU
std::vector<sdl::ttexture> &images() { return images_; }
#else
const std::vector<surface> &surf() const { return surf_; }
const SDL_Rect &clip() const { return clip_; }
#endif
bool operator<(const tblit &rhs) const { return key_ < rhs.key_; }
private:
int x_; /**< x screen coordinate to render at. */
int y_; /**< y screen coordinate to render at. */
#ifdef SDL_GPU
std::vector<sdl::ttexture> images_;
#else
std::vector<surface> surf_; /**< surface(s) to render. */
SDL_Rect clip_; /**<
* The clipping area of the source if
* omitted the entire source is used.
*/
* The clipping area of the source if
* omitted the entire source is used.
*/
#endif
drawing_buffer_key key_;
};
@ -966,7 +1021,15 @@ protected:
tdrawing_buffer drawing_buffer_;
public:
#ifdef SDL_GPU
void drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, int x, int y,
const sdl::ttexture& img);
void drawing_buffer_add(const tdrawing_layer layer,
const map_location& loc, int x, int y,
const std::vector<sdl::ttexture> &imgs);
#else
/**
* Add an item to the drawing buffer. You need to update screen on affected area
*
@ -982,6 +1045,7 @@ public:
const map_location& loc, int x, int y,
const std::vector<surface> &surf,
const SDL_Rect &clip = SDL_Rect());
#endif
protected:

View file

@ -108,6 +108,22 @@ void editor_display::draw_hex(const map_location& loc)
int ypos = get_location_y(loc);
display::draw_hex(loc);
if (map().on_board_with_border(loc)) {
#ifdef SDL_GPU
if (map().in_selection(loc)) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_texture("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,
image::get_texture(brush, image::SCALED_TO_HEX));
}
if (map().on_board(loc) && loc == mouseoverHex_) {
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_texture("misc/hover-hex.png", image::SCALED_TO_HEX));
}
#else
if (map().in_selection(loc)) {
drawing_buffer_add(LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image("editor/selection-overlay.png", image::TOD_COLORED));
@ -122,6 +138,7 @@ void editor_display::draw_hex(const map_location& loc)
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_image("misc/hover-hex.png", image::SCALED_TO_HEX));
}
#endif
}
}

View file

@ -59,7 +59,11 @@ std::map<map_location,fixed_t> game_display::debugHighlights_;
*
* This function is only used internally by game_display so I have moved it out of the header into the compilaton unit.
*/
#ifdef SDL_GPU
std::vector<sdl::ttexture> footsteps_images(const map_location& loc, const pathfind::marked_route & route_, const display_context * dc_);
#else
std::vector<surface> footsteps_images(const map_location& loc, const pathfind::marked_route & route_, const display_context * dc_);
#endif
game_display::game_display(game_board& board, CVideo& video, boost::weak_ptr<wb::manager> wb,
const tod_manager& tod,
@ -99,6 +103,7 @@ game_display::~game_display()
} catch (...) {}
}
//TODO: proper SDL_gpu implementation
void game_display::new_turn()
{
const time_of_day& tod = tod_manager_.get_time_of_day();
@ -115,6 +120,17 @@ void game_display::new_turn()
const int starting_ticks = SDL_GetTicks();
for(int i = 0; i != niterations; ++i) {
#ifdef SDL_GPU
if(old_mask != NULL) {
const fixed_t proportion = ftofxp(1.0) - fxpdiv(i,niterations);
tod_hex_mask1 = sdl::ttexture(adjust_surface_alpha(old_mask,proportion));
}
if(new_mask != NULL) {
const fixed_t proportion = fxpdiv(i,niterations);
tod_hex_mask2 = sdl::ttexture(adjust_surface_alpha(new_mask,proportion));
}
#else
if(old_mask != NULL) {
const fixed_t proportion = ftofxp(1.0) - fxpdiv(i,niterations);
tod_hex_mask1.assign(adjust_surface_alpha(old_mask,proportion));
@ -124,6 +140,7 @@ void game_display::new_turn()
const fixed_t proportion = fxpdiv(i,niterations);
tod_hex_mask2.assign(adjust_surface_alpha(new_mask,proportion));
}
#endif
invalidate_all();
draw();
@ -136,8 +153,13 @@ void game_display::new_turn()
}
}
#ifdef SDL_GPU
tod_hex_mask1 = sdl::ttexture();
tod_hex_mask2 = sdl::ttexture();
#else
tod_hex_mask1.assign(NULL);
tod_hex_mask2.assign(NULL);
#endif
}
first_turn_ = false;
@ -281,6 +303,29 @@ void game_display::draw_hex(const map_location& loc)
if( u != NULL ) {
hex_top_layer = LAYER_MOUSEOVER_TOP;
}
#ifdef SDL_GPU
if(u == NULL) {
drawing_buffer_add( hex_top_layer, loc, xpos, ypos,
image::get_texture("misc/hover-hex-top.png~RC(magenta>gold)", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_texture("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_texture("misc/hover-hex-enemy-top.png~RC(magenta>red)", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_texture("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_texture("misc/hover-hex-top.png~RC(magenta>green)", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_texture("misc/hover-hex-bottom.png~RC(magenta>green)", image::SCALED_TO_HEX));
} else {
drawing_buffer_add( hex_top_layer, loc, xpos, ypos,
image::get_texture("misc/hover-hex-top.png~RC(magenta>lightblue)", image::SCALED_TO_HEX));
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_texture("misc/hover-hex-bottom.png~RC(magenta>lightblue)", image::SCALED_TO_HEX));
}
#else
if(u == NULL) {
drawing_buffer_add( hex_top_layer, loc, xpos, ypos,
image::get_image("misc/hover-hex-top.png~RC(magenta>gold)", image::SCALED_TO_HEX));
@ -302,6 +347,7 @@ void game_display::draw_hex(const map_location& loc)
drawing_buffer_add(LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
image::get_image("misc/hover-hex-bottom.png~RC(magenta>lightblue)", image::SCALED_TO_HEX));
}
#endif
}
@ -312,8 +358,13 @@ 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);
#ifdef SDL_GPU
drawing_buffer_add(LAYER_REACHMAP, loc, xpos, ypos,
image::get_texture(unreachable,image::SCALED_TO_HEX));
#else
drawing_buffer_add(LAYER_REACHMAP, loc, xpos, ypos,
image::get_image(unreachable,image::SCALED_TO_HEX));
#endif
}
if (boost::shared_ptr<wb::manager> w = wb_.lock()) {
@ -321,14 +372,40 @@ void game_display::draw_hex(const map_location& loc)
if (!(w->is_active() && w->has_temp_move()))
{
// Footsteps indicating a movement path
const std::vector<surface>& footstepImages = footsteps_images(loc, route_, dc_);
#ifdef SDL_GPU
std::vector<sdl::ttexture> footstepImages = footsteps_images(loc, route_, dc_);
#else
std::vector<surface> footstepImages = footsteps_images(loc, route_, dc_);
#endif
if (!footstepImages.empty()) {
drawing_buffer_add(LAYER_FOOTSTEPS, loc, xpos, ypos, footstepImages);
drawing_buffer_add(LAYER_FOOTSTEPS, loc, xpos, ypos, footsteps_images(loc, route_, dc_));
}
}
}
// Draw the attack direction indicator
#ifdef SDL_GPU
if(on_map && loc == attack_indicator_src_) {
drawing_buffer_add(LAYER_ATTACK_INDICATOR, loc, xpos, ypos,
image::get_texture("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,
image::get_texture("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX));
}
// Linger overlay unconditionally otherwise it might give glitches
// so it's drawn over the shroud and fog.
if(game_mode_ != RUNNING) {
static const image::locator linger(game_config::images::linger);
drawing_buffer_add(LAYER_LINGER_OVERLAY, loc, xpos, ypos,
image::get_texture(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,
image::get_texture(selected, image::SCALED_TO_HEX));
}
#else
if(on_map && loc == attack_indicator_src_) {
drawing_buffer_add(LAYER_ATTACK_INDICATOR, loc, xpos, ypos,
image::get_image("misc/attack-indicator-src-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX));
@ -350,6 +427,7 @@ void game_display::draw_hex(const map_location& loc)
drawing_buffer_add(LAYER_SELECTED_HEX, loc, xpos, ypos,
image::get_image(selected, image::SCALED_TO_HEX));
}
#endif
// Show def% and turn to reach info
if(!is_shrouded && on_map) {
@ -433,7 +511,22 @@ void game_display::draw_movement_info(const map_location& loc)
int xpos = get_location_x(loc);
int ypos = get_location_y(loc);
#ifdef SDL_GPU
if (w->second.invisible) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_texture("misc/hidden.png", image::SCALED_TO_HEX));
}
if (w->second.zoc) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_texture("misc/zoc.png", image::SCALED_TO_HEX));
}
if (w->second.capture) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_texture("misc/capture.png", image::SCALED_TO_HEX));
}
#else
if (w->second.invisible) {
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_image("misc/hidden.png", image::SCALED_TO_HEX));
@ -448,6 +541,7 @@ void game_display::draw_movement_info(const map_location& loc)
drawing_buffer_add(LAYER_MOVE_INFO, loc, xpos, ypos,
image::get_image("misc/capture.png", image::SCALED_TO_HEX));
}
#endif
//we display turn info only if different from a simple last "1"
if (w->second.turns > 1 || (w->second.turns == 1 && loc != route_.steps.back())) {
@ -488,9 +582,17 @@ void game_display::draw_movement_info(const map_location& loc)
}
}
#ifdef SDL_GPU
std::vector<sdl::ttexture> footsteps_images(const map_location& loc, const pathfind::marked_route & route_, const display_context * dc_)
#else
std::vector<surface> footsteps_images(const map_location& loc, const pathfind::marked_route & route_, const display_context * dc_)
#endif
{
#ifdef SDL_GPU
std::vector<sdl::ttexture> res;
#else
std::vector<surface> res;
#endif
if (route_.steps.size() < 2) {
return res; // no real "route"
@ -515,7 +617,11 @@ std::vector<surface> footsteps_images(const map_location& loc, const pathfind::m
}
const std::string foot_speed_prefix = game_config::foot_speed_prefix[image_number-1];
#ifdef SDL_GPU
sdl::ttexture teleport;
#else
surface teleport = NULL;
#endif
// We draw 2 half-hex (with possibly different directions),
// but skip the first for the first step.
@ -529,7 +635,11 @@ std::vector<surface> footsteps_images(const map_location& loc, const pathfind::m
if (!tiles_adjacent(*(i+(h-1)), *(i+h))) {
std::string teleport_image =
h==0 ? game_config::foot_teleport_enter : game_config::foot_teleport_exit;
#ifdef SDL_GPU
teleport = image::get_texture(teleport_image, image::SCALED_TO_HEX);
#else
teleport = image::get_image(teleport_image, image::SCALED_TO_HEX);
#endif
continue;
}
@ -547,11 +657,19 @@ std::vector<surface> footsteps_images(const map_location& loc, const pathfind::m
+ sense + "-" + i->write_direction(dir)
+ ".png" + rotate;
#ifdef SDL_GPU
res.push_back(image::get_texture(image, image::SCALED_TO_HEX));
#else
res.push_back(image::get_image(image, image::SCALED_TO_HEX));
#endif
}
// we draw teleport image (if any) in last
#ifdef SDL_GPU
if (!teleport.null()) res.push_back(teleport);
#else
if (teleport != NULL) res.push_back(teleport);
#endif
return res;
}

View file

@ -180,9 +180,13 @@ void unit_drawer::redraw_unit (const unit & u) const
SDL_Rect unit_rect = sdl::create_rect(xsrc, ysrc +adjusted_params.y, hex_size, hex_size);
draw_bars = sdl::rects_overlap(unit_rect, disp.map_outside_area());
}
#ifdef SDL_GPU
sdl::ttexture ellipse_front;
sdl::ttexture ellipse_back;
#else
surface ellipse_front(NULL);
surface ellipse_back(NULL);
#endif
int ellipse_floating = 0;
// Always show the ellipse for selected units
if(draw_bars && (preferences::show_side_colors() || sel_hex == loc)) {
@ -206,14 +210,32 @@ void unit_drawer::redraw_unit (const unit & u) const
// Load the ellipse parts recolored to match team color
char buf[100];
std::string tc=team::get_side_color_index(side);
#ifdef SDL_GPU
snprintf(buf,sizeof(buf),"%s-%s%s%stop.png~RC(ellipse_red>%s)",ellipse.c_str(),leader,nozoc,selected,tc.c_str());
ellipse_back = image::get_texture(image::locator(buf), image::SCALED_TO_ZOOM);
snprintf(buf,sizeof(buf),"%s-%s%s%sbottom.png~RC(ellipse_red>%s)",ellipse.c_str(),leader,nozoc,selected,tc.c_str());
ellipse_front = image::get_texture(image::locator(buf), image::SCALED_TO_ZOOM);
#else
snprintf(buf,sizeof(buf),"%s-%s%s%stop.png~RC(ellipse_red>%s)",ellipse.c_str(),leader,nozoc,selected,tc.c_str());
ellipse_back.assign(image::get_image(image::locator(buf), image::SCALED_TO_ZOOM));
snprintf(buf,sizeof(buf),"%s-%s%s%sbottom.png~RC(ellipse_red>%s)",ellipse.c_str(),leader,nozoc,selected,tc.c_str());
ellipse_front.assign(image::get_image(image::locator(buf), image::SCALED_TO_ZOOM));
#endif
}
}
#ifdef SDL_GPU
if (!ellipse_back.null()) {
//disp.drawing_buffer_add(display::LAYER_UNIT_BG, loc,
disp.drawing_buffer_add(display::LAYER_UNIT_FIRST, loc,
xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_back);
}
if (!ellipse_front.null()) {
//disp.drawing_buffer_add(display::LAYER_UNIT_FG, loc,
disp.drawing_buffer_add(display::LAYER_UNIT_FIRST, loc,
xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_front);
}
#else
if (ellipse_back != NULL) {
//disp.drawing_buffer_add(display::LAYER_UNIT_BG, loc,
disp.drawing_buffer_add(display::LAYER_UNIT_FIRST, loc,
@ -225,6 +247,7 @@ void unit_drawer::redraw_unit (const unit & u) const
disp.drawing_buffer_add(display::LAYER_UNIT_FIRST, loc,
xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_front);
}
#endif
if(draw_bars) {
const image::locator* orb_img = NULL;
/*static*/ const image::locator partmoved_orb(game_config::images::orb + "~RC(magenta>" +
@ -309,11 +332,19 @@ void unit_drawer::redraw_unit (const unit & u) const
}
for(std::vector<std::string>::const_iterator ov = u.overlays().begin(); ov != u.overlays().end(); ++ov) {
#ifdef SDL_GPU
const sdl::ttexture ov_img(image::get_texture(*ov, image::SCALED_TO_ZOOM));
if(!ov_img.null()) {
disp.drawing_buffer_add(display::LAYER_UNIT_BAR,
loc, xsrc, ysrc +adjusted_params.y, ov_img);
}
#else
const surface ov_img(image::get_image(*ov, image::SCALED_TO_ZOOM));
if(ov_img != NULL) {
disp.drawing_buffer_add(display::LAYER_UNIT_BAR,
loc, xsrc, ysrc +adjusted_params.y, ov_img);
}
#endif
}
}
@ -336,6 +367,7 @@ void unit_drawer::redraw_unit (const unit & u) const
ac.refreshing_ = false;
}
//TODO: proper SDL_gpu implementation
void unit_drawer::draw_bar(const std::string& image, int xpos, int ypos,
const map_location& loc, size_t height, double filled,
const SDL_Color& col, fixed_t alpha) const
@ -389,8 +421,16 @@ 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;
#ifdef SDL_GPU
sdl::ttexture img(surf);
img.set_clip(top);
disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos, surf);
img.set_clip(bot);
disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos + top.h, surf);
#else
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);
#endif
size_t unfilled = static_cast<size_t>(height * (1.0 - filled));
@ -399,7 +439,11 @@ 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_rect(filled_surf,&filled_area,SDL_MapRGBA(bar_surf->format,col.r,col.g,col.b, r_alpha));
#ifdef SDL_GPU
disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, sdl::ttexture(filled_surf));
#else
disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, filled_surf);
#endif
}
}

View file

@ -198,6 +198,24 @@ void attack::draw_hex(const map_location& hex)
std::string direction_text = map_location::write_direction(
get_dest_hex().get_relative_dir(target_hex_));
#ifdef SDL_GPU
if (hex == get_dest_hex()) //add symbol to attacker hex
{
int xpos = resources::screen->get_location_x(get_dest_hex());
int ypos = resources::screen->get_location_y(get_dest_hex());
resources::screen->drawing_buffer_add(layer, get_dest_hex(), xpos, ypos,
image::get_texture("whiteboard/attack-indicator-src-" + direction_text + ".png", image::SCALED_TO_HEX));
}
else if (hex == target_hex_) //add symbol to defender hex
{
int xpos = resources::screen->get_location_x(target_hex_);
int ypos = resources::screen->get_location_y(target_hex_);
resources::screen->drawing_buffer_add(layer, target_hex_, xpos, ypos,
image::get_texture("whiteboard/attack-indicator-dst-" + direction_text + ".png", image::SCALED_TO_HEX));
}
#else
if (hex == get_dest_hex()) //add symbol to attacker hex
{
int xpos = resources::screen->get_location_x(get_dest_hex());
@ -214,6 +232,7 @@ void attack::draw_hex(const map_location& hex)
resources::screen->drawing_buffer_add(layer, target_hex_, xpos, ypos,
image::get_image("whiteboard/attack-indicator-dst-" + direction_text + ".png", image::SCALED_TO_HEX));
}
#endif
}
}

View file

@ -143,9 +143,13 @@ void suppose_dead::draw_hex(const map_location& hex)
int xpos = resources::screen->get_location_x(loc_);
int ypos = resources::screen->get_location_y(loc_);
#ifdef SDL_GPU
resources::screen->drawing_buffer_add(layer, loc_, xpos, ypos,
image::get_texture("whiteboard/suppose_dead.png", image::SCALED_TO_HEX));
#else
resources::screen->drawing_buffer_add(layer, loc_, xpos, ypos,
image::get_image("whiteboard/suppose_dead.png", image::SCALED_TO_HEX));
#endif
}
}