diff --git a/src/display.cpp b/src/display.cpp index 6eb3d511e6ff..6407fbcd280a 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -979,7 +979,7 @@ static const std::string& get_direction(size_t n) return dirs[n >= dirs.size() ? 0 : n]; } -std::vector display::get_fog_shroud_images(const map_location& loc, image::TYPE image_type) +std::vector display::get_fog_shroud_images(const map_location& loc, image::TYPE image_type) { std::vector names; @@ -1057,12 +1057,14 @@ std::vector display::get_fog_shroud_images(const map_location& loc, ima } // now get the surfaces - std::vector res; + std::vector res; + res.reserve(names.size()); - for (std::string& name : names) { - const surface surf(image::get_image(name, image_type)); - if (surf) - res.push_back(surf); + for(std::string& name : names) { + texture tex(image::get_texture(name)); // TODO: image_type + if(tex) { + res.push_back(std::move(tex)); + } } return res; @@ -1404,6 +1406,7 @@ void display::draw_text_in_hex(const map_location& loc, } } } + drawing_buffer_add(layer, loc, x, y, text_surf); } @@ -1569,6 +1572,7 @@ void display::enable_menu(const std::string& item, bool enable) void display::announce(const std::string& message, const color_t& color, int lifetime) { font::remove_floating_label(prevLabel); + font::floating_label flabel(message); flabel.set_font_size(font::SIZE_XLARGE); flabel.set_color(color); @@ -2861,50 +2865,135 @@ void display::draw_invalidated() { } } -void display::draw_hex(const map_location& /*loc*/) + +// +// NEW RENDERING CODE ========================================================================= +// + +void display::draw_hex(const map_location& loc) { - return; + const int xpos = get_location_x(loc); + const int ypos = get_location_y(loc); - //int xpos = get_location_x(loc); - //int ypos = get_location_y(loc); + image::TYPE image_type = get_image_type(loc); - //image::TYPE image_type = get_image_type(loc); + const bool on_map = get_map().on_board(loc); + const time_of_day& tod = get_time_of_day(loc); - //const bool on_map = get_map().on_board(loc); - //const time_of_day& tod = get_time_of_day(loc); + const bool is_shrouded = shrouded(loc); + const bool is_fogged = fogged(loc); - //int num_images_fg = 0; - //int num_images_bg = 0; + // FIXME + if(dc_->teams().empty()) { + //return; + } - //if(!shrouded(loc)) { -#if 0 - std::vector images_fg = get_terrain_images(loc,tod.id, image_type, FOREGROUND); - std::vector images_bg = get_terrain_images(loc,tod.id, image_type, BACKGROUND); + // TODO: why is this created every time? + unit_drawer drawer = unit_drawer(*this); - if(images_fg.empty() && images_bg.empty()) { - return; + std::vector images_fg = get_terrain_images(loc, tod.id, image_type, FOREGROUND); + std::vector images_bg = get_terrain_images(loc, tod.id, image_type, BACKGROUND); + + // Some debug output + const int num_images_fg = images_fg.size(); + const int num_images_bg = images_bg.size(); + + if(!is_shrouded) { + // + // Background terrains + // + for(const texture& t : images_bg) { + render_scaled_to_zoom(t, xpos, ypos); } - num_images_fg = images_fg.size(); - num_images_bg = images_bg.size(); - for(auto& t : images_bg) { - //assert(t); + // + // Village flags + // + const texture& flag = get_flag(loc); + if(flag) { + render_scaled_to_zoom(flag, xpos, ypos); } - for(auto& t : images_fg) { - //assert(t); + } + + // + // Units + // + auto u_it = dc_->units().find(loc); + auto request = exclusive_unit_draw_requests_.find(loc); + + // Real units + if(u_it != dc_->units().end() && (request == exclusive_unit_draw_requests_.end() || request->second == u_it->id())) { + drawer.redraw_unit(*u_it); + } + + // Fake (moving) units + for(const unit* temp_unit : *fake_unit_man_) { + if(request == exclusive_unit_draw_requests_.end() || request->second == temp_unit->id()) { + drawer.redraw_unit(*temp_unit); } - // unshrouded terrain (the normal case) - if(!images_bg.empty()) { - drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_BG, loc, xpos, ypos, images_bg); - } else { - //std::cerr << "bg images empty" << std::endl; + } + + // + // Foreground terrains + // + if(!is_shrouded) { + for(const texture& t : images_fg) { + render_scaled_to_zoom(t, xpos, ypos); } + } - if(!images_fg.empty()) { - drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_FG, loc, xpos, ypos, images_fg); - } else { - //std::cerr << "fg images empty" << std::endl; + // + // Shroud and fog + // + if(is_shrouded || is_fogged) { + + // If is_shrouded is false, is_fogged is true + const std::string& weather_image = is_shrouded + ? get_variant(shroud_images_, loc) + : get_variant(fog_images_, loc); + + // TODO: image type + render_scaled_to_zoom(image::get_texture(weather_image), xpos, ypos); + } + + if(!is_shrouded) { + // TODO: + // std::vector fog_shroud_images = get_fog_shroud_images(loc, image_type); + } + + // + // Mouseover overlays (TODO: delegate to editor) + // +#if 0 + if(loc == mouseoverHex_ && (on_map || (in_editor() && get_map().on_board_with_border(loc))) + && mouseover_hex_overlay_ != nullptr) + { + render_scaled_to_zoom(mouseover_hex_overlay_, xpos, ypos); + } +#endif + + // + // Arrows + // + auto arrows_in_hex = arrows_map_.find(loc); + if(arrows_in_hex != arrows_map_.end()) { + for(arrow* const a : arrows_in_hex->second) { + a->draw_hex(loc); } + } + + // + // Hex cursor (TODO: split into layers) + // + if(on_map && loc == mouseoverHex_) { + draw_hex_cursor(loc); + } + + // + // TODO + // + //if(!shrouded(loc)) { +#if 0 // Draw the grid, if that's been enabled if(grid_) { @@ -2918,9 +3007,7 @@ void display::draw_hex(const map_location& /*loc*/) // village-control flags. //drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_BG, loc, xpos, ypos, get_flag(loc)); //} -#endif -#if 0 if(!shrouded(loc)) { typedef overlay_map::const_iterator Itor; std::pair overlays = overlays_->equal_range(loc); @@ -2963,38 +3050,8 @@ void display::draw_hex(const map_location& /*loc*/) 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(drawing_buffer::LAYER_MOUSEOVER_OVERLAY, loc, xpos, ypos, mouseover_hex_overlay_); - } - - // Paint arrows - arrows_map_t::const_iterator arrows_in_hex = arrows_map_.find(loc); - if(arrows_in_hex != arrows_map_.end()) { - for (arrow* const a : arrows_in_hex->second) { - a->draw_hex(loc); - } - } - // Apply shroud, fog and linger overlay - 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(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(drawing_buffer::LAYER_FOG_SHROUD, loc, xpos, ypos, - image::get_image(fog_image, image_type)); - } - - if(!shrouded(loc)) { - drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, xpos, ypos, get_fog_shroud_images(loc, image_type)); - } - if (on_map) { if (draw_coordinates_) { int off_x = xpos + hex_size()/2; @@ -3058,138 +3115,31 @@ void display::draw_hex(const map_location& /*loc*/) #endif } - -// -// NEW RENDERING CODE ========================================================================= -// - -//template -////void display::render_scaled_to_zoom(const texture& tex, const int x_pos, const int y_pos, T&&... extra_args) - - -void display::draw_gamemap() -{ - SDL_Rect area = map_area(); - render_clip_rect_setter setter(&area); - - // TODO: ToD coloring of terrains. - - // The unit drawer can't function without teams. - // FIXME - if(dc_->teams().empty()) { - //return; - } - - // TODO: why is this created every time? - unit_drawer drawer = unit_drawer(*this); - - for(const map_location& loc : get_visible_hexes()) { - const int xpos = get_location_x(loc); - const int ypos = get_location_y(loc); - - image::TYPE image_type = get_image_type(loc); - - const bool on_map = get_map().on_board(loc); - const time_of_day& tod = get_time_of_day(loc); - - // TODO: - //if(shrouded(loc))) { - // return; - //} - - std::vector images_fg = get_terrain_images(loc, tod.id, image_type, FOREGROUND); - std::vector images_bg = get_terrain_images(loc, tod.id, image_type, BACKGROUND); - - // - // Background terrains - // - for(const texture& t : images_bg) { - render_scaled_to_zoom(t, xpos, ypos); - } - - // - // Village flags - // - texture flag = get_flag(loc); - if(flag) { - render_scaled_to_zoom(flag, xpos, ypos); - } - - // - // Units - // - auto u_it = dc_->units().find(loc); - auto request = exclusive_unit_draw_requests_.find(loc); - - // Real units - if(u_it != dc_->units().end() && (request == exclusive_unit_draw_requests_.end() || request->second == u_it->id())) { - drawer.redraw_unit(*u_it); - } - - // Fake (moving) units - for(const unit* temp_unit : *fake_unit_man_) { - if(request == exclusive_unit_draw_requests_.end() || request->second == temp_unit->id()) { - drawer.redraw_unit(*temp_unit); - } - } - - // - // Foreground terrains - // - for(const texture& t : images_fg) { - render_scaled_to_zoom(t, xpos, ypos); - } - - // - // Mouseover overlays - // -#if 0 - if(loc == mouseoverHex_ && (on_map || (in_editor() && get_map().on_board_with_border(loc))) - && mouseover_hex_overlay_ != nullptr) - { - render_scaled_to_zoom(mouseover_hex_overlay_, xpos, ypos); - } -#endif - - // - // Arrows - // - auto arrows_in_hex = arrows_map_.find(loc); - if(arrows_in_hex != arrows_map_.end()) { - for(arrow* const a : arrows_in_hex->second) { - a->draw_hex(loc); - } - } - - // - // Hex cursor (TODO: split into layers) - // - if(on_map && loc == mouseoverHex_) { - draw_hex_cursor(loc); - } - } -} - void display::draw_new() { // Execute any pre-draw actions from derived classes. pre_draw(); // Draw theme background. - const SDL_Rect area = map_outside_area(); - draw_background(area, theme_.border().background_image); + const SDL_Rect outside_area = map_outside_area(); + draw_background(outside_area, theme_.border().background_image); // Progress animations. invalidate_animations(); + draw_all_panels(); + draw_minimap(); + + SDL_Rect map_area_rect = map_area(); + render_clip_rect_setter setter(&map_area_rect); + // Draw the gamemap and its contents (units, etc); - draw_gamemap(); + for(const map_location& loc : get_visible_hexes()) { + draw_hex(loc); + } post_commit(); - draw_all_panels(); - draw_minimap(); - // Draw map labels. font::draw_floating_labels(); @@ -3201,8 +3151,9 @@ void display::draw_new() draw_debugging_aids(); // Call any redraw observers. + // FIXME: makes the editor slow. for(std::function f : redraw_observers_) { - f(*this); + // f(*this); } // Execute any post-draw actions from derived classes. diff --git a/src/display.hpp b/src/display.hpp index 4f8c7bcb9355..e175b605df06 100644 --- a/src/display.hpp +++ b/src/display.hpp @@ -725,8 +725,6 @@ class display : public filter_context, public video2::draw_layering */ virtual void draw_sidebar() {} - void draw_gamemap(); - void draw_minimap(); enum TERRAIN_TYPE { BACKGROUND, FOREGROUND}; @@ -736,7 +734,7 @@ class display : public filter_context, public video2::draw_layering image::TYPE type, TERRAIN_TYPE terrain_type); - std::vector get_fog_shroud_images(const map_location& loc, image::TYPE image_type); + std::vector get_fog_shroud_images(const map_location& loc, image::TYPE image_type); void draw_image_for_report(surface& img, SDL_Rect& rect); diff --git a/src/game_display.cpp b/src/game_display.cpp index 0b51dba7343e..fdae1bb66f6d 100644 --- a/src/game_display.cpp +++ b/src/game_display.cpp @@ -221,11 +221,14 @@ void game_display::scroll_to_leader(int side, SCROLL_TYPE scroll_type,bool force } } -void game_display::pre_draw() { - if (std::shared_ptr w = wb_.lock()) { +void game_display::pre_draw() +{ + if(std::shared_ptr w = wb_.lock()) { w->pre_draw(); } + process_reachmap_changes(); + /** * @todo FIXME: must modify changed, but best to do it at the * floating_label level @@ -233,8 +236,8 @@ void game_display::pre_draw() { chat_man_->prune_chat_messages(); } - -void game_display::post_draw() { +void game_display::post_draw() +{ if (std::shared_ptr w = wb_.lock()) { w->post_draw(); } @@ -242,6 +245,8 @@ void game_display::post_draw() { void game_display::draw_invalidated() { + return; // DONE + halo_man_->unrender(invalidated_); display::draw_invalidated(); if (fake_unit_man_->empty()) { @@ -291,12 +296,12 @@ void game_display::draw_hex_cursor(const map_location& loc) fg_path = "misc/hover-hex-bottom.png~RC(magenta>lightblue)"; } - texture cursor_bg = image::get_texture(image::locator(bg_path)); + texture cursor_bg = image::get_texture(bg_path); if(cursor_bg) { render_scaled_to_zoom(cursor_bg, xpos, ypos); } - texture cursor_fg = image::get_texture(image::locator(fg_path)); + texture cursor_fg = image::get_texture(fg_path); if(cursor_fg) { render_scaled_to_zoom(cursor_fg, xpos, ypos); } @@ -304,16 +309,17 @@ void game_display::draw_hex_cursor(const map_location& loc) void game_display::draw_hex(const map_location& loc) { - return; + // Inherited. + display::draw_hex(loc); + const bool on_map = get_map().on_board(loc); const bool is_shrouded = shrouded(loc); -// const bool is_fogged = fogged(loc); + //const bool is_fogged = fogged(loc); + const int xpos = get_location_x(loc); const int ypos = get_location_y(loc); -// image::TYPE image_type = get_image_type(loc); - - display::draw_hex(loc); + //image::TYPE image_type = get_image_type(loc); if(cursor::get() == cursor::WAIT) { // Interaction is disabled, so we don't need anything else @@ -351,17 +357,19 @@ void game_display::draw_hex(const map_location& loc) } #endif - // Draw reach_map information. - // We remove the reachability mask of the unit - // that we want to attack. - 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(drawing_buffer::LAYER_REACHMAP, loc, xpos, ypos, - image::get_image(unreachable,image::SCALED_TO_HEX)); + // We remove the reachability mask of the unit that we want to attack. + if(!is_shrouded && !reach_map_.empty() + && reach_map_.find(loc) == reach_map_.end() && loc != attack_indicator_dst_) + { + static texture unreachable = image::get_texture(game_config::images::unreachable); + static texture::info info = unreachable.get_info(); + + SDL_Rect dst {xpos, ypos, info.w, info.h}; + video().render_copy(unreachable, nullptr, &dst); // SCALED_TO_HEX } +#if 0 if (std::shared_ptr w = wb_.lock()) { w->draw_hex(loc); @@ -373,29 +381,43 @@ void game_display::draw_hex(const map_location& loc) } } } +#endif + // Draw the attack direction indicator + // TODO: SCALED_TO_HEX if(on_map && loc == attack_indicator_src_) { - 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(drawing_buffer::LAYER_ATTACK_INDICATOR, loc, xpos, ypos, - image::get_image("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX)); + texture indicator = image::get_texture("misc/attack-indicator-src-" + attack_indicator_direction() + ".png"); + texture::info info = indicator.get_info(); + + SDL_Rect dst {xpos, ypos, info.w, info.h}; + video().render_copy(indicator, nullptr, &dst); + } else if(on_map && loc == attack_indicator_dst_) { + texture indicator = image::get_texture("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png"); + texture::info info = indicator.get_info(); + + SDL_Rect dst {xpos, ypos, info.w, info.h}; + video().render_copy(indicator, nullptr, &dst); } // Linger overlay unconditionally otherwise it might give glitches // so it's drawn over the shroud and fog. if(mode_ != RUNNING) { - static const image::locator linger(game_config::images::linger); - drawing_buffer_add(drawing_buffer::LAYER_LINGER_OVERLAY, loc, xpos, ypos, - image::get_image(linger, image::TOD_COLORED)); + static texture linger = image::get_texture(game_config::images::linger); + static texture::info info = linger.get_info(); + + SDL_Rect dst {xpos, ypos, info.w, info.h}; + video().render_copy(linger, nullptr, &dst); // TOD_COLORED } if(on_map && loc == selectedHex_ && !game_config::images::selected.empty()) { - static const image::locator selected(game_config::images::selected); - drawing_buffer_add(drawing_buffer::LAYER_SELECTED_HEX, loc, xpos, ypos, - image::get_image(selected, image::SCALED_TO_HEX)); + static texture selected = image::get_texture(game_config::images::selected); + static texture::info info = selected.get_info(); + + SDL_Rect dst {xpos, ypos, info.w, info.h}; + video().render_copy(selected, nullptr, &dst); // SCALED_TO_HEX } +#if 0 // Show def% and turn to reach info if(!is_shrouded && on_map) { draw_movement_info(loc); @@ -408,7 +430,9 @@ void game_display::draw_hex(const map_location& loc) draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, txt, 18, font::BAD_COLOR); } } + //simulate_delay += 1; +#endif } const time_of_day& game_display::get_time_of_day(const map_location& loc) const @@ -442,7 +466,6 @@ void game_display::draw_sidebar() } } - void game_display::set_game_mode(const game_mode mode) { if(mode != mode_) { @@ -459,11 +482,11 @@ void game_display::draw_movement_info(const map_location& loc) std::shared_ptr wb = wb_.lock(); // Don't use empty route or the first step (the unit will be there) - if(w != route_.marks.end() - && !route_.steps.empty() && route_.steps.front() != loc) { - const unit_map::const_iterator un = - (wb && wb->get_temp_move_unit().valid()) ? - wb->get_temp_move_unit() : dc_->units().find(route_.steps.front()); + if(w != route_.marks.end() && !route_.steps.empty() && route_.steps.front() != loc) { + const unit_map::const_iterator un = (wb && wb->get_temp_move_unit().valid()) + ? wb->get_temp_move_unit() + : dc_->units().find(route_.steps.front()); + if(un != dc_->units().end()) { // Display the def% of this terrain int def = 100 - un->defense_modifier(get_map().get_terrain(loc)); @@ -504,6 +527,7 @@ void game_display::draw_movement_info(const map_location& loc) return; } } + // When out-of-turn, it's still interesting to check out the terrain defs of the selected unit else if (selectedHex_.valid() && loc == mouseoverHex_) { @@ -523,9 +547,9 @@ void game_display::draw_movement_info(const map_location& loc) } } - if (!reach_map_.empty()) { + if(!reach_map_.empty()) { reach_map::iterator reach = reach_map_.find(loc); - if (reach != reach_map_.end() && reach->second > 1) { + if(reach != reach_map_.end() && reach->second > 1) { const std::string num = std::to_string(reach->second); draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, num, 16, font::YELLOW_COLOR); } diff --git a/src/units/drawer.cpp b/src/units/drawer.cpp index 87342b532bd7..428c7332ae81 100644 --- a/src/units/drawer.cpp +++ b/src/units/drawer.cpp @@ -226,8 +226,8 @@ void unit_drawer::redraw_unit(const unit & u) const ellipse << "-" << leader << nozoc << selected << "bottom.png~RC(ellipse_red>" << tc << ")"; // Load the ellipse parts recolored to match team color - ellipse_back = image::get_texture(image::locator(ellipse_top) /*, image::SCALED_TO_ZOOM)*/); - ellipse_front = image::get_texture(image::locator(ellipse_bot) /*, image::SCALED_TO_ZOOM)*/); + ellipse_back = image::get_texture(ellipse_top /*, image::SCALED_TO_ZOOM)*/); + ellipse_front = image::get_texture(ellipse_bot /*, image::SCALED_TO_ZOOM)*/); } }