mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-15 17:25:32 +00:00
764 lines
24 KiB
C++
764 lines
24 KiB
C++
/* $Id$ */
|
|
/*
|
|
Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
|
|
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License version 2
|
|
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.
|
|
*/
|
|
|
|
/**
|
|
* @file display.hpp
|
|
*
|
|
* map_display and display: classes which take care of
|
|
* displaying the map and game-data on the screen.
|
|
*
|
|
* The display is divided into two main sections:
|
|
* - the game area, which displays the tiles of the game board, and units on them,
|
|
* - and the side bar, which appears on the right hand side.
|
|
* The side bar display is divided into three sections:
|
|
* - the minimap, which is displayed at the top right
|
|
* - the game status, which includes the day/night image,
|
|
* the turn number, information about the current side,
|
|
* and information about the hex currently moused over (highlighted)
|
|
* - the unit status, which displays an image and stats
|
|
* for the current unit.
|
|
*/
|
|
|
|
#ifndef DISPLAY_H_INCLUDED
|
|
#define DISPLAY_H_INCLUDED
|
|
|
|
class config;
|
|
class gamestatus;
|
|
class team;
|
|
class unit;
|
|
class unit_map;
|
|
|
|
#include "builder.hpp"
|
|
#include "generic_event.hpp"
|
|
#include "image.hpp"
|
|
#include "key.hpp"
|
|
#include "map.hpp"
|
|
#include "map_label.hpp"
|
|
#include "reports.hpp"
|
|
#include "time_of_day.hpp"
|
|
#include "theme.hpp"
|
|
#include "video.hpp"
|
|
#include "widgets/button.hpp"
|
|
|
|
#include "SDL.h"
|
|
|
|
#include <map>
|
|
#include <set>
|
|
#include <string>
|
|
|
|
|
|
class display
|
|
{
|
|
public:
|
|
display(CVideo& video, const gamemap& map, const config& theme_cfg,
|
|
const config& cfg, const config& level);
|
|
virtual ~display();
|
|
|
|
static Uint32 rgb(Uint8 red, Uint8 green, Uint8 blue)
|
|
{ return 0xFF000000 | (red << 16) | (green << 8) | blue; }
|
|
|
|
/** Gets the underlying screen object. */
|
|
CVideo& video() { return screen_; }
|
|
|
|
/** return the screen surface or the surface used for map_screenshot. */
|
|
surface get_screen_surface() { return map_screenshot_ ? map_screenshot_surf_ : screen_.getSurface();}
|
|
|
|
virtual bool in_game() const { return false; }
|
|
virtual bool in_editor() const { return false; }
|
|
|
|
/**
|
|
* the dimensions of the display. x and y are width/height.
|
|
* mapx is the width of the portion of the display which shows the game area.
|
|
* Between mapx and x is the sidebar region.
|
|
*/
|
|
int w() const { return screen_.getx(); } /**< width */
|
|
int h() const { return screen_.gety(); } /**< height */
|
|
const SDL_Rect& minimap_area() const
|
|
{ return theme_.mini_map_location(screen_area()); }
|
|
const SDL_Rect& unit_image_area() const
|
|
{ return theme_.unit_image_location(screen_area()); }
|
|
|
|
SDL_Rect screen_area() const
|
|
{ const SDL_Rect res = {0,0,w(),h()}; return res; }
|
|
|
|
/**
|
|
* Returns the maximum area used for the map
|
|
* regardless to resolution and view size
|
|
*/
|
|
const SDL_Rect& max_map_area() const;
|
|
|
|
/**
|
|
* Returns the area used for the map
|
|
*/
|
|
const SDL_Rect& map_area() const;
|
|
|
|
/**
|
|
* Returns the available area for a map, this may differ
|
|
* from the above. This area will get the background area
|
|
* applied to it.
|
|
*/
|
|
const SDL_Rect& map_outside_area() const { return map_screenshot_ ?
|
|
max_map_area() : theme_.main_map_location(screen_area()); }
|
|
|
|
/** Check if the bbox of the hex at x,y has pixels outside the area rectangle. */
|
|
bool outside_area(const SDL_Rect& area, const int x,const int y) const;
|
|
|
|
/**
|
|
* Function which returns the width of a hex in pixels,
|
|
* up to where the next hex starts.
|
|
* (i.e. not entirely from tip to tip -- use hex_size()
|
|
* to get the distance from tip to tip)
|
|
*/
|
|
int hex_width() const { return (zoom_*3)/4; }
|
|
|
|
/**
|
|
* Function which returns the size of a hex in pixels
|
|
* (from top tip to bottom tip or left edge to right edge).
|
|
*/
|
|
int hex_size() const { return zoom_; }
|
|
|
|
/** Returns the current zoom factor. */
|
|
double get_zoom_factor() { return double(zoom_)/double(image::tile_size); }
|
|
|
|
/**
|
|
* given x,y co-ordinates of an onscreen pixel, will return the
|
|
* location of the hex that this pixel corresponds to.
|
|
* Returns an invalid location if the mouse isn't over any valid location.
|
|
*/
|
|
const gamemap::location hex_clicked_on(int x, int y,
|
|
gamemap::location::DIRECTION* nearest_hex=NULL,
|
|
gamemap::location::DIRECTION* second_nearest_hex=NULL) const;
|
|
|
|
/**
|
|
* given x,y co-ordinates of a pixel on the map, will return the
|
|
* location of the hex that this pixel corresponds to.
|
|
* Returns an invalid location if the mouse isn't over any valid location.
|
|
*/
|
|
const gamemap::location pixel_position_to_hex(int x, int y,
|
|
gamemap::location::DIRECTION* nearest_hex=NULL,
|
|
gamemap::location::DIRECTION* second_nearest_hex=NULL) const;
|
|
|
|
/**
|
|
* given x,y co-ordinates of the mouse, will return the location of the
|
|
* hex in the minimap that the mouse is currently over, or an invalid
|
|
* location if the mouse isn't over the minimap.
|
|
*/
|
|
gamemap::location minimap_location_on(int x, int y);
|
|
|
|
const gamemap::location& selected_hex() { return selectedHex_; }
|
|
const gamemap::location& mouseover_hex() { return mouseoverHex_; }
|
|
|
|
virtual void select_hex(gamemap::location hex);
|
|
virtual void highlight_hex(gamemap::location hex);
|
|
|
|
/** Function to invalidate the game status displayed on the sidebar. */
|
|
void invalidate_game_status() { invalidateGameStatus_ = true; }
|
|
|
|
/** Functions to get the on-screen positions of hexes. */
|
|
int get_location_x(const gamemap::location& loc) const;
|
|
int get_location_y(const gamemap::location& loc) const;
|
|
|
|
/**
|
|
* Rectangular area of hexes, allowing to decide how the top and bottom
|
|
* edges handles the vertical shift for each parity of the x coordinate
|
|
*/
|
|
struct rect_of_hexes{
|
|
int left;
|
|
int right;
|
|
int top[2]; // for even and odd values of x, respectively
|
|
int bottom[2];
|
|
|
|
/** very simple iterator to walk into the rect_of_hexes */
|
|
struct iterator {
|
|
iterator(gamemap::location loc, rect_of_hexes& rect)
|
|
: loc_(loc), rect_(rect){};
|
|
|
|
/** increment y first, then when reaching bottom, increment x */
|
|
void operator++();
|
|
bool operator!=(const iterator &that) const {return that.loc_ != loc_;};
|
|
const gamemap::location& operator*() const {return loc_;};
|
|
|
|
private:
|
|
gamemap::location loc_;
|
|
rect_of_hexes& rect_;
|
|
};
|
|
|
|
iterator begin();
|
|
iterator end();
|
|
};
|
|
|
|
/** Return the rectangular area of hexes overlapped by r (r is in screen coordinates) */
|
|
const rect_of_hexes hexes_under_rect(const SDL_Rect& r) const;
|
|
|
|
/** Returns the rectangular area of visible hexes */
|
|
const rect_of_hexes get_visible_hexes() const {return hexes_under_rect(map_area());};
|
|
|
|
/** Returns true if location (x,y) is covered in shroud. */
|
|
bool shrouded(const gamemap::location& loc) const {
|
|
return viewpoint_ && viewpoint_->shrouded(loc);
|
|
}
|
|
/** Returns true if location (x,y) is covered in fog. */
|
|
bool fogged(const gamemap::location& loc) const {
|
|
return viewpoint_ && viewpoint_->fogged(loc);
|
|
}
|
|
|
|
/**
|
|
* Determines whether a grid should be overlayed on the game board.
|
|
* (to more clearly show where hexes are)
|
|
*/
|
|
void set_grid(const bool grid) { grid_ = grid; }
|
|
|
|
/** Save a (map-)screenshot and return the estimated file size */
|
|
int screenshot(std::string filename, bool map_screenshot = false);
|
|
|
|
/** Invalidates entire screen, including all tiles and sidebar. */
|
|
void redraw_everything();
|
|
|
|
theme& get_theme() { return theme_; }
|
|
gui::button* find_button(const std::string& id);
|
|
gui::button::TYPE string_to_button_type(std::string type);
|
|
void create_buttons();
|
|
void invalidate_theme() { panelsDrawn_ = false; }
|
|
|
|
void refresh_report(reports::TYPE report_num, reports::report report,
|
|
bool brightened = false);
|
|
|
|
// Will be overridden in the display subclass
|
|
virtual void draw_minimap_units() {};
|
|
|
|
/** Function to invalidate all tiles. */
|
|
void invalidate_all();
|
|
|
|
/** Function to invalidate a specific tile for redrawing. */
|
|
bool invalidate(const gamemap::location& loc);
|
|
|
|
/** invalidate all hexes under the rectangle rect (in screen coordinates) */
|
|
bool invalidate_locations_in_rect(const SDL_Rect& rect);
|
|
|
|
/** check if an hexes under the rectangle is invalidated */
|
|
bool rectangle_need_update(const SDL_Rect& rect) const;
|
|
|
|
/**
|
|
* Function to invalidate animated terrains which may have changed.
|
|
*/
|
|
virtual void invalidate_animations();
|
|
|
|
/**
|
|
* Per-location invalidation called by invalidate_animations()
|
|
* defaults to no action, overriden by derived classes
|
|
*/
|
|
virtual void invalidate_animations_location(const gamemap::location& /*loc*/) {}
|
|
|
|
const gamemap& get_map()const { return map_;}
|
|
|
|
/**
|
|
* The last action in drawing a tile is adding the overlays.
|
|
* These overlays are drawn in the following order:
|
|
* hex_overlay_ if the drawn location is in the map
|
|
* selected_hex_overlay_ if the drawn location is selected
|
|
* mouseover_hex_overlay_ if the drawn location is underneath the mouse
|
|
*
|
|
* These functions require a prerendered surface.
|
|
* Since they are drawn at the top, they are not influenced by TOD, shroud etc.
|
|
*/
|
|
void set_hex_overlay(const gamemap::location& loc, surface image) { hex_overlay_[loc] = image; }
|
|
void clear_hex_overlay(const gamemap::location& loc);
|
|
|
|
void set_selected_hex_overlay(const surface& image) { selected_hex_overlay_ = image; }
|
|
void clear_selected_hex_overlay() { selected_hex_overlay_ = NULL; }
|
|
|
|
void set_mouseover_hex_overlay(const surface& image) { mouseover_hex_overlay_ = image; }
|
|
void clear_mouseover_hex_overlay() { mouseover_hex_overlay_ = NULL; }
|
|
|
|
/**
|
|
* Debug function to toggle the "sunset" mode.
|
|
* The map area become progressively darker,
|
|
* except where hexes are refreshed.
|
|
* delay is the number of frames between each darkening
|
|
* (0 to toggle).
|
|
*/
|
|
void sunset(const size_t delay = 0);
|
|
|
|
/** Toogle to continuously redraw the screen. */
|
|
void toggle_benchmark();
|
|
|
|
void flip();
|
|
|
|
/** Copy the backbuffer to the framebuffer. */
|
|
void update_display();
|
|
|
|
/** Rebuild all dynamic terrain. */
|
|
void rebuild_all() { builder_.rebuild_all(); }
|
|
|
|
/**
|
|
* Draw the image of a unit at a certain location.
|
|
* x,y: pixel location on screen to draw the unit
|
|
* image: the image of the unit
|
|
* reverse: if the unit should be flipped across the x axis
|
|
* greyscale: used when the unit is stoned
|
|
* alpha: the merging to use with the background
|
|
* blendto: blend to this colour using blend_ratio
|
|
* submerged: the amount of the unit out of 1.0 that is submerged
|
|
* (presumably under water) and thus shouldn't be drawn
|
|
*/
|
|
void render_unit_image(int x, int y, const bool fake_unit,
|
|
const int drawing_order, surface image,
|
|
bool hreverse=false, bool greyscale=false,
|
|
fixed_t alpha=ftofxp(1.0), Uint32 blendto=0,
|
|
double blend_ratio=0, double submerged=0.0,bool vreverse =false);
|
|
|
|
const theme::menu* menu_pressed();
|
|
|
|
/**
|
|
* Finds the menu which has a given item in it,
|
|
* and enables or disables it.
|
|
*/
|
|
void enable_menu(const std::string& item, bool enable);
|
|
|
|
void set_diagnostic(const std::string& msg);
|
|
|
|
/** Delay routines: use these not SDL_Delay (for --nogui). */
|
|
void delay(unsigned int milliseconds) const;
|
|
|
|
/**
|
|
* Set/Get whether 'turbo' mode is on.
|
|
* When turbo mode is on, everything moves much faster.
|
|
*/
|
|
void set_turbo(const bool turbo) { turbo_ = turbo; }
|
|
|
|
double turbo_speed() const;
|
|
|
|
void set_turbo_speed(const double speed) { turbo_speed_ = speed; }
|
|
|
|
/** control unit idle animations and their frequency */
|
|
void set_idle_anim(bool ison) { idle_anim_ = ison; }
|
|
bool idle_anim() const { return idle_anim_; }
|
|
void set_idle_anim_rate(int rate);
|
|
double idle_anim_rate() const { return idle_anim_rate_; }
|
|
|
|
/**
|
|
* Add a location to highlight.
|
|
*
|
|
* Note that this has nothing to do with selecting hexes,
|
|
* it is pure highlighting. These hexes will be highlighted
|
|
* slightly darker than the currently selected hex.
|
|
*/
|
|
void add_highlighted_loc(const gamemap::location &hex);
|
|
|
|
void clear_highlighted_locs();
|
|
|
|
void remove_highlighted_loc(const gamemap::location &hex);
|
|
|
|
void bounds_check_position();
|
|
void bounds_check_position(int& xpos, int& ypos);
|
|
|
|
/**
|
|
* Scrolls the display by xmov,ymov pixels.
|
|
* Invalidation and redrawing will be scheduled.
|
|
*/
|
|
void scroll(int xmov, int ymov);
|
|
|
|
/**
|
|
* Zooms the display by the specified amount.
|
|
* Negative values zoom out.
|
|
* Note the amount should be a multiple of four,
|
|
* otherwise the images might start to look odd
|
|
* (hex_width() gets rounding errors).
|
|
*/
|
|
void set_zoom(int amount);
|
|
|
|
/** Sets the zoom amount to the default. */
|
|
void set_default_zoom();
|
|
|
|
enum SCROLL_TYPE { SCROLL, WARP, ONSCREEN };
|
|
|
|
/**
|
|
* Scroll such that location loc is on-screen.
|
|
* WARP jumps to loc; SCROLL uses scroll speed;
|
|
* ONSCREEN only scrolls if x,y is offscreen
|
|
*/
|
|
void scroll_to_tile(const gamemap::location& loc, SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true);
|
|
|
|
/**
|
|
* Scroll such that location loc1 is on-screen.
|
|
* It will also try to make it such that loc2 is on-screen,
|
|
* but this is not guaranteed. For ONSCREEN scrolls add_spacing
|
|
* sets the desired minimum distance from the border in hexes.
|
|
*/
|
|
void scroll_to_tiles(gamemap::location loc1, gamemap::location loc2,
|
|
SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true,
|
|
double add_spacing=0.0);
|
|
|
|
/** Scroll to fit as many locations on-screen as possible, starting with the first. */
|
|
void scroll_to_tiles(const std::vector<gamemap::location>& locs,
|
|
SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true,
|
|
bool only_if_possible=false,
|
|
double add_spacing=0.0);
|
|
|
|
/** Expose the event, so observers can be notified about map scrolling. */
|
|
events::generic_event &scroll_event() const { return _scroll_event; }
|
|
|
|
/** Check if a tile is fully on screen. */
|
|
bool tile_on_screen(const gamemap::location& loc);
|
|
|
|
/**
|
|
* Draws invalidated items.
|
|
* If update is true, will also copy the display to the frame buffer.
|
|
* If force is true, will not skip frames, even if running behind.
|
|
* Not virtual, since it gathers common actions. Calls various protected
|
|
* virtuals (further below) to allow specialized behaviour in derived classes.
|
|
*/
|
|
void draw(bool update=true, bool force=false);
|
|
|
|
map_labels& labels() { return map_labels_; }
|
|
const map_labels& labels() const { return map_labels_; }
|
|
|
|
/** Announce a message prominently. */
|
|
void announce(const std::string msg,
|
|
const SDL_Color& colour = font::GOOD_COLOUR);
|
|
|
|
/**
|
|
* Schedule the minimap for recalculation.
|
|
* Useful if any terrain in the map has changed.
|
|
*/
|
|
void recalculate_minimap() {minimap_ = NULL; redrawMinimap_ = true; };
|
|
|
|
/**
|
|
* Schedule the minimap to be redrawn.
|
|
* Useful if units have moved about on the map.
|
|
*/
|
|
void redraw_minimap() { redrawMinimap_ = true; }
|
|
|
|
/**
|
|
* Set what will be shown for the report with type which_report.
|
|
* Note that this only works for some reports,
|
|
* i.e. reports that can not be deducted
|
|
* from the supplied arguments to generate_report,
|
|
* currently: SELECTED_TERRAIN, EDIT_LEFT_BUTTON_FUNCTION
|
|
*/
|
|
void set_report_content(const reports::TYPE which_report, const std::string &content);
|
|
std::map<reports::TYPE, std::string> get_report_contents() {return report_;};
|
|
|
|
protected:
|
|
/** Clear the screen contents */
|
|
void clear_screen();
|
|
|
|
/**
|
|
* Called near the beginning of each draw() call.
|
|
* Derived classes can use this to add extra actions before redrawing
|
|
* invalidated hexes takes place. No action here by default.
|
|
*/
|
|
virtual void pre_draw() {}
|
|
|
|
/**
|
|
* Get the clipping rectangle for drawing.
|
|
* Virtual since the editor might use a slightly different approach.
|
|
*/
|
|
virtual const SDL_Rect& get_clip_rect();
|
|
|
|
/**
|
|
* Only called when there's actual redrawing to do. Loops through
|
|
* invalidated locations and redraws them. Derived classes can override
|
|
* this, possibly to insert pre- or post-processing around a call to the
|
|
* base class's function.
|
|
*/
|
|
virtual void draw_invalidated();
|
|
|
|
/**
|
|
* Hook for actions to take right after draw() calls drawing_buffer_commit
|
|
* No action here by default.
|
|
*/
|
|
virtual void post_commit() {}
|
|
|
|
/**
|
|
* Redraws a single gamemap location.
|
|
*/
|
|
virtual void draw_hex(const gamemap::location& loc);
|
|
|
|
/**
|
|
* @returns the image type to be used for the passed hex
|
|
* (mostly to do with brightening like for mouseover)
|
|
*/
|
|
virtual image::TYPE get_image_type(const gamemap::location& loc);
|
|
|
|
/**
|
|
* Update time of day member to the tod to be used in the current drawing
|
|
*/
|
|
virtual void update_time_of_day();
|
|
|
|
/**
|
|
* Called near the end of a draw operation, derived classes can use this
|
|
* to render a specific sidebar. Very similar to post_commit.
|
|
*/
|
|
virtual void draw_sidebar();
|
|
|
|
/**
|
|
* Draws the border tile overlay.
|
|
* The routine determines by itself which border it is on
|
|
* and draws an overlay accordingly. The definition of the
|
|
* border is stored in the 'main_map_border' part of the theme.
|
|
*
|
|
* @param loc the map location of the tile
|
|
* @param xpos the on-screen pixels x coordinate of the tile
|
|
* @param ypos the on-screen pixels y coordinate of the tile
|
|
*/
|
|
virtual void draw_border(const gamemap::location& loc,
|
|
const int xpos, const int ypos);
|
|
|
|
void draw_minimap();
|
|
|
|
enum ADJACENT_TERRAIN_TYPE { ADJACENT_BACKGROUND, ADJACENT_FOREGROUND, ADJACENT_FOGSHROUD };
|
|
|
|
std::vector<surface> get_terrain_images(const gamemap::location &loc,
|
|
const std::string timeid,
|
|
image::TYPE type,
|
|
ADJACENT_TERRAIN_TYPE terrain_type);
|
|
|
|
std::vector<std::string> get_fog_shroud_graphics(const gamemap::location& loc);
|
|
|
|
void draw_image_for_report(surface& img, SDL_Rect& rect);
|
|
|
|
void scroll_to_xy(int screenxpos, int screenypos, SCROLL_TYPE scroll_type);
|
|
|
|
CVideo& screen_;
|
|
const gamemap& map_;
|
|
const viewpoint *viewpoint_;
|
|
int xpos_, ypos_;
|
|
theme theme_;
|
|
int zoom_;
|
|
int last_zoom_;
|
|
terrain_builder builder_;
|
|
surface minimap_;
|
|
SDL_Rect minimap_location_;
|
|
bool redrawMinimap_;
|
|
bool redraw_background_;
|
|
bool invalidateAll_;
|
|
bool grid_;
|
|
int diagnostic_label_;
|
|
bool panelsDrawn_;
|
|
double turbo_speed_;
|
|
bool turbo_;
|
|
bool invalidateGameStatus_;
|
|
map_labels map_labels_;
|
|
std::string shroud_image_;
|
|
std::string fog_image_;
|
|
time_of_day tod_;
|
|
|
|
/** Event raised when the map is being scrolled */
|
|
mutable events::generic_event _scroll_event;
|
|
|
|
/**
|
|
* Holds the tick count for when the next drawing event is scheduled.
|
|
* Drawing shouldn't occur before this time.
|
|
*/
|
|
int nextDraw_;
|
|
|
|
// Not set by the initializer:
|
|
SDL_Rect reportRects_[reports::NUM_REPORTS];
|
|
surface reportSurfaces_[reports::NUM_REPORTS];
|
|
reports::report reports_[reports::NUM_REPORTS];
|
|
std::map<reports::TYPE, std::string> report_;
|
|
std::vector<gui::button> buttons_;
|
|
std::set<gamemap::location> invalidated_;
|
|
std::map<gamemap::location, surface> hex_overlay_;
|
|
surface selected_hex_overlay_;
|
|
surface mouseover_hex_overlay_;
|
|
gamemap::location selectedHex_;
|
|
gamemap::location mouseoverHex_;
|
|
std::set<gamemap::location> highlighted_locations_;
|
|
CKey keys_;
|
|
|
|
public:
|
|
/** Helper structure for rendering the terrains. */
|
|
struct tblit{
|
|
tblit(const int x, const int y) :
|
|
x(x),
|
|
y(y),
|
|
surf(),
|
|
clip()
|
|
{}
|
|
|
|
tblit(const int x, const int y, const surface& surf,
|
|
const SDL_Rect& clip = SDL_Rect()) :
|
|
x(x),
|
|
y(y),
|
|
surf(1, surf),
|
|
clip(clip)
|
|
{}
|
|
|
|
tblit(const int x, const int y, const std::vector<surface>& surf,
|
|
const SDL_Rect& clip = SDL_Rect()) :
|
|
x(x),
|
|
y(y),
|
|
surf(surf),
|
|
clip(clip)
|
|
{}
|
|
|
|
|
|
int x; /**< x screen coordinate to render at. */
|
|
int y; /**< y screen coordinate to render at. */
|
|
std::vector<surface> surf; /**< surface(s) to render. */
|
|
SDL_Rect clip; /**<
|
|
* The clipping area of the source if
|
|
* ommitted the entire source is used.
|
|
*/
|
|
};
|
|
|
|
/**
|
|
* The layers to render something on. This value should never be stored
|
|
* it's the internal drawing order and adding removing and reordering
|
|
* the layers should be safe.
|
|
* If needed in WML use the name and map that to the enum value.
|
|
*/
|
|
enum tdrawing_layer{
|
|
LAYER_TERRAIN_BG, /**<
|
|
* Layer for the terrain drawn behind the
|
|
* unit.
|
|
*/
|
|
LAYER_TERRAIN_TMP_BG, /**<
|
|
* Layer which holds stuff that needs to be
|
|
* sorted out further, but under units.
|
|
*/
|
|
LAYER_UNIT_BG, /**< Used for the ellipse behind the unit. */
|
|
LAYER_UNIT_FIRST, /**< Reserve layeres to be selected for WML. */
|
|
LAYER_UNIT_LAST=LAYER_UNIT_FIRST+100,
|
|
LAYER_UNIT_FG, /**<
|
|
* Used for the ellipse in front of the
|
|
* unit.
|
|
*/
|
|
LAYER_UNIT_FAKE, /**< The fake unit is drawn on this layer. */
|
|
LAYER_TERRAIN_FG, /**<
|
|
* Layer for the terrain drawn in front of
|
|
* the unit.
|
|
*/
|
|
LAYER_TERRAIN_TMP_FG, /**<
|
|
* Layer which holds stuff that needs to be
|
|
* sorted out further, but on top of units.
|
|
*/
|
|
LAYER_REACHMAP, /**< "black stripes" on unreachable hexes. */
|
|
LAYER_FOG_SHROUD, /**< Fog and shroud. */
|
|
LAYER_UNIT_BAR, /**<
|
|
* Unit bars and overlays are drawn on this
|
|
* layer (for testing here).
|
|
*/
|
|
LAYER_MOVE_INFO, /**< Movement info (defense%, ect...). */
|
|
LAYER_LINGER_OVERLAY, /**< The overlay used for the linger mode. */
|
|
LAYER_BORDER, /**< The border of the map. */
|
|
|
|
LAYER_LAST_LAYER /**<
|
|
* Don't draw to this layer it's a dummy to
|
|
* size the vector.
|
|
*/
|
|
};
|
|
|
|
/**
|
|
* Draw text on a hex. (0.5, 0.5) is the center.
|
|
* The font size is adjusted to the zoom factor
|
|
* and divided by 2 for tiny-gui.
|
|
*/
|
|
void draw_text_in_hex(const gamemap::location& loc,
|
|
const tdrawing_layer layer, const std::string& text, size_t font_size,
|
|
SDL_Color color, double x_in_hex=0.5, double y_in_hex=0.5);
|
|
|
|
protected:
|
|
|
|
// Initially tdrawing_buffer was a vector but profiling showed that a map
|
|
// was more efficient. Tested with the LAYER_UNIT_LAST for various values
|
|
// and different types the results were. (Tested with oprofile.)
|
|
|
|
// container unit layers counts
|
|
// vector 100 3748
|
|
// vector 10000 147338
|
|
// map 10000 3362
|
|
|
|
// Since a map with 10000 items was more efficient I didn't test the map
|
|
// with 100 items. I want to retest once more is converted, since with
|
|
// a different usage it numbers might differ so the old code is disabled
|
|
// with TDRAWING_BUFFER_USES_VECTOR
|
|
// 20080308 -- Mordante
|
|
|
|
/**
|
|
* * 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.
|
|
*/
|
|
#if TDRAWING_BUFFER_USES_VECTOR
|
|
typedef std::vector<std::map<int /*drawing_order*/, std::vector<tblit> > > tdrawing_buffer;
|
|
#else
|
|
typedef std::map<tdrawing_layer, std::map<int /*drawing_order*/, std::vector<tblit> > > tdrawing_buffer;
|
|
#endif
|
|
tdrawing_buffer drawing_buffer_;
|
|
|
|
public:
|
|
|
|
/**
|
|
* Add an item to the drawing buffer.
|
|
*
|
|
* @param layer The layer to draw on.
|
|
* @param drawing_order The order in which to draw, needed for units.
|
|
* @param blit The structure to blit.
|
|
*/
|
|
void drawing_buffer_add(const tdrawing_layer layer, const int drawing_order, const tblit& blit)
|
|
{ drawing_buffer_[layer][drawing_order].push_back(blit); }
|
|
|
|
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();
|
|
|
|
/**
|
|
* Strict weak ordering to sort a STL-set of hexes
|
|
* for drawing using the z-order.
|
|
* (1000 are just to weight the y compare to x)
|
|
*/
|
|
struct ordered_draw : public std::binary_function<gamemap::location, gamemap::location, bool> {
|
|
bool operator()(gamemap::location a, gamemap::location b) {
|
|
return (a.y*2 + a.x%2) * 1024 + a.x < (b.y*2 + b.x%2) * 1024 + b.x;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Initiate a redraw.
|
|
*
|
|
* Invalidate controls and panels when changed after they have been drawn
|
|
* initially. Useful for dynamic theme modification.
|
|
*/
|
|
bool draw_init();
|
|
void draw_wrap(bool update,bool force,bool changed);
|
|
|
|
/** Used to indicate to drawing funtions that we are doing a map screenshot */
|
|
bool map_screenshot_;
|
|
|
|
private:
|
|
/** Handle for the label which displays frames per second. */
|
|
int fps_handle_;
|
|
|
|
bool idle_anim_;
|
|
double idle_anim_rate_;
|
|
|
|
surface map_screenshot_surf_;
|
|
};
|
|
|
|
#endif
|
|
|