The display class is now fully refactored,
but the editor does not yet use the editor_display subclass. That's the next step.
This commit is contained in:
parent
c490eb5df3
commit
ffc9498cef
4 changed files with 357 additions and 354 deletions
584
src/display.cpp
584
src/display.cpp
|
@ -70,6 +70,9 @@ map_display::map_display(CVideo& video, const gamemap& map, const config& theme_
|
|||
minimap_(NULL), redrawMinimap_(false), redraw_background_(true),
|
||||
invalidateAll_(true), grid_(false),
|
||||
diagnostic_label_(0), panelsDrawn_(false),
|
||||
turbo_speed_(2), turbo_(false),
|
||||
map_labels_(*this,map, 0),
|
||||
_scroll_event("scrolled"),
|
||||
nextDraw_(0), fps_handle_(0)
|
||||
{
|
||||
if(non_interactive()) {
|
||||
|
@ -1080,6 +1083,292 @@ void map_display::draw_minimap(int x, int y, int w, int h)
|
|||
update_rect(minimap_location);
|
||||
}
|
||||
|
||||
void map_display::scroll(int xmove, int ymove)
|
||||
{
|
||||
const int orig_x = xpos_;
|
||||
const int orig_y = ypos_;
|
||||
xpos_ += xmove;
|
||||
ypos_ += ymove;
|
||||
bounds_check_position();
|
||||
const int dx = orig_x - xpos_; // dx = -xmove
|
||||
const int dy = orig_y - ypos_; // dy = -ymove
|
||||
|
||||
//only invalidate if we've actually moved
|
||||
if(dx == 0 && dy == 0)
|
||||
return;
|
||||
|
||||
map_labels_.scroll(dx, dy);
|
||||
font::scroll_floating_labels(dx, dy);
|
||||
|
||||
surface screen(screen_.getSurface());
|
||||
|
||||
SDL_Rect dstrect = map_area();
|
||||
dstrect.x += dx;
|
||||
dstrect.y += dy;
|
||||
dstrect = intersect_rects(dstrect, map_area());
|
||||
|
||||
SDL_Rect srcrect = dstrect;
|
||||
srcrect.x -= dx;
|
||||
srcrect.y -= dy;
|
||||
|
||||
SDL_BlitSurface(screen,&srcrect,screen,&dstrect);
|
||||
|
||||
//invalidate locations in the newly visible rects
|
||||
|
||||
if (dy != 0) {
|
||||
SDL_Rect r = map_area();
|
||||
r.x = 0;
|
||||
r.y = dy < 0 ? r.h+dy : 0;
|
||||
r.h = abs(dy);
|
||||
invalidate_locations_in_rect(r);
|
||||
}
|
||||
if (dx != 0) {
|
||||
SDL_Rect r = map_area();
|
||||
r.x = dx < 0 ? r.w+dx : 0;
|
||||
r.y = 0;
|
||||
r.w = abs(dx);
|
||||
invalidate_locations_in_rect(r);
|
||||
}
|
||||
|
||||
_scroll_event.notify_observers();
|
||||
update_rect(map_area());
|
||||
|
||||
redraw_background_ = true;
|
||||
redrawMinimap_ = true;
|
||||
}
|
||||
|
||||
void map_display::set_zoom(int amount)
|
||||
{
|
||||
int new_zoom = zoom_ + amount;
|
||||
if (new_zoom < MinZoom) {
|
||||
new_zoom = MinZoom;
|
||||
}
|
||||
if (new_zoom > MaxZoom) {
|
||||
new_zoom = MaxZoom;
|
||||
}
|
||||
if (new_zoom != zoom_) {
|
||||
SDL_Rect const &area = map_area();
|
||||
xpos_ += (xpos_ + area.w / 2) * amount / zoom_;
|
||||
ypos_ += (ypos_ + area.h / 2) * amount / zoom_;
|
||||
zoom_ = new_zoom;
|
||||
bounds_check_position();
|
||||
|
||||
zoom_redraw_hook();
|
||||
image::set_zoom(zoom_);
|
||||
map_labels_.recalculate_labels();
|
||||
redraw_background_ = true;
|
||||
invalidate_all();
|
||||
|
||||
// Forces a redraw after zooming.
|
||||
// This prevents some graphic glitches from occurring.
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
void map_display::set_default_zoom()
|
||||
{
|
||||
set_zoom(DefaultZoom - zoom_);
|
||||
}
|
||||
|
||||
void map_display::scroll_to_tile(const gamemap::location& loc, SCROLL_TYPE scroll_type, bool check_fogged)
|
||||
{
|
||||
if(screen_.update_locked() || (check_fogged && fogged(loc))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(map_.on_board(loc) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// current position of target (upper left tile corner) in screen coordinates
|
||||
const int screenxpos = get_location_x(loc);
|
||||
const int screenypos = get_location_y(loc);
|
||||
|
||||
if (scroll_type == ONSCREEN) {
|
||||
// the tile must be fully visible
|
||||
SDL_Rect r = map_area();
|
||||
r.w -= hex_width();
|
||||
r.h -= zoom_;
|
||||
|
||||
if (!outside_area(r,screenxpos,screenypos)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const SDL_Rect area = map_area();
|
||||
const int xmove_expected = (screenxpos + hex_width()/2) - (area.x + area.w/2 - zoom_/2);
|
||||
const int ymove_expected = (screenypos + zoom_/2) - (area.y + area.h/2 - zoom_/2);
|
||||
|
||||
int xpos = xpos_ + xmove_expected;
|
||||
int ypos = ypos_ + ymove_expected;
|
||||
bounds_check_position(xpos, ypos);
|
||||
int xmove = xpos - xpos_;
|
||||
int ymove = ypos - ypos_;
|
||||
|
||||
if(scroll_type == WARP ) {
|
||||
scroll(xmove,ymove);
|
||||
draw();
|
||||
return;
|
||||
}
|
||||
|
||||
// doing an animated scroll, with acceleration etc.
|
||||
|
||||
int x_old = 0;
|
||||
int y_old = 0;
|
||||
|
||||
const double dist_total = hypot(xmove, ymove);
|
||||
double dist_moved = 0.0;
|
||||
|
||||
int t_prev = SDL_GetTicks();
|
||||
|
||||
double velocity = 0.0;
|
||||
while (dist_moved < dist_total) {
|
||||
events::pump();
|
||||
|
||||
int t = SDL_GetTicks();
|
||||
double dt = (t - t_prev) / 1000.0;
|
||||
if (dt > 0.200) {
|
||||
// do not skip too many frames on slow pcs
|
||||
dt = 0.200;
|
||||
}
|
||||
t_prev = t;
|
||||
|
||||
//std::cout << t << " " << hypot(x_old, y_old) << "\n";
|
||||
|
||||
// those values might need some fine-tuning:
|
||||
const double accel_time = 0.3 / turbo_speed(); // seconds until full speed is reached
|
||||
const double decel_time = 0.4 / turbo_speed(); // seconds from full speed to stop
|
||||
|
||||
double velocity_max = preferences::scroll_speed() * 60.0;
|
||||
velocity_max *= turbo_speed();
|
||||
double accel = velocity_max / accel_time;
|
||||
double decel = velocity_max / decel_time;
|
||||
|
||||
// If we started to decelerate now, where would we stop?
|
||||
double stop_time = velocity / decel;
|
||||
double dist_stop = dist_moved + velocity*stop_time - 0.5*decel*stop_time*stop_time;
|
||||
if (dist_stop > dist_total || velocity > velocity_max) {
|
||||
velocity -= decel * dt;
|
||||
if (velocity < 1.0) velocity = 1.0;
|
||||
} else {
|
||||
velocity += accel * dt;
|
||||
if (velocity > velocity_max) velocity = velocity_max;
|
||||
}
|
||||
|
||||
dist_moved += velocity * dt;
|
||||
if (dist_moved > dist_total) dist_moved = dist_total;
|
||||
|
||||
int x_new = round_double(xmove * dist_moved / dist_total);
|
||||
int y_new = round_double(ymove * dist_moved / dist_total);
|
||||
|
||||
int dx = x_new - x_old;
|
||||
int dy = y_new - y_old;
|
||||
|
||||
scroll(dx,dy);
|
||||
x_old += dx;
|
||||
y_old += dy;
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
void map_display::scroll_to_tiles(const gamemap::location& loc1, const gamemap::location& loc2,
|
||||
SCROLL_TYPE scroll_type, bool check_fogged)
|
||||
{
|
||||
const int xpos1 = get_location_x(loc1);
|
||||
const int ypos1 = get_location_y(loc1);
|
||||
const int xpos2 = get_location_x(loc2);;
|
||||
const int ypos2 = get_location_y(loc2);;
|
||||
|
||||
const int minx = minimum<int>(xpos1,xpos2);
|
||||
const int maxx = maximum<int>(xpos1,xpos2);
|
||||
const int miny = minimum<int>(ypos1,ypos2);
|
||||
const int maxy = maximum<int>(ypos1,ypos2);
|
||||
const int diffx = maxx - minx;
|
||||
const int diffy = maxy - miny;
|
||||
|
||||
// if rectangle formed by corners loc1 and loc2 is larger
|
||||
// than map area then just scroll to loc1
|
||||
if(diffx > map_area().w || diffy > map_area().h) {
|
||||
scroll_to_tile(loc1,scroll_type,check_fogged);
|
||||
} else {
|
||||
// only scroll if rectangle is not completely inside map area
|
||||
// assume most paths are within rectangle, sometimes
|
||||
// with rugged terrain this is not true -- but use common
|
||||
// cases to determine behaviour instead of exceptions
|
||||
if (outside_area(map_area(),minx,miny) ||
|
||||
outside_area(map_area(),maxx,maxy)) {
|
||||
// scroll to middle point of rectangle
|
||||
scroll_to_tile(gamemap::location((loc1.x+loc2.x)/2,(loc1.y+loc2.y)/2),scroll_type,check_fogged);
|
||||
} // else don't scroll, rectangle is already on screen
|
||||
}
|
||||
}
|
||||
|
||||
void map_display::bounds_check_position()
|
||||
{
|
||||
const int orig_zoom = zoom_;
|
||||
|
||||
if(zoom_ < MinZoom) {
|
||||
zoom_ = MinZoom;
|
||||
}
|
||||
|
||||
if(zoom_ > MaxZoom) {
|
||||
zoom_ = MaxZoom;
|
||||
}
|
||||
|
||||
bounds_check_position(xpos_, ypos_);
|
||||
|
||||
if(zoom_ != orig_zoom) {
|
||||
image::set_zoom(zoom_);
|
||||
}
|
||||
}
|
||||
|
||||
void map_display::bounds_check_position(int& xpos, int& ypos)
|
||||
{
|
||||
const int tile_width = hex_width();
|
||||
|
||||
// adjust for the border 2 times 1 hex
|
||||
const int xend = tile_width * (map_.x() + 2) + tile_width/3;
|
||||
const int yend = zoom_ * (map_.y() + 2) + zoom_/2;
|
||||
|
||||
if(xpos > xend - map_area().w) {
|
||||
xpos = xend - map_area().w;
|
||||
}
|
||||
|
||||
if(ypos > yend - map_area().h) {
|
||||
ypos = yend - map_area().h;
|
||||
}
|
||||
|
||||
if(xpos < 0) {
|
||||
xpos = 0;
|
||||
}
|
||||
|
||||
if(ypos < 0) {
|
||||
ypos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void map_display::invalidate_all()
|
||||
{
|
||||
INFO_DP << "invalidate_all()";
|
||||
invalidateAll_ = true;
|
||||
invalidated_.clear();
|
||||
update_rect(map_area());
|
||||
}
|
||||
|
||||
double map_display::turbo_speed() const
|
||||
{
|
||||
bool res = turbo_;
|
||||
if(keys_[SDLK_LSHIFT] || keys_[SDLK_RSHIFT]) {
|
||||
res = !res;
|
||||
}
|
||||
|
||||
res |= screen_.faked();
|
||||
if (res)
|
||||
return turbo_speed_;
|
||||
else
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
// Methods for superclass aware of units go here
|
||||
|
||||
std::map<gamemap::location,fixed_t> display::debugHighlights_;
|
||||
|
@ -1088,7 +1377,6 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
|
|||
const gamestatus& status, const std::vector<team>& t,
|
||||
const config& theme_cfg, const config& cfg, const config& level) :
|
||||
map_display(video, map, theme_cfg, cfg, level),
|
||||
_scroll_event("scrolled"),
|
||||
units_(units),
|
||||
temp_unit_(NULL),
|
||||
status_(status),
|
||||
|
@ -1096,8 +1384,8 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
|
|||
invalidateUnit_(true),
|
||||
invalidateGameStatus_(true),
|
||||
currentTeam_(0), activeTeam_(0),
|
||||
turbo_speed_(2), turbo_(false), sidebarScaling_(1.0),
|
||||
first_turn_(true), in_game_(false), map_labels_(*this,map, 0),
|
||||
sidebarScaling_(1.0),
|
||||
first_turn_(true), in_game_(false),
|
||||
tod_hex_mask1(NULL), tod_hex_mask2(NULL), reach_map_changed_(true)
|
||||
{
|
||||
singleton_ = this;
|
||||
|
@ -1235,225 +1523,6 @@ void display::highlight_hex(gamemap::location hex)
|
|||
}
|
||||
}
|
||||
|
||||
void display::scroll(int xmove, int ymove)
|
||||
{
|
||||
const int orig_x = xpos_;
|
||||
const int orig_y = ypos_;
|
||||
xpos_ += xmove;
|
||||
ypos_ += ymove;
|
||||
bounds_check_position();
|
||||
const int dx = orig_x - xpos_; // dx = -xmove
|
||||
const int dy = orig_y - ypos_; // dy = -ymove
|
||||
|
||||
//only invalidate if we've actually moved
|
||||
if(dx == 0 && dy == 0)
|
||||
return;
|
||||
|
||||
map_labels_.scroll(dx, dy);
|
||||
font::scroll_floating_labels(dx, dy);
|
||||
|
||||
surface screen(screen_.getSurface());
|
||||
|
||||
SDL_Rect dstrect = map_area();
|
||||
dstrect.x += dx;
|
||||
dstrect.y += dy;
|
||||
dstrect = intersect_rects(dstrect, map_area());
|
||||
|
||||
SDL_Rect srcrect = dstrect;
|
||||
srcrect.x -= dx;
|
||||
srcrect.y -= dy;
|
||||
|
||||
SDL_BlitSurface(screen,&srcrect,screen,&dstrect);
|
||||
|
||||
//invalidate locations in the newly visible rects
|
||||
|
||||
if (dy != 0) {
|
||||
SDL_Rect r = map_area();
|
||||
r.x = 0;
|
||||
r.y = dy < 0 ? r.h+dy : 0;
|
||||
r.h = abs(dy);
|
||||
invalidate_locations_in_rect(r);
|
||||
}
|
||||
if (dx != 0) {
|
||||
SDL_Rect r = map_area();
|
||||
r.x = dx < 0 ? r.w+dx : 0;
|
||||
r.y = 0;
|
||||
r.w = abs(dx);
|
||||
invalidate_locations_in_rect(r);
|
||||
}
|
||||
|
||||
_scroll_event.notify_observers();
|
||||
update_rect(map_area());
|
||||
|
||||
redraw_background_ = true;
|
||||
redrawMinimap_ = true;
|
||||
}
|
||||
|
||||
void display::set_zoom(int amount)
|
||||
{
|
||||
int new_zoom = zoom_ + amount;
|
||||
if (new_zoom < MinZoom) {
|
||||
new_zoom = MinZoom;
|
||||
}
|
||||
if (new_zoom > MaxZoom) {
|
||||
new_zoom = MaxZoom;
|
||||
}
|
||||
if (new_zoom != zoom_) {
|
||||
SDL_Rect const &area = map_area();
|
||||
xpos_ += (xpos_ + area.w / 2) * amount / zoom_;
|
||||
ypos_ += (ypos_ + area.h / 2) * amount / zoom_;
|
||||
zoom_ = new_zoom;
|
||||
bounds_check_position();
|
||||
|
||||
energy_bar_rects_.clear();
|
||||
image::set_zoom(zoom_);
|
||||
map_labels_.recalculate_labels();
|
||||
redraw_background_ = true;
|
||||
invalidate_all();
|
||||
|
||||
// Forces a redraw after zooming. This prevents some graphic glitches from occurring.
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
void display::set_default_zoom()
|
||||
{
|
||||
set_zoom(DefaultZoom - zoom_);
|
||||
}
|
||||
|
||||
void display::scroll_to_tile(const gamemap::location& loc, SCROLL_TYPE scroll_type, bool check_fogged)
|
||||
{
|
||||
if(screen_.update_locked() || (check_fogged && fogged(loc))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(map_.on_board(loc) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// current position of target (upper left tile corner) in screen coordinates
|
||||
const int screenxpos = get_location_x(loc);
|
||||
const int screenypos = get_location_y(loc);
|
||||
|
||||
if (scroll_type == ONSCREEN) {
|
||||
// the tile must be fully visible
|
||||
SDL_Rect r = map_area();
|
||||
r.w -= hex_width();
|
||||
r.h -= zoom_;
|
||||
|
||||
if (!outside_area(r,screenxpos,screenypos)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const SDL_Rect area = map_area();
|
||||
const int xmove_expected = (screenxpos + hex_width()/2) - (area.x + area.w/2 - zoom_/2);
|
||||
const int ymove_expected = (screenypos + zoom_/2) - (area.y + area.h/2 - zoom_/2);
|
||||
|
||||
int xpos = xpos_ + xmove_expected;
|
||||
int ypos = ypos_ + ymove_expected;
|
||||
bounds_check_position(xpos, ypos);
|
||||
int xmove = xpos - xpos_;
|
||||
int ymove = ypos - ypos_;
|
||||
|
||||
if(scroll_type == WARP ) {
|
||||
scroll(xmove,ymove);
|
||||
draw();
|
||||
return;
|
||||
}
|
||||
|
||||
// doing an animated scroll, with acceleration etc.
|
||||
|
||||
int x_old = 0;
|
||||
int y_old = 0;
|
||||
|
||||
const double dist_total = hypot(xmove, ymove);
|
||||
double dist_moved = 0.0;
|
||||
|
||||
int t_prev = SDL_GetTicks();
|
||||
|
||||
double velocity = 0.0;
|
||||
while (dist_moved < dist_total) {
|
||||
events::pump();
|
||||
|
||||
int t = SDL_GetTicks();
|
||||
double dt = (t - t_prev) / 1000.0;
|
||||
if (dt > 0.200) {
|
||||
// do not skip too many frames on slow pcs
|
||||
dt = 0.200;
|
||||
}
|
||||
t_prev = t;
|
||||
|
||||
//std::cout << t << " " << hypot(x_old, y_old) << "\n";
|
||||
|
||||
// those values might need some fine-tuning:
|
||||
const double accel_time = 0.3 / turbo_speed(); // seconds until full speed is reached
|
||||
const double decel_time = 0.4 / turbo_speed(); // seconds from full speed to stop
|
||||
|
||||
double velocity_max = preferences::scroll_speed() * 60.0;
|
||||
velocity_max *= turbo_speed();
|
||||
double accel = velocity_max / accel_time;
|
||||
double decel = velocity_max / decel_time;
|
||||
|
||||
// If we started to decelerate now, where would we stop?
|
||||
double stop_time = velocity / decel;
|
||||
double dist_stop = dist_moved + velocity*stop_time - 0.5*decel*stop_time*stop_time;
|
||||
if (dist_stop > dist_total || velocity > velocity_max) {
|
||||
velocity -= decel * dt;
|
||||
if (velocity < 1.0) velocity = 1.0;
|
||||
} else {
|
||||
velocity += accel * dt;
|
||||
if (velocity > velocity_max) velocity = velocity_max;
|
||||
}
|
||||
|
||||
dist_moved += velocity * dt;
|
||||
if (dist_moved > dist_total) dist_moved = dist_total;
|
||||
|
||||
int x_new = round_double(xmove * dist_moved / dist_total);
|
||||
int y_new = round_double(ymove * dist_moved / dist_total);
|
||||
|
||||
int dx = x_new - x_old;
|
||||
int dy = y_new - y_old;
|
||||
|
||||
scroll(dx,dy);
|
||||
x_old += dx;
|
||||
y_old += dy;
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
void display::scroll_to_tiles(const gamemap::location& loc1, const gamemap::location& loc2,
|
||||
SCROLL_TYPE scroll_type, bool check_fogged)
|
||||
{
|
||||
const int xpos1 = get_location_x(loc1);
|
||||
const int ypos1 = get_location_y(loc1);
|
||||
const int xpos2 = get_location_x(loc2);;
|
||||
const int ypos2 = get_location_y(loc2);;
|
||||
|
||||
const int minx = minimum<int>(xpos1,xpos2);
|
||||
const int maxx = maximum<int>(xpos1,xpos2);
|
||||
const int miny = minimum<int>(ypos1,ypos2);
|
||||
const int maxy = maximum<int>(ypos1,ypos2);
|
||||
const int diffx = maxx - minx;
|
||||
const int diffy = maxy - miny;
|
||||
|
||||
// if rectangle formed by corners loc1 and loc2 is larger
|
||||
// than map area then just scroll to loc1
|
||||
if(diffx > map_area().w || diffy > map_area().h) {
|
||||
scroll_to_tile(loc1,scroll_type,check_fogged);
|
||||
} else {
|
||||
// only scroll if rectangle is not completely inside map area
|
||||
// assume most paths are within rectangle, sometimes
|
||||
// with rugged terrain this is not true -- but use common
|
||||
// cases to determine behaviour instead of exceptions
|
||||
if (outside_area(map_area(),minx,miny) ||
|
||||
outside_area(map_area(),maxx,maxy)) {
|
||||
// scroll to middle point of rectangle
|
||||
scroll_to_tile(gamemap::location((loc1.x+loc2.x)/2,(loc1.y+loc2.y)/2),scroll_type,check_fogged);
|
||||
} // else don't scroll, rectangle is already on screen
|
||||
}
|
||||
}
|
||||
|
||||
void display::scroll_to_leader(unit_map& units, int side)
|
||||
{
|
||||
const unit_map::iterator leader = find_leader(units,side);
|
||||
|
@ -1467,50 +1536,6 @@ void display::scroll_to_leader(unit_map& units, int side)
|
|||
}
|
||||
}
|
||||
|
||||
void display::bounds_check_position()
|
||||
{
|
||||
const int orig_zoom = zoom_;
|
||||
|
||||
if(zoom_ < MinZoom) {
|
||||
zoom_ = MinZoom;
|
||||
}
|
||||
|
||||
if(zoom_ > MaxZoom) {
|
||||
zoom_ = MaxZoom;
|
||||
}
|
||||
|
||||
bounds_check_position(xpos_, ypos_);
|
||||
|
||||
if(zoom_ != orig_zoom) {
|
||||
image::set_zoom(zoom_);
|
||||
}
|
||||
}
|
||||
|
||||
void display::bounds_check_position(int& xpos, int& ypos)
|
||||
{
|
||||
const int tile_width = hex_width();
|
||||
|
||||
// adjust for the border 2 times 1 hex
|
||||
const int xend = tile_width * (map_.x() + 2) + tile_width/3;
|
||||
const int yend = zoom_ * (map_.y() + 2) + zoom_/2;
|
||||
|
||||
if(xpos > xend - map_area().w) {
|
||||
xpos = xend - map_area().w;
|
||||
}
|
||||
|
||||
if(ypos > yend - map_area().h) {
|
||||
ypos = yend - map_area().h;
|
||||
}
|
||||
|
||||
if(xpos < 0) {
|
||||
xpos = 0;
|
||||
}
|
||||
|
||||
if(ypos < 0) {
|
||||
ypos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void display::redraw_everything()
|
||||
{
|
||||
if(screen_.update_locked() || teams_.empty())
|
||||
|
@ -1581,8 +1606,9 @@ void editor_display::draw(bool update,bool force)
|
|||
|
||||
tile_stack_clear();
|
||||
|
||||
tile_stack_terrains(*it,"morning",image_type,ADJACENT_BACKGROUND);
|
||||
tile_stack_terrains(*it,"morning",image_type,ADJACENT_FOREGROUND);
|
||||
const std::string nodarken = "morning";
|
||||
tile_stack_terrains(*it,nodarken,image_type,ADJACENT_BACKGROUND);
|
||||
tile_stack_terrains(*it,nodarken,image_type,ADJACENT_FOREGROUND);
|
||||
|
||||
// draw the grid, if that's been enabled
|
||||
if(grid_) {
|
||||
|
@ -2506,14 +2532,6 @@ void display::invalidate(const gamemap::location& loc)
|
|||
}
|
||||
}
|
||||
|
||||
void display::invalidate_all()
|
||||
{
|
||||
INFO_DP << "invalidate_all()";
|
||||
invalidateAll_ = true;
|
||||
invalidated_.clear();
|
||||
update_rect(map_area());
|
||||
}
|
||||
|
||||
void display::invalidate_animations()
|
||||
{
|
||||
new_animation_frame();
|
||||
|
@ -2646,20 +2664,6 @@ void display::set_playing_team(size_t teamindex)
|
|||
}
|
||||
|
||||
|
||||
double display::turbo_speed() const
|
||||
{
|
||||
bool res = turbo_;
|
||||
if(keys_[SDLK_LSHIFT] || keys_[SDLK_RSHIFT]) {
|
||||
res = !res;
|
||||
}
|
||||
|
||||
res |= screen_.faked();
|
||||
if (res)
|
||||
return turbo_speed_;
|
||||
else
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
// timestring() returns the current date as a string.
|
||||
// Uses preferences::clock_format() for formatting.
|
||||
static std::string timestring ()
|
||||
|
|
109
src/display.hpp
109
src/display.hpp
|
@ -231,6 +231,14 @@ public:
|
|||
//Delay routines: use these not SDL_Delay (for --nogui).
|
||||
void delay(unsigned int milliseconds) const;
|
||||
|
||||
//functions to 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; }
|
||||
|
||||
//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.
|
||||
|
@ -240,11 +248,46 @@ public:
|
|||
|
||||
void remove_highlighted_loc(const gamemap::location &hex);
|
||||
|
||||
void bounds_check_position();
|
||||
void bounds_check_position(int& xpos, int& ypos);
|
||||
|
||||
//function to invalidate all tiles.
|
||||
void invalidate_all();
|
||||
|
||||
//function which 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 };
|
||||
|
||||
//function which will 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);
|
||||
|
||||
//function which will scroll such that location loc is on-screen.
|
||||
//it will also try to make it such that loc is on-screen but this
|
||||
//is not guaranteed.
|
||||
void scroll_to_tiles(const gamemap::location& loc1, const gamemap::location& loc2,
|
||||
SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true);
|
||||
|
||||
//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.
|
||||
virtual void draw(bool update=true,bool force=false) = 0;
|
||||
|
||||
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);
|
||||
|
@ -252,6 +295,8 @@ public:
|
|||
protected:
|
||||
void draw_minimap(int x, int y, int w, int h);
|
||||
|
||||
virtual void zoom_redraw_hook() {};
|
||||
|
||||
enum ADJACENT_TERRAIN_TYPE { ADJACENT_BACKGROUND, ADJACENT_FOREGROUND, ADJACENT_FOGSHROUD };
|
||||
|
||||
std::vector<surface> get_terrain_images(const gamemap::location &loc,
|
||||
|
@ -276,10 +321,16 @@ protected:
|
|||
bool grid_;
|
||||
int diagnostic_label_;
|
||||
bool panelsDrawn_;
|
||||
double turbo_speed_;
|
||||
bool turbo_;
|
||||
map_labels map_labels_;
|
||||
// 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
|
||||
std::vector<gui::button> buttons_;
|
||||
std::set<gamemap::location> invalidated_;
|
||||
|
@ -289,7 +340,7 @@ protected:
|
|||
gamemap::location selectedHex_;
|
||||
gamemap::location mouseoverHex_;
|
||||
std::set<gamemap::location> highlighted_locations_;
|
||||
|
||||
CKey keys_;
|
||||
|
||||
//composes and draws the terrains on a tile
|
||||
void tile_stack_terrains(const gamemap::location& loc,
|
||||
|
@ -343,32 +394,6 @@ public:
|
|||
//the map. Used for special effects like flashes.
|
||||
void adjust_colours(int r, int g, int b);
|
||||
|
||||
//function which 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 };
|
||||
|
||||
//function which will 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);
|
||||
|
||||
//function which will scroll such that location loc is on-screen.
|
||||
//it will also try to make it such that loc is on-screen but this
|
||||
//is not guaranteed.
|
||||
void scroll_to_tiles(const gamemap::location& loc1, const gamemap::location& loc2,
|
||||
SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true);
|
||||
|
||||
//scrolls to the leader of a certain side. This will normally
|
||||
//be the playing team.
|
||||
void scroll_to_leader(unit_map& units, int side);
|
||||
|
@ -416,10 +441,6 @@ public:
|
|||
//expose the event so observers can be notified about map scrolling
|
||||
events::generic_event &scroll_event() const { return _scroll_event; }
|
||||
|
||||
private:
|
||||
// event raised when the map is being scrolled
|
||||
mutable events::generic_event _scroll_event;
|
||||
|
||||
public:
|
||||
//function to return a footstep for the given location, on screen at
|
||||
//pixel co-ordinates (xloc,yloc). A footstep will only be drawn if
|
||||
|
@ -430,9 +451,6 @@ public:
|
|||
//draws the movement info (turns available) for a given location
|
||||
void draw_movement_info(const gamemap::location& loc);
|
||||
|
||||
//function to invalidate all tiles.
|
||||
void invalidate_all();
|
||||
|
||||
//function to invalidate a specific tile for redrawing
|
||||
void invalidate(const gamemap::location& loc);
|
||||
|
||||
|
@ -486,14 +504,6 @@ public:
|
|||
unit_map& get_units() {return units_;};
|
||||
const unit_map& get_const_units() const {return units_;};
|
||||
|
||||
//functions to 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; }
|
||||
|
||||
//a debug highlight draws a cross on a tile to emphasize
|
||||
//something there. it is used in debug mode, typically to
|
||||
//show AI plans.
|
||||
|
@ -512,9 +522,6 @@ public:
|
|||
void remove_observer(const std::string& name) { observers_.erase(name); }
|
||||
const std::set<std::string>& observers() const { return observers_; }
|
||||
|
||||
map_labels& labels() { return map_labels_; }
|
||||
const map_labels& labels() const { return map_labels_; }
|
||||
|
||||
enum MESSAGE_TYPE { MESSAGE_PUBLIC, MESSAGE_PRIVATE };
|
||||
void add_chat_message(const std::string& speaker, int side, const std::string& msg, MESSAGE_TYPE type, bool bell);
|
||||
void clear_chat_messages() { prune_chat_messages(true); }
|
||||
|
@ -534,6 +541,8 @@ private:
|
|||
display(const display&);
|
||||
void operator=(const display&);
|
||||
|
||||
void zoom_redraw_hook() {energy_bar_rects_.clear();}
|
||||
|
||||
void draw_sidebar();
|
||||
void draw_game_status();
|
||||
|
||||
|
@ -543,14 +552,9 @@ private:
|
|||
surface reportSurfaces_[reports::NUM_REPORTS];
|
||||
reports::report reports_[reports::NUM_REPORTS];
|
||||
|
||||
void bounds_check_position();
|
||||
void bounds_check_position(int& xpos, int& ypos);
|
||||
|
||||
//this surface must be freed by the caller
|
||||
surface get_flag(const t_translation::t_letter& terrain, const gamemap::location& loc);
|
||||
|
||||
CKey keys_;
|
||||
|
||||
unit_map& units_;
|
||||
|
||||
unit *temp_unit_;
|
||||
|
@ -565,7 +569,6 @@ private:
|
|||
|
||||
const gamestatus& status_;
|
||||
|
||||
|
||||
const std::vector<team>& teams_;
|
||||
|
||||
void invalidate_route();
|
||||
|
@ -588,16 +591,12 @@ private:
|
|||
|
||||
size_t currentTeam_, activeTeam_;
|
||||
|
||||
double turbo_speed_;
|
||||
bool turbo_;
|
||||
double sidebarScaling_;
|
||||
|
||||
bool first_turn_, in_game_;
|
||||
|
||||
std::set<std::string> observers_;
|
||||
|
||||
map_labels map_labels_;
|
||||
|
||||
struct chat_message
|
||||
{
|
||||
chat_message(int speaker, int h) : speaker_handle(speaker), handle(h), created_at(SDL_GetTicks())
|
||||
|
|
|
@ -31,12 +31,12 @@ namespace {
|
|||
//or the tile below is obscured. This is because in the case where the tile
|
||||
//itself is visible, but the tile below is obscured, the bottom half of the
|
||||
//tile will still be shrouded, and the label being drawn looks weird
|
||||
static bool is_shrouded(const display& disp, const gamemap::location& loc)
|
||||
static bool is_shrouded(const map_display& disp, const gamemap::location& loc)
|
||||
{
|
||||
return disp.shrouded(loc) || disp.shrouded(gamemap::location(loc.x,loc.y+1));
|
||||
}
|
||||
|
||||
map_labels::map_labels(const display& disp,
|
||||
map_labels::map_labels(const map_display& disp,
|
||||
const gamemap& map,
|
||||
const team* team) :
|
||||
disp_(disp),
|
||||
|
@ -45,7 +45,7 @@ map_labels::map_labels(const display& disp,
|
|||
{
|
||||
}
|
||||
|
||||
map_labels::map_labels(const display& disp,
|
||||
map_labels::map_labels(const map_display& disp,
|
||||
const config& cfg,
|
||||
const gamemap& map,
|
||||
const team* team) :
|
||||
|
@ -120,7 +120,7 @@ const terrain_label* map_labels::get_label(const gamemap::location& loc)
|
|||
}
|
||||
|
||||
|
||||
const display& map_labels::disp() const
|
||||
const map_display& map_labels::disp() const
|
||||
{
|
||||
return disp_;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class config;
|
|||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class display;
|
||||
class map_display;
|
||||
class team;
|
||||
class terrain_label;
|
||||
class replay;
|
||||
|
@ -36,8 +36,8 @@ public:
|
|||
typedef std::map<gamemap::location,const terrain_label*> label_map;
|
||||
typedef std::map<std::string,label_map> team_label_map;
|
||||
|
||||
map_labels(const display& disp, const gamemap& map, const team*);
|
||||
map_labels(const display& disp, const config& cfg, const gamemap& map, const team*);
|
||||
map_labels(const map_display& disp, const gamemap& map, const team*);
|
||||
map_labels(const map_display& disp, const config& cfg, const gamemap& map, const team*);
|
||||
~map_labels();
|
||||
|
||||
void write(config& res) const;
|
||||
|
@ -64,7 +64,7 @@ public:
|
|||
|
||||
void recalculate_shroud();
|
||||
|
||||
const display& disp() const;
|
||||
const map_display& disp() const;
|
||||
|
||||
const std::string& team_name() const;
|
||||
|
||||
|
@ -76,7 +76,7 @@ private:
|
|||
map_labels(const map_labels&);
|
||||
void operator=(const map_labels&);
|
||||
|
||||
const display& disp_;
|
||||
const map_display& disp_;
|
||||
const team* team_;
|
||||
const gamemap& map_;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue