[[Animation refactoring]]

* Refactoring of all animation code in unit_display and halo.

* Adding animated.hpp, and the animated<T> template.

* Partial rewrite of image.?pp for speed: looking up images was what
  was slowing the game

* Replacing all SDL_Surface*, and scoped_sdl_surface, with
  shared_sdl_surface, which was renamed surface.

* Optimizing halo movement when unit moves

* Inlining some stuff for performance reasons

* Optimizing invalide_all redraws

* Adding support for animated terrain images
This commit is contained in:
Philippe Plantier 2004-07-18 19:02:25 +00:00
parent b867c23503
commit ac441889d9
53 changed files with 1704 additions and 1098 deletions

View file

@ -222,7 +222,7 @@ void show_about(display& disp)
0,0,0,1.0,disp.video().getSurface());
update_whole_screen();
const scoped_sdl_surface map_image(image::get_image(game_config::map_image,image::UNSCALED));
const surface map_image(image::get_image(game_config::map_image,image::UNSCALED));
SDL_Rect map_rect;
map_rect.x = disp.x()/2 - map_image->w/2;
map_rect.y = disp.y()/2 - map_image->h/2;

View file

@ -1836,4 +1836,4 @@ const std::set<gamemap::location>& ai::avoided_locations() const
}
return avoid_;
}
}

View file

@ -743,4 +743,5 @@ void ai::access_points(const move_map& srcdst, const location& u, const location
}
}
}
}
}

362
src/animated.hpp Normal file
View file

@ -0,0 +1,362 @@
/* $Id$ */
/*
Copyright (C) 2004 by Philippe Plantier <ayin@anathas.org>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef ANIMATED_IMAGE_H_INCLUDED
#define ANIMATED_IMAGE_H_INCLUDED
#include <string>
#include <vector>
#include "SDL.h"
#include "config.hpp"
#include "util.hpp"
template<typename T>
class void_value
{
public:
const T operator()() { return T(); }
};
template<typename T, typename T_void_value=void_value<T> >
class animated
{
public:
class string_initializer
{
public:
virtual T operator()(const std::string& s) const { return T(s); }
};
animated();
//if T can be constructed from a string, you may use this constructor
// animated(const std::string& cfg);
//if T cannot, you may provide a custom (subclassed) string_initializer
//to do the job
animated(const std::string &cfg, const string_initializer& init=string_initializer());
// //if T can be constructed from a config&, you may use this constructor
//animated(const config& cfg, const std::string& tag);
// Adds a void frame
void add_frame(int start);
// Adds a frame
void add_frame(int start, const T& value);
//Starts an animation cycle. The first frame of the animation to start
//may be set to any value
static const int INFINITE_CYCLES = -1;
void start_animation(int start_time=0, int cycles=1, int acceleration=1);
int get_first_frame_time() const;
int get_last_frame_time() const;
int get_duration() const;
//inlined for performance
void update_current_frame() { if(does_not_change_) return; update_current_frame_internal(); };
bool frame_changed() const;
//True if the current animation was finished
bool animation_finished() const;
int get_animation_time() const;
int get_frame_time() const;
const T& get_current_frame() const;
const T& get_base_frame() const;
private:
struct frame
{
frame(int milliseconds) :
milliseconds(milliseconds), has_value(false)
{};
frame(int milliseconds, const T& value) :
milliseconds(milliseconds), value(value), has_value(true)
{};
// Represents the timestamp of the frame start
int milliseconds;
bool has_value;
T value;
};
void update_current_frame_internal();
static const T void_value_;
int starting_frame_time_;
int ending_frame_time_;
bool started_;
bool no_current_frame_;
bool does_not_change_; // optimization for 1-frame permanent animations
int real_start_ticks_;
int start_ticks_;
int current_cycle_;
int current_time_;
int cycles_;
int acceleration_;
bool frame_changed_;
int start_frame_;
int duration_;
typename std::vector<frame>::size_type current_frame_;
std::vector<frame> frames_;
};
template<typename T, typename T_void_value>
const T animated<T,T_void_value>::void_value_ = T_void_value()();
template<typename T, typename T_void_value>
animated<T,T_void_value>::animated() :
no_current_frame_(true), started_(false),
starting_frame_time_(INT_MAX),
ending_frame_time_(INT_MIN),
start_ticks_(0),
real_start_ticks_(0),
does_not_change_(false),
acceleration_(1)
{}
template<typename T, typename T_void_value>
animated<T,T_void_value>::animated(const std::string &cfg, const string_initializer& init):
no_current_frame_(true), started_(false),
starting_frame_time_(INT_MAX),
start_ticks_(0),
real_start_ticks_(0),
does_not_change_(false),
acceleration_(1)
{
std::vector<std::string> items = config::split(cfg);
int current_time = 0;
std::vector<std::string>::const_iterator itor = items.begin();
for(; itor != items.end(); ++itor) {
const std::vector<std::string>& items = config::split(*itor, ':');
std::string str;
int time;
if(items.size() > 1) {
str = items.front();
time = atoi(items.back().c_str());
} else {
str = *itor;
time = 100;
}
frames_.push_back(frame(current_time, init(str)));
current_time += time;
}
starting_frame_time_ = 0;
ending_frame_time_ = current_time;
}
template<typename T, typename T_void_value>
void animated<T,T_void_value>::add_frame(int start)
{
frames_.push_back(frame(start));
starting_frame_time_ = minimum<int>(starting_frame_time_, start);
ending_frame_time_ = maximum<int>(ending_frame_time_, start);
}
template<typename T, typename T_void_value>
void animated<T,T_void_value>::add_frame(int start, const T& value)
{
frames_.push_back(frame(start, value));
starting_frame_time_ = minimum<int>(starting_frame_time_, start);
ending_frame_time_ = maximum<int>(ending_frame_time_, start);
}
template<typename T, typename T_void_value>
void animated<T,T_void_value>::start_animation(int start_frame, int cycles, int acceleration)
{
started_ = true;
start_frame_ = start_frame;
start_ticks_ = real_start_ticks_ = current_time_ = SDL_GetTicks() * acceleration;
cycles_ = cycles;
current_cycle_ = 0;
acceleration_ = acceleration;
// current_frame_ = frames_.begin();
current_frame_ = 0;
if (ending_frame_time_ >= start_frame_) {
duration_ = ending_frame_time_ - start_frame_;
} else {
duration_ = 0;
}
}
template<typename T, typename T_void_value>
void animated<T,T_void_value>::update_current_frame_internal()
{
// std::cerr << "--- updating frame ---\n";
if(does_not_change_)
return;
frame_changed_ = false;
// Always update current_time_, for the animation_time functions to work.
current_time_ = SDL_GetTicks() * acceleration_;
if(!started_)
return;
if(frames_.empty()) {
no_current_frame_ = true;
does_not_change_ = true;
return;
}
if(frames_.size() == 1 && cycles_ == INFINITE_CYCLES) {
does_not_change_ = true;
frame_changed_ = false;
}
if (duration_ > 0) {
// Ticks is the actual time since animation started.
int ticks = current_time_ - start_ticks_;
// Handles cycle overflow
if(ticks > duration_) {
int ncycles = ticks/duration_;
current_cycle_ = minimum<int>(cycles_, current_cycle_ + ncycles);
start_ticks_ += ncycles * duration_;
ticks -= ncycles * duration_;
// current_frame_ = frames_.begin();
current_frame_ = 0;
frame_changed_ = true;
}
// Checks if the animation is finished
if(cycles_ != INFINITE_CYCLES && current_cycle_ >= cycles_) {
// If the animation is finished, the current frame is the last
// one
current_frame_ = frames_.size() - 1;
frame_changed_ = true;
// std::cerr << "Animation finished\n";
no_current_frame_ = false;
started_ = false;
return;
}
if(ticks < (frames_[current_frame_].milliseconds - start_frame_)) {
// std::cerr << "Animation not yet started\n";
frame_changed_ = true;
no_current_frame_ = true;
return;
}
// Looks for the current frame
typename std::vector<frame>::size_type i = current_frame_ + 1;
for(; i != frames_.size(); ++i) {
if(ticks < (frames_[i].milliseconds - start_frame_))
break;
current_frame_ = i;
frame_changed_ = true;
// std::cerr << "Skipping to next frame\n";
}
no_current_frame_ = false;
} else {
// If the duration is void, the animation is automatically finished.
// current_cycle_ = cycles_;
if(cycles_ != -1)
started_ = false;
does_not_change_ = true;
frame_changed_ = false;
// current_frame_ = frames_.size() - 1;
// frame_changed_ = false;
// std::cerr << "Returning last frame\n";
no_current_frame_ = false;
}
}
template<typename T, typename T_void_value>
bool animated<T,T_void_value>::frame_changed() const
{
return frame_changed_;
}
template<typename T, typename T_void_value>
bool animated<T,T_void_value>::animation_finished() const
{
if(!started_)
return true;
//if(current_cycle_ == cycles_)
// return true;
return false;
}
template<typename T, typename T_void_value>
int animated<T,T_void_value>::get_animation_time() const
{
if(does_not_change_)
return SDL_GetTicks() * acceleration_ - real_start_ticks_ + start_frame_;
return current_time_ - real_start_ticks_ + start_frame_;
}
template<typename T, typename T_void_value>
int animated<T,T_void_value>::get_frame_time() const
{
return current_time_ - start_ticks_ + start_frame_;
}
template<typename T, typename T_void_value>
const T& animated<T,T_void_value>::get_current_frame() const
{
if(no_current_frame_ == true)
return void_value_;
if(!frames_[current_frame_].has_value)
return void_value_;
return frames_[current_frame_].value;
}
template<typename T, typename T_void_value>
const T& animated<T,T_void_value>::get_base_frame() const
{
if(frames_.empty())
return void_value_;
return frames_[0];
}
template<typename T, typename T_void_value>
int animated<T,T_void_value>::get_first_frame_time() const
{
if (starting_frame_time_ != INT_MAX && starting_frame_time_ != INT_MIN)
return starting_frame_time_;
return 0;
}
template<typename T, typename T_void_value>
int animated<T,T_void_value>::get_last_frame_time() const
{
if (ending_frame_time_ != INT_MAX && ending_frame_time_ != INT_MIN)
return ending_frame_time_;
return 0;
}
#endif

View file

@ -17,6 +17,30 @@
#include "terrain.hpp"
#include "util.hpp"
namespace {
class locator_string_initializer : public animated<image::locator>::string_initializer
{
public:
locator_string_initializer() : loc_(), no_loc_(true) {}
locator_string_initializer(const gamemap::location& loc): loc_(loc), no_loc_(false) {}
image::locator operator()(const std::string &s) const;
private:
bool no_loc_;
gamemap::location loc_;
};
image::locator locator_string_initializer::operator()(const std::string &s) const
{
if(no_loc_) {
return image::locator("terrain/" + s + ".png");
} else {
return image::locator("terrain/" + s + ".png", loc_);
}
}
}
terrain_builder::tile::tile()
{
@ -67,8 +91,8 @@ terrain_builder::terrain_builder(const config& cfg, const gamemap& gmap) :
//rebuild_terrain(gamemap::location(0,0));
}
const std::vector<image::locator> *terrain_builder::get_terrain_at(const gamemap::location &loc,
ADJACENT_TERRAIN_TYPE terrain_type) const
const terrain_builder::imagelist *terrain_builder::get_terrain_at(const gamemap::location &loc,
ADJACENT_TERRAIN_TYPE terrain_type) const
{
if(!tile_map_.on_map(loc))
return NULL;
@ -86,6 +110,29 @@ const std::vector<image::locator> *terrain_builder::get_terrain_at(const gamemap
return NULL;
}
bool terrain_builder::update_animation(const gamemap::location &loc)
{
imagelist& bg = tile_map_[loc].images_background;
imagelist& fg = tile_map_[loc].images_foreground;
bool changed = false;
imagelist::iterator itor = bg.begin();
for(; itor != bg.end(); ++itor) {
itor->update_current_frame();
if(itor->frame_changed())
changed = true;
}
itor = fg.begin();
for(; itor != fg.end(); ++itor) {
itor->update_current_frame();
if(itor->frame_changed())
changed = true;
}
return changed;
}
void terrain_builder::rebuild_terrain(const gamemap::location &loc)
{
if (tile_map_.on_map(loc)) {
@ -93,7 +140,7 @@ void terrain_builder::rebuild_terrain(const gamemap::location &loc)
btile.clear();
const std::string filename =
map_.get_terrain_info(map_.get_terrain(loc)).default_image();
image::locator img_loc(filename);
animated<image::locator> img_loc(filename);
btile.images_foreground.push_back(img_loc);
}
}
@ -142,9 +189,9 @@ void terrain_builder::replace_token(std::string &s, const std::string &token, co
}
}
void terrain_builder::replace_token(terrain_builder::imagelist &list, const std::string &token, const std::string &replacement)
void terrain_builder::replace_token(terrain_builder::rule_imagelist &list, const std::string &token, const std::string &replacement)
{
for(imagelist::iterator itor = list.begin(); itor != list.end(); ++itor) {
for(rule_imagelist::iterator itor = list.begin(); itor != list.end(); ++itor) {
replace_token(itor->second, token, replacement);
replace_token(itor->second, token, replacement);
}
@ -225,7 +272,7 @@ terrain_builder::building_rule terrain_builder::rotate_rule(const terrain_builde
return ret;
}
void terrain_builder::add_images_from_config(imagelist& images, const config &cfg)
void terrain_builder::add_images_from_config(rule_imagelist& images, const config &cfg)
{
const config::child_list& cimages = cfg.get_children("image");
@ -561,7 +608,11 @@ void terrain_builder::apply_rule(const terrain_builder::building_rule &rule, con
std::multimap<int, std::string>::const_iterator img;
for(img = rule.images.begin(); img != rule.images.end(); ++img) {
image::locator th(img->second, constraint->second.loc);
animated<image::locator> th(img->second, locator_string_initializer(constraint->second.loc));
th.start_animation(0,animated<image::locator>::INFINITE_CYCLES);
th.update_current_frame();
//image::locator th(img->second, constraint->second.loc);
if(img->first < 0) {
btile.images_background.push_back(th);
} else {
@ -571,7 +622,10 @@ void terrain_builder::apply_rule(const terrain_builder::building_rule &rule, con
}
for(img = constraint->second.images.begin(); img != constraint->second.images.end(); ++img) {
image::locator th(img->second);
animated<image::locator> th(img->second, locator_string_initializer());
th.start_animation(0,animated<image::locator>::INFINITE_CYCLES);
th.update_current_frame();
if(img->first < 0) {
btile.images_background.push_back(th);
} else {
@ -699,13 +753,16 @@ void terrain_builder::build_terrains()
//checks if all the images referenced by the current rule are valid.
//if not, this rule will not match.
bool absent_image = false;
imagelist::const_iterator image;
rule_imagelist::const_iterator image;
constraint_set::const_iterator constraint;
for(image = rule->second.images.begin();
!absent_image && (image != rule->second.images.end()); ++image) {
if(!image::exists("terrain/" + image->second + ".png"))
std::string s = image->second;
s = s.substr(0, s.find_first_of(",:"));
if(!image::exists("terrain/" + s + ".png"))
absent_image = true;
}
@ -714,7 +771,11 @@ void terrain_builder::build_terrains()
for(image = constraint->second.images.begin();
!absent_image && (image != constraint->second.images.end());
++image) {
if(!image::exists("terrain/" + image->second + ".png"))
std::string s = image->second;
s = s.substr(0, s.find_first_of(",:"));
if(!image::exists("terrain/" + s + ".png"))
absent_image = true;
}
}

View file

@ -16,25 +16,30 @@
#include "config.hpp"
#include "map.hpp"
#include "image.hpp"
#include "animated.hpp"
#include "SDL.h"
#include <string>
#include <map>
//builder: dynamically builds castle and other dynamically-generated tiles.
//terrain_builder: returns the lst of images used to build a terrain tile
class terrain_builder
{
public:
enum ADJACENT_TERRAIN_TYPE { ADJACENT_BACKGROUND, ADJACENT_FOREGROUND };
typedef std::vector<animated<image::locator> > imagelist;
terrain_builder(const config& cfg, const gamemap& gmap);
//returns a vector of string representing the images to load & blit together to get the
//built content for this tile.
//Returns NULL if there is no built content for this tile.
const std::vector<image::locator> *get_terrain_at(const gamemap::location &loc,
const imagelist *get_terrain_at(const gamemap::location &loc,
ADJACENT_TERRAIN_TYPE terrain_type) const;
//updates the animation at a given tile. returns true if something has
//changed, and must be redrawn.
bool terrain_builder::update_animation(const gamemap::location &loc);
// regenerate the generated content at the given
// location. Currently: set the image at that location to the
@ -43,7 +48,7 @@ public:
void rebuild_all();
typedef std::multimap<int, std::string> imagelist;
typedef std::multimap<int, std::string> rule_imagelist;
struct terrain_constraint
{
@ -57,15 +62,15 @@ public:
std::vector<std::string> no_flag;
std::vector<std::string> has_flag;
imagelist images;
rule_imagelist images;
};
struct tile
{
tile();
std::set<std::string> flags;
std::vector<image::locator> images_foreground;
std::vector<image::locator> images_background;
imagelist images_foreground;
imagelist images_background;
gamemap::TERRAIN adjacents[7];
@ -83,7 +88,7 @@ private:
int probability;
int precedence;
imagelist images;
rule_imagelist images;
};
struct tilemap
@ -106,14 +111,14 @@ private:
terrain_constraint rotate(const terrain_constraint &constraint, int angle);
void replace_token(std::string &, const std::string &token, const std::string& replacement);
void replace_token(imagelist &, const std::string &token, const std::string& replacement);
void replace_token(rule_imagelist &, const std::string &token, const std::string& replacement);
void replace_token(building_rule &s, const std::string &token, const std::string& replacement);
building_rule rotate_rule(const building_rule &rule, int angle, const std::vector<std::string>& angle_name);
void add_rotated_rules(building_ruleset& rules, const building_rule& tpl, const std::string &rotations);
void add_constraint_item(std::vector<std::string> &list, const config& cfg, const std::string &item);
void terrain_builder::add_images_from_config(imagelist &images, const config &cfg);
void terrain_builder::add_images_from_config(rule_imagelist &images, const config &cfg);
void add_constraints(std::map<gamemap::location, terrain_constraint>& constraints,
const gamemap::location &loc, const std::string& type);

View file

@ -18,30 +18,30 @@ bool use_colour_cursors()
return game_config::editor == false && preferences::use_colour_cursors();
}
SDL_Cursor* create_cursor(SDL_Surface* surface)
SDL_Cursor* create_cursor(surface surf)
{
const scoped_sdl_surface surf(make_neutral_surface(surface));
if(surf == NULL) {
const surface nsurf(make_neutral_surface(surf));
if(nsurf == NULL) {
return NULL;
}
//the width must be a multiple of 8 (SDL requirement)
size_t cursor_width = surf->w;
size_t cursor_width = nsurf->w;
if((cursor_width%8) != 0) {
cursor_width += 8 - (cursor_width%8);
}
std::vector<Uint8> data((cursor_width*surf->h)/8,0);
std::vector<Uint8> data((cursor_width*nsurf->h)/8,0);
std::vector<Uint8> mask(data.size(),0);
//see http://sdldoc.csn.ul.ie/sdlcreatecursor.php for documentation on
//the format that data has to be in to pass to SDL_CreateCursor
surface_lock lock(surf);
surface_lock lock(nsurf);
const Uint32* const pixels = reinterpret_cast<Uint32*>(lock.pixels());
for(size_t y = 0; y != surf->h; ++y) {
for(size_t x = 0; x != surf->w; ++x) {
for(size_t y = 0; y != nsurf->h; ++y) {
for(size_t x = 0; x != nsurf->w; ++x) {
Uint8 r,g,b,a;
SDL_GetRGBA(pixels[y*surf->w + x],surf->format,&r,&g,&b,&a);
SDL_GetRGBA(pixels[y*nsurf->w + x],nsurf->format,&r,&g,&b,&a);
const size_t index = y*cursor_width + x;
@ -55,7 +55,7 @@ SDL_Cursor* create_cursor(SDL_Surface* surface)
}
}
return SDL_CreateCursor(&data[0],&mask[0],cursor_width,surf->h,0,0);
return SDL_CreateCursor(&data[0],&mask[0],cursor_width,nsurf->h,0,0);
}
SDL_Cursor* cache[cursor::NUM_CURSORS] = { NULL, NULL, NULL, NULL };
@ -66,14 +66,14 @@ const std::string images[cursor::NUM_CURSORS] = { "normal.png", "wait.png", "mov
cursor::CURSOR_TYPE current_cursor = cursor::NUM_CURSORS;
int cursor_x = -1, cursor_y = -1;
SDL_Surface* cursor_buf = NULL;
surface cursor_buf = NULL;
bool have_focus = true;
SDL_Cursor* get_cursor(cursor::CURSOR_TYPE type)
{
if(cache[type] == NULL) {
static const std::string prefix = "cursors-bw/";
const scoped_sdl_surface surf(image::get_image(prefix + images[type],image::UNSCALED));
const surface surf(image::get_image(prefix + images[type],image::UNSCALED));
cache[type] = create_cursor(surf);
}
@ -147,7 +147,7 @@ setter::~setter()
set(old_);
}
void draw(SDL_Surface* screen)
void draw(surface screen)
{
if(use_colour_cursors() == false) {
return;
@ -170,7 +170,7 @@ void draw(SDL_Surface* screen)
cursor_x = new_cursor_x;
cursor_y = new_cursor_y;
const scoped_sdl_surface surf(image::get_image("cursors/" + images[current_cursor],image::UNSCALED));
const surface surf(image::get_image("cursors/" + images[current_cursor],image::UNSCALED));
if(surf == NULL) {
//fall back to b&w cursors
std::cerr << "could not load colour cursors. Falling back to hardware cursors\n";
@ -203,7 +203,7 @@ void draw(SDL_Surface* screen)
}
}
void undraw(SDL_Surface* screen)
void undraw(surface screen)
{
if(use_colour_cursors() == false) {
return;

View file

@ -2,6 +2,7 @@
#define CURSOR_HPP_INCLUDED
#include "SDL.h"
#include "sdl_utils.hpp"
namespace cursor
{
@ -18,8 +19,8 @@ void use_colour(bool value);
void set(CURSOR_TYPE type);
void draw(SDL_Surface* screen);
void undraw(SDL_Surface* screen);
void draw(surface screen);
void undraw(surface screen);
void set_focus(bool focus);

View file

@ -264,7 +264,7 @@ private:
const std::vector<save_info>* info_;
const std::vector<config*>* summaries_;
int index_;
std::map<std::string,shared_sdl_surface> map_cache_;
std::map<std::string,surface> map_cache_;
};
void save_preview_pane::draw()
@ -285,7 +285,7 @@ void save_preview_pane::draw()
const config& summary = *(*summaries_)[index_];
SDL_Surface* const screen = disp().video().getSurface();
surface const screen = disp().video().getSurface();
const SDL_Rect area = { location().x+save_preview_border, location().y+save_preview_border,
location().w-save_preview_border*2, location().h-save_preview_border*2 };
@ -296,7 +296,7 @@ void save_preview_pane::draw()
const game_data::unit_type_map::const_iterator leader = data_->unit_types.find(summary["leader"]);
if(leader != data_->unit_types.end()) {
const scoped_sdl_surface image(image::get_image(leader->second.image(),image::UNSCALED));
const surface image(image::get_image(leader->second.image(),image::UNSCALED));
if(image != NULL) {
SDL_Rect image_rect = {area.x,area.y,image->w,image->h};
ypos += image_rect.h + save_preview_border;
@ -321,10 +321,10 @@ void save_preview_pane::draw()
}
}
SDL_Surface* map_surf = NULL;
surface map_surf(NULL);
if(map_data.empty() == false) {
const std::map<std::string,shared_sdl_surface>::const_iterator itor = map_cache_.find(map_data);
const std::map<std::string,surface>::const_iterator itor = map_cache_.find(map_data);
if(itor != map_cache_.end()) {
map_surf = itor->second;
} else if(map_ != NULL) {
@ -333,7 +333,7 @@ void save_preview_pane::draw()
map_surf = image::getMinimap(100,100,*map_,0,NULL);
if(map_surf != NULL) {
map_cache_.insert(std::pair<std::string,shared_sdl_surface>(map_data,shared_sdl_surface(map_surf)));
map_cache_.insert(std::pair<std::string,surface>(map_data,surface(map_surf)));
}
} catch(gamemap::incorrect_format_exception&) {
}
@ -534,7 +534,7 @@ void unit_speak(const config& message_info, display& disp, const unit_map& units
for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
if(i->second.matches_filter(message_info)) {
disp.scroll_to_tile(i->first.x,i->first.y);
const scoped_sdl_surface surface(image::get_image(i->second.type().image_profile(),image::UNSCALED));
const surface surface(image::get_image(i->second.type().image_profile(),image::UNSCALED));
gui::show_dialog(disp,surface,i->second.underlying_description(),message_info["message"],gui::MESSAGE);
}
}
@ -549,7 +549,7 @@ int show_file_chooser_dialog(display &disp, std::string &filename,
const events::resize_lock prevent_resizing;
CVideo& screen = disp.video();
SDL_Surface* const scr = screen.getSurface();
surface const scr = screen.getSurface();
const int width = 400;
const int height = 400;
@ -671,14 +671,14 @@ void unit_preview_pane::draw()
const bool right_align = left_side();
SDL_Surface* const screen = disp().video().getSurface();
surface const screen = disp().video().getSurface();
const SDL_Rect area = { location().x+unit_preview_border, location().y+unit_preview_border,
location().w-unit_preview_border*2, location().h-unit_preview_border*2 };
SDL_Rect clip_area = area;
const clip_rect_setter clipper(screen,clip_area);
scoped_sdl_surface unit_image(image::get_image(u.type().image(),image::UNSCALED));
surface unit_image(image::get_image(u.type().image(),image::UNSCALED));
if(left_side() == false && unit_image != NULL) {
unit_image.assign(image::reverse_image(unit_image));
}
@ -817,7 +817,7 @@ void show_unit_description(display& disp, const gamemap& map, const unit& u)
options.push_back(string_table["attack_resistance"]);
options.push_back(string_table["close_window"]);
const scoped_sdl_surface profile(image::get_image(u.type().image_profile(),image::SCALED));
const surface profile(image::get_image(u.type().image_profile(),image::SCALED));
const int res = gui::show_dialog(disp, profile, u.type().language_name(),
description,gui::MESSAGE, &options);

View file

@ -54,21 +54,21 @@ namespace {
display::display(unit_map& units, CVideo& video, const gamemap& map,
const gamestatus& status, const std::vector<team>& t, const config& theme_cfg,
const config& built_terrains)
: screen_(video), xpos_(0), ypos_(0),
zoom_(DefaultZoom), map_(map), units_(units),
minimap_(NULL), redrawMinimap_(false),
pathsList_(NULL), status_(status),
teams_(t), lastDraw_(0), drawSkips_(0),
invalidateAll_(true), invalidateUnit_(true),
invalidateGameStatus_(true), panelsDrawn_(false),
currentTeam_(0), activeTeam_(0), hideEnergy_(false),
deadAmount_(0.0), advancingAmount_(0.0), updatesLocked_(0),
turbo_(false), grid_(false), sidebarScaling_(1.0),
theme_(theme_cfg,screen_area()), builder_(built_terrains, map),
first_turn_(true), in_game_(false), map_labels_(*this,map),
tod_hex_mask1(NULL), tod_hex_mask2(NULL), diagnostic_label_(0),
help_string_(0)
const config& built_terrains) :
screen_(video), xpos_(0), ypos_(0),
zoom_(DefaultZoom), map_(map), units_(units),
minimap_(NULL), redrawMinimap_(false),
pathsList_(NULL), status_(status),
teams_(t), lastDraw_(0), drawSkips_(0),
invalidateAll_(true), invalidateUnit_(true),
invalidateGameStatus_(true), panelsDrawn_(false),
currentTeam_(0), activeTeam_(0), hideEnergy_(false),
deadAmount_(0.0), advancingAmount_(0.0), updatesLocked_(0),
turbo_(false), grid_(false), sidebarScaling_(1.0),
theme_(theme_cfg,screen_area()), builder_(built_terrains, map),
first_turn_(true), in_game_(false), map_labels_(*this,map),
tod_hex_mask1(NULL), tod_hex_mask2(NULL), diagnostic_label_(0),
help_string_(0)
{
if(non_interactive())
updatesLocked_++;
@ -82,14 +82,14 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
unitProfileRect_.w = 0;
//clear the screen contents
SDL_Surface* const disp = screen_.getSurface();
surface const disp(screen_.getSurface());
SDL_Rect area = screen_area();
SDL_FillRect(disp,&area,SDL_MapRGB(disp->format,0,0,0));
}
display::~display()
{
SDL_FreeSurface(minimap_);
// SDL_FreeSurface(minimap_);
prune_chat_messages(true);
}
@ -108,8 +108,8 @@ void display::new_turn()
const time_of_day& old_tod = status_.get_previous_time_of_day();
if(old_tod.image_mask != tod.image_mask) {
const scoped_sdl_surface old_mask(image::get_image(old_tod.image_mask,image::UNMASKED));
const scoped_sdl_surface new_mask(image::get_image(tod.image_mask,image::UNMASKED));
const surface old_mask(image::get_image(old_tod.image_mask,image::UNMASKED));
const surface new_mask(image::get_image(tod.image_mask,image::UNMASKED));
const int niterations = 10;
const int frame_time = 30;
@ -234,6 +234,27 @@ int display::get_location_y(const gamemap::location& loc) const
return map_area().y + loc.y*zoom_ - ypos_ + (is_odd(loc.x) ? zoom_/2 : 0);
}
void display::get_visible_hex_bounds(gamemap::location &topleft, gamemap::location &bottomright) const
{
const SDL_Rect& rect = map_area();
const int tile_width = hex_width();
topleft.x = xpos_ / tile_width;
topleft.y = (ypos_ - (is_odd(topleft.x) ? zoom_/2 : 0)) / zoom_;
bottomright.x = (xpos_ + rect.w) / tile_width;
bottomright.y = ((ypos_ + rect.h) - (is_odd(bottomright.x) ? zoom_/2 : 0)) / zoom_;
if(topleft.x > -1)
topleft.x--;
if(topleft.y > -1)
topleft.y--;
if(bottomright.x < map_.x())
bottomright.x++;
if(bottomright.y < map_.y())
bottomright.y++;
}
gamemap::location display::minimap_location_on(int x, int y)
{
const SDL_Rect rect = minimap_area();
@ -461,12 +482,12 @@ namespace {
void draw_panel(display& disp, const theme::panel& panel, std::vector<gui::button>& buttons)
{
log_scope("draw panel");
scoped_sdl_surface surf(image::get_image(panel.image(),image::UNSCALED));
surface surf(image::get_image(panel.image(),image::UNSCALED));
const SDL_Rect screen = disp.screen_area();
SDL_Rect& loc = panel.location(screen);
if(surf->w != loc.w || surf->h != loc.h) {
surf.assign(scale_surface(surf.get(),loc.w,loc.h));
surf.assign(scale_surface(surf,loc.w,loc.h));
}
disp.blit_surface(loc.x,loc.y,surf);
@ -479,7 +500,7 @@ void draw_panel(display& disp, const theme::panel& panel, std::vector<gui::butto
}
}
void draw_label(display& disp, SDL_Surface* target, const theme::label& label)
void draw_label(display& disp, surface target, const theme::label& label)
{
log_scope("draw label");
@ -488,12 +509,12 @@ void draw_label(display& disp, SDL_Surface* target, const theme::label& label)
SDL_Rect& loc = label.location(disp.screen_area());
if(icon.empty() == false) {
scoped_sdl_surface surf(image::get_image(icon,image::UNSCALED));
surface surf(image::get_image(icon,image::UNSCALED));
if(surf->w != loc.w || surf->h != loc.h) {
surf.assign(scale_surface(surf.get(),loc.w,loc.h));
surf.assign(scale_surface(surf,loc.w,loc.h));
}
SDL_BlitSurface(surf.get(),NULL,target,&loc);
SDL_BlitSurface(surf,NULL,target,&loc);
if(text.empty() == false) {
tooltips::add_tooltip(loc,text);
@ -510,8 +531,11 @@ void draw_label(display& disp, SDL_Surface* target, const theme::label& label)
void display::draw(bool update,bool force)
{
//log_scope("Drawing");
invalidate_animations();
if(!panelsDrawn_) {
SDL_Surface* const screen = screen_.getSurface();
surface const screen(screen_.getSurface());
const std::vector<theme::panel>& panels = theme_.panels();
for(std::vector<theme::panel>::const_iterator p = panels.begin(); p != panels.end(); ++p) {
@ -530,8 +554,11 @@ void display::draw(bool update,bool force)
}
if(invalidateAll_ && !map_.empty()) {
for(int x = -1; x <= map_.x(); ++x)
for(int y = -1; y <= map_.y(); ++y)
gamemap::location topleft;
gamemap::location bottomright;
get_visible_hex_bounds(topleft, bottomright);
for(int x = topleft.x; x <= bottomright.x; ++x)
for(int y = topleft.y; y <= bottomright.y; ++y)
draw_tile(x,y);
invalidateAll_ = false;
@ -629,7 +656,7 @@ void display::draw_game_status(int x, int y)
}
}
void display::draw_image_for_report(scoped_sdl_surface& img, scoped_sdl_surface& surf, SDL_Rect& rect)
void display::draw_image_for_report(surface& img, surface& surf, SDL_Rect& rect)
{
SDL_Rect visible_area = get_non_transperant_portion(img);
SDL_Rect target = rect;
@ -686,7 +713,7 @@ void display::draw_report(reports::TYPE report_num)
reports_[report_num] = report;
scoped_sdl_surface& surf = reportSurfaces_[report_num];
surface& surf = reportSurfaces_[report_num];
if(surf != NULL) {
SDL_BlitSurface(surf,NULL,screen_.getSurface(),&rect);
@ -744,7 +771,7 @@ void display::draw_report(reports::TYPE report_num)
}
} else if(i->image.empty() == false) {
// Draw an image element
scoped_sdl_surface img(image::get_image(i->image,image::UNSCALED));
surface img(image::get_image(i->image,image::UNSCALED));
if(img == NULL) {
std::cerr << "could not find image for report: '" << i->image << "'\n";
@ -784,13 +811,13 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
SDL_Rect clipRect = clip_rect != NULL ? *clip_rect : screen_area();
const scoped_sdl_surface background(image::get_image(game_config::rightside_image,image::UNSCALED));
const scoped_sdl_surface background_bot(image::get_image(game_config::rightside_image_bot,image::UNSCALED));
const surface background(image::get_image(game_config::rightside_image,image::UNSCALED));
const surface background_bot(image::get_image(game_config::rightside_image_bot,image::UNSCALED));
if(background == NULL || background_bot == NULL)
return;
SDL_Surface* const screen = screen_.getSurface();
surface const screen(screen_.getSurface());
if(description_rect.w > 0 && description_rect.x >= mapx()) {
SDL_Rect srcrect = description_rect;
@ -892,7 +919,7 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
y += description_rect.h;
const scoped_sdl_surface profile(image::get_image(u.type().image(),image::UNSCALED));
const surface profile(image::get_image(u.type().image(),image::UNSCALED));
if(profile == NULL)
return;
@ -914,8 +941,8 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
void display::draw_minimap(int x, int y, int w, int h)
{
const scoped_sdl_surface surface(get_minimap(w,h));
if(surface == NULL)
const surface surf(get_minimap(w,h));
if(surf == NULL)
return;
SDL_Rect minimap_location = {x,y,w,h};
@ -923,7 +950,7 @@ void display::draw_minimap(int x, int y, int w, int h)
clip_rect_setter clip_setter(video().getSurface(),minimap_location);
SDL_Rect loc = minimap_location;
SDL_BlitSurface(surface,NULL,video().getSurface(),&loc);
SDL_BlitSurface(surf,NULL,video().getSurface(),&loc);
for(unit_map::const_iterator u = units_.begin(); u != units_.end(); ++u) {
if(fogged(u->first.x,u->first.y) ||
@ -942,8 +969,8 @@ void display::draw_minimap(int x, int y, int w, int h)
SDL_FillRect(video().getSurface(),&rect,mapped_col);
}
const double xscaling = double(surface->w)/double(map_.x());
const double yscaling = double(surface->h)/double(map_.y());
const double xscaling = double(surf->w)/double(map_.x());
const double yscaling = double(surf->h)/double(map_.y());
const int xbox = static_cast<int>(xscaling*xpos_/(zoom_*0.75));
const int ybox = static_cast<int>(yscaling*ypos_/zoom_);
@ -951,8 +978,8 @@ void display::draw_minimap(int x, int y, int w, int h)
const int wbox = static_cast<int>(xscaling*map_area().w/(zoom_*0.75) - xscaling);
const int hbox = static_cast<int>(yscaling*map_area().h/zoom_ - yscaling);
const Uint32 boxcolour = SDL_MapRGB(surface->format,0xFF,0xFF,0xFF);
SDL_Surface* const screen = screen_.getSurface();
const Uint32 boxcolour = SDL_MapRGB(surf->format,0xFF,0xFF,0xFF);
const surface screen(screen_.getSurface());
gui::draw_rectangle(x+xbox,y+ybox,wbox,hbox,boxcolour,screen);
@ -998,8 +1025,8 @@ void display::draw_halo_on_tile(int x, int y)
}
}
void display::draw_unit_on_tile(int x, int y, SDL_Surface* unit_image_override,
double highlight_ratio, Uint32 blend_with)
void display::draw_unit_on_tile(int x, int y, surface unit_image_override,
double highlight_ratio, Uint32 blend_with)
{
if(updatesLocked_)
return;
@ -1022,7 +1049,7 @@ void display::draw_unit_on_tile(int x, int y, SDL_Surface* unit_image_override,
return;
}
SDL_Surface* const dst = screen_.getSurface();
surface const dst(screen_.getSurface());
clip_rect_setter set_clip_rect(dst,clip_rect);
@ -1030,10 +1057,7 @@ void display::draw_unit_on_tile(int x, int y, SDL_Surface* unit_image_override,
SDL_Color energy_colour = {0,0,0,0};
if(unit_image_override != NULL)
sdl_add_ref(unit_image_override);
scoped_sdl_surface unit_image(unit_image_override);
surface unit_image(unit_image_override);
const std::string* energy_file = NULL;
@ -1149,8 +1173,8 @@ void display::draw_unit_on_tile(int x, int y, SDL_Surface* unit_image_override,
}
if(loc != hiddenUnit_) {
scoped_sdl_surface ellipse_front(NULL);
scoped_sdl_surface ellipse_back(NULL);
surface ellipse_front(NULL);
surface ellipse_back(NULL);
if(preferences::show_side_colours()) {
char buf[50];
@ -1181,8 +1205,8 @@ void display::draw_unit_on_tile(int x, int y, SDL_Surface* unit_image_override,
const std::vector<std::string>& overlays = it->second.overlays();
for(std::vector<std::string>::const_iterator ov = overlays.begin(); ov != overlays.end(); ++ov) {
const scoped_sdl_surface img(image::get_image(*ov));
if(img.get() != NULL) {
const surface img(image::get_image(*ov));
if(img != NULL) {
draw_unit(xpos,ypos,img);
}
}
@ -1192,8 +1216,8 @@ void display::draw_bar(const std::string& image, int xpos, int ypos, size_t heig
{
filled = minimum<double>(maximum<double>(filled,0.0),1.0);
scoped_sdl_surface surf(image::get_image(image,image::SCALED,image::NO_ADJUST_COLOUR));
scoped_sdl_surface unmoved_surf(image::get_image("unmoved-energy.png",image::SCALED,image::NO_ADJUST_COLOUR));
surface surf(image::get_image(image,image::SCALED,image::NO_ADJUST_COLOUR));
surface unmoved_surf(image::get_image("unmoved-energy.png",image::SCALED,image::NO_ADJUST_COLOUR));
if(surf == NULL || unmoved_surf == NULL) {
return;
}
@ -1242,20 +1266,20 @@ void display::draw_terrain_on_tile(int x, int y, image::TYPE image_type, ADJACEN
return;
}
SDL_Surface* const dst = screen_.getSurface();
surface const dst(screen_.getSurface());
clip_rect_setter set_clip_rect(dst,clip_rect);
const std::vector<shared_sdl_surface>& images = get_terrain_images(x,y,image_type,type);
const std::vector<surface>& images = get_terrain_images(x,y,image_type,type);
std::vector<shared_sdl_surface>::const_iterator itor;
std::vector<surface>::const_iterator itor;
for(itor = images.begin(); itor != images.end(); ++itor) {
SDL_Rect dstrect = { xpos, ypos, 0, 0 };
SDL_BlitSurface(*itor,NULL,dst,&dstrect);
}
}
void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uint32 blend_to)
void display::draw_tile(int x, int y, surface unit_image, double alpha, Uint32 blend_to)
{
if(updatesLocked_)
return;
@ -1273,7 +1297,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
return;
}
SDL_Surface* const dst = screen_.getSurface();
surface const dst(screen_.getSurface());
clip_rect_setter set_clip_rect(dst,clip_rect);
@ -1314,7 +1338,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
if(!is_shrouded) {
draw_terrain_on_tile(x,y,image_type,ADJACENT_BACKGROUND);
scoped_sdl_surface flag(get_flag(terrain,x,y));
surface flag(get_flag(terrain,x,y));
if(flag != NULL) {
SDL_Rect dstrect = { xpos, ypos, 0, 0 };
SDL_BlitSurface(flag,NULL,dst,&dstrect);
@ -1325,7 +1349,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
for(std::pair<Itor,Itor> overlays = overlays_.equal_range(loc);
overlays.first != overlays.second; ++overlays.first) {
scoped_sdl_surface overlay_surface(image::get_image(overlays.first->second,image_type));
surface overlay_surface(image::get_image(overlays.first->second,image_type));
//note that dstrect can be changed by SDL_BlitSurface and so a
//new instance should be initialized to pass to each call to
@ -1338,7 +1362,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
draw_footstep(loc,xpos,ypos);
} else {
//FIXME: shouldn't void.png and fog.png be in the program configuration?
scoped_sdl_surface surface(image::get_image("terrain/void.png"));
surface surface(image::get_image("terrain/void.png"));
if(surface == NULL) {
std::cerr << "Could not get void surface!\n";
@ -1350,7 +1374,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
}
if(fogged(x,y)) {
const scoped_sdl_surface fog_surface(image::get_image("terrain/fog.png"));
const surface fog_surface(image::get_image("terrain/fog.png"));
if(fog_surface != NULL) {
SDL_Rect dstrect = { xpos, ypos, 0, 0 };
SDL_BlitSurface(fog_surface,NULL,dst,&dstrect);
@ -1375,7 +1399,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
SDL_BlitSurface(tod_hex_mask2,NULL,dst,&dstrect);
}
} else if(mask != "") {
const scoped_sdl_surface img(image::get_image(mask,image::UNMASKED,image::NO_ADJUST_COLOUR));
const surface img(image::get_image(mask,image::UNMASKED,image::NO_ADJUST_COLOUR));
if(img != NULL) {
SDL_Rect dstrect = { xpos, ypos, 0, 0 };
SDL_BlitSurface(img,NULL,dst,&dstrect);
@ -1383,7 +1407,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
}
if(grid_) {
scoped_sdl_surface grid_surface(image::get_image("terrain/grid.png"));
surface grid_surface(image::get_image("terrain/grid.png"));
if(grid_surface != NULL) {
SDL_Rect dstrect = { xpos, ypos, 0, 0 };
SDL_BlitSurface(grid_surface,NULL,dst,&dstrect);
@ -1391,7 +1415,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
}
if(game_config::debug && debugHighlights_.count(gamemap::location(x,y))) {
const scoped_sdl_surface cross(image::get_image(game_config::cross_image));
const surface cross(image::get_image(game_config::cross_image));
if(cross != NULL)
draw_unit(xpos,ypos,cross,false,debugHighlights_[loc],0);
}
@ -1452,7 +1476,7 @@ void display::draw_footstep(const gamemap::location& loc, int xloc, int yloc)
}
}
scoped_sdl_surface image(image::get_image(*image_str));
surface image(image::get_image(*image_str));
if(image == NULL) {
std::cerr << "Could not find image: " << *image_str << "\n";
return;
@ -1583,22 +1607,23 @@ std::vector<std::string> display::get_fog_shroud_graphics(const gamemap::locatio
return res;
}
std::vector<shared_sdl_surface> display::get_terrain_images(int x, int y, image::TYPE image_type, ADJACENT_TERRAIN_TYPE terrain_type)
std::vector<surface> display::get_terrain_images(int x, int y, image::TYPE image_type, ADJACENT_TERRAIN_TYPE terrain_type)
{
std::vector<shared_sdl_surface> res;
std::vector<surface> res;
gamemap::location loc(x,y);
terrain_builder::ADJACENT_TERRAIN_TYPE builder_terrain_type =
(terrain_type == ADJACENT_FOREGROUND ?
terrain_builder::ADJACENT_FOREGROUND : terrain_builder::ADJACENT_BACKGROUND);
const std::vector<image::locator>* const terrains = builder_.get_terrain_at(loc,builder_terrain_type);
const std::vector<animated<image::locator> >* const terrains = builder_.get_terrain_at(loc,builder_terrain_type);
if(terrains != NULL) {
for(std::vector<image::locator>::const_iterator it = terrains->begin(); it != terrains->end(); ++it) {
image::locator image = *it;
image.filename = "terrain/" + it->filename;
for(std::vector<animated<image::locator> >::const_iterator it = terrains->begin(); it != terrains->end(); ++it) {
// it->update_current_frame();
image::locator image = it->get_current_frame();
// image.filename = "terrain/" + image.filename;
const shared_sdl_surface surface(get_terrain(image,image_type,x,y,true));
const surface surface(get_terrain(image,image_type,x,y,true));
if(surface != NULL) {
res.push_back(surface);
}
@ -1611,9 +1636,9 @@ std::vector<shared_sdl_surface> display::get_terrain_images(int x, int y, image:
if(!fog_shroud.empty()) {
for(std::vector<std::string>::const_iterator it = fog_shroud.begin(); it != fog_shroud.end(); ++it) {
image::locator image(*it);
image.filename = "terrain/" + *it;
// image.filename = "terrain/" + *it;
const shared_sdl_surface surface(get_terrain(image,image_type,x,y,true));
const surface surface(get_terrain(image,image_type,x,y,true));
if(surface != NULL) {
res.push_back(surface);
}
@ -1625,10 +1650,10 @@ std::vector<shared_sdl_surface> display::get_terrain_images(int x, int y, image:
return res;
}
SDL_Surface* display::get_terrain(const image::locator& image, image::TYPE image_type,
surface display::get_terrain(const image::locator& image, image::TYPE image_type,
int x, int y, bool search_tod)
{
SDL_Surface* im = NULL;
surface im(NULL);
const time_of_day& tod = status_.get_time_of_day();
const time_of_day& tod_at = timeofday_at(status_,units_,gamemap::location(x,y));
@ -1636,7 +1661,7 @@ SDL_Surface* display::get_terrain(const image::locator& image, image::TYPE image
//see if there is a time-of-day specific version of this image
if(search_tod) {
image::locator tod_image = image;
tod_image.filename = image.filename + "-" + tod.id + ".png";
// tod_image.filename = image.filename + "-" + tod.id + ".png";
im = image::get_image(tod_image,image_type);
if(im != NULL) {
@ -1644,12 +1669,12 @@ SDL_Surface* display::get_terrain(const image::locator& image, image::TYPE image
}
}
image::locator tmp = image;
tmp.filename += ".png";
// image::locator tmp = image;
// tmp.filename += ".png";
im = image::get_image(tmp,image_type);
im = image::get_image(image, image_type);
if(im == NULL) {
return NULL;
return im;
}
//see if this tile is illuminated to a different colour than it'd
@ -1659,8 +1684,8 @@ SDL_Surface* display::get_terrain(const image::locator& image, image::TYPE image
const int badj = tod_at.blue - tod.blue;
if((radj|gadj|badj) != 0 && im != NULL) {
const scoped_sdl_surface backup(im);
im = adjust_surface_colour(im,radj,gadj,badj);
const surface backup(im);
im = surface(adjust_surface_colour(im,radj,gadj,badj));
if(im == NULL)
std::cerr << "could not adjust surface..\n";
}
@ -1668,11 +1693,11 @@ SDL_Surface* display::get_terrain(const image::locator& image, image::TYPE image
return im;
}
SDL_Surface* display::get_flag(gamemap::TERRAIN terrain, int x, int y)
surface display::get_flag(gamemap::TERRAIN terrain, int x, int y)
{
const bool village = map_.is_village(terrain);
if(!village)
return NULL;
return surface(NULL);
const gamemap::location loc(x,y);
@ -1684,23 +1709,23 @@ SDL_Surface* display::get_flag(gamemap::TERRAIN terrain, int x, int y)
}
}
return NULL;
return surface(NULL);
}
void display::blit_surface(int x, int y, SDL_Surface* surface, SDL_Rect* srcrect, SDL_Rect* clip_rect)
void display::blit_surface(int x, int y, surface surf, SDL_Rect* srcrect, SDL_Rect* clip_rect)
{
SDL_Surface* const target = video().getSurface();
const surface target(video().getSurface());
SDL_Rect dst = {x,y,0,0};
if(clip_rect != NULL) {
const clip_rect_setter clip_setter(target,*clip_rect);
SDL_BlitSurface(surface,srcrect,target,&dst);
SDL_BlitSurface(surf,srcrect,target,&dst);
} else {
SDL_BlitSurface(surface,srcrect,target,&dst);
SDL_BlitSurface(surf,srcrect,target,&dst);
}
}
SDL_Surface* display::get_minimap(int w, int h)
surface display::get_minimap(int w, int h)
{
if(minimap_ != NULL && (minimap_->w != w || minimap_->h != h)) {
SDL_FreeSurface(minimap_);
@ -1713,7 +1738,6 @@ SDL_Surface* display::get_minimap(int w, int h)
team_valid() ? &teams_[currentTeam_] : NULL);
}
sdl_add_ref(minimap_);
return minimap_;
}
@ -1762,9 +1786,9 @@ void display::float_label(const gamemap::location& loc, const std::string& text,
0,-2,60,screen_area(),font::CENTER_ALIGN,NULL,0,font::ANCHOR_LABEL_MAP);
}
void display::draw_unit(int x, int y, SDL_Surface* image,
void display::draw_unit(int x, int y, surface image,
bool upside_down, double alpha, Uint32 blendto, double submerged,
SDL_Surface* ellipse_back, SDL_Surface* ellipse_front)
surface ellipse_back, surface ellipse_front)
{
//calculate the y position of the ellipse. It should be the same as the y position of the image, unless
//the image is partially submerged, in which case the ellipse should appear to float 'on top of' the water
@ -1773,8 +1797,7 @@ void display::draw_unit(int x, int y, SDL_Surface* image,
draw_unit(x,ellipse_ypos,ellipse_back,false,blendto == 0 ? alpha : 1.0,0,0.0);
}
sdl_add_ref(image);
scoped_sdl_surface surf(image);
surface surf(image);
if(upside_down) {
surf.assign(flop_surface(surf));
@ -1821,16 +1844,16 @@ struct is_energy_colour {
(colour&0x000000FF) > 0x00000099; }
};
const SDL_Rect& display::calculate_energy_bar(SDL_Surface* surf)
const SDL_Rect& display::calculate_energy_bar(surface surf)
{
const std::map<SDL_Surface*,SDL_Rect>::const_iterator i = energy_bar_rects_.find(surf);
const std::map<surface,SDL_Rect>::const_iterator i = energy_bar_rects_.find(surf);
if(i != energy_bar_rects_.end()) {
return i->second;
}
int first_row = -1, last_row = -1, first_col = -1, last_col = -1;
scoped_sdl_surface image(make_neutral_surface(surf));
surface image(make_neutral_surface(surf));
surface_lock image_lock(image);
const Uint32* const begin = image_lock.pixels();
@ -1852,7 +1875,7 @@ const SDL_Rect& display::calculate_energy_bar(SDL_Surface* surf)
}
const SDL_Rect res = {first_col,first_row,last_col-first_col,last_row+1-first_row};
energy_bar_rects_.insert(std::pair<SDL_Surface*,SDL_Rect>(surf,res));
energy_bar_rects_.insert(std::pair<surface,SDL_Rect>(surf,res));
return calculate_energy_bar(surf);
}
@ -1875,11 +1898,25 @@ void display::invalidate_unit()
invalidateUnit_ = true;
}
void display::invalidate_animations()
{
gamemap::location topleft;
gamemap::location bottomright;
get_visible_hex_bounds(topleft, bottomright);
for(int x = topleft.x; x <= bottomright.x; ++x) {
for(int y = topleft.y; y <= bottomright.y; ++y) {
gamemap::location loc(x,y);
if(builder_.update_animation(loc))
invalidated_.insert(loc);
}
}
}
void display::recalculate_minimap()
{
if(minimap_ != NULL) {
SDL_FreeSurface(minimap_);
minimap_ = NULL;
minimap_.assign(NULL);
}
redraw_minimap();

View file

@ -135,8 +135,8 @@ public:
//over
void highlight_hex(gamemap::location hex);
//given x,y co-ordinates of the mouse, will return the location of the
//hex that the mouse is currently over. Returns an invalid location is
//given x,y co-ordinates of a pixel, will return the location of the
//hex that this pixel corresponds to. Returns an invalid location is
//the mouse isn't over any valid location.
gamemap::location hex_clicked_on(int x, int y);
@ -160,6 +160,9 @@ public:
int get_location_x(const gamemap::location& loc) const;
int get_location_y(const gamemap::location& loc) const;
//returns the locations of 2 hexes that bind the visible area of the map.
void get_visible_hex_bounds(gamemap::location &topleft, gamemap::location &bottomright) const;
//function to remove a footstep from a specific location
void remove_footstep(const gamemap::location& loc);
@ -167,7 +170,7 @@ public:
//then it will be used, otherwise the unit's default image will be used.
//alpha controls how faded the unit is. If blend_to is not 0, then the
//unit will be alpha-blended to blend_to instead of the background colour
void draw_tile(int x, int y, SDL_Surface* unit_image=NULL,
void draw_tile(int x, int y, surface unit_image=surface(NULL),
double alpha=1.0, Uint32 blend_to=0);
//function to float a label above a tile
@ -180,7 +183,7 @@ private:
//composes and draws the terrains on a tile
void draw_terrain_on_tile(int x, int y, image::TYPE image_type, ADJACENT_TERRAIN_TYPE type);
void draw_unit_on_tile(int x, int y, SDL_Surface* unit_image=NULL,
void draw_unit_on_tile(int x, int y, surface unit_image=surface(NULL),
double alpha=1.0, Uint32 blend_to=0);
void draw_halo_on_tile(int x, int y);
@ -199,7 +202,7 @@ public:
CVideo& video() { return screen_; }
//blits a surface with black as alpha
void blit_surface(int x, int y, SDL_Surface* surface, SDL_Rect* srcrect=NULL, SDL_Rect* clip_rect=NULL);
void blit_surface(int x, int y, surface surface, SDL_Rect* srcrect=NULL, SDL_Rect* clip_rect=NULL);
//function to invalidate all tiles.
void invalidate_all();
@ -213,6 +216,9 @@ public:
//function to invalidate that unit status displayed on the sidebar.
void invalidate_unit();
//function to invalidate animated terrains which may have changed.
void invalidate_animations();
//function to schedule the minimap for recalculation. Useful if any
//terrain in the map has changed.
void recalculate_minimap();
@ -314,12 +320,13 @@ public:
// to blend to this colour, instead of the background
//submerged: the amount of the unit out of 1.0 that is submerged
// (presumably under water) and thus shouldn't be drawn
void draw_unit(int x, int y, SDL_Surface* image,
bool upside_down=false,double alpha=1.0, Uint32 blendto=0, double submerged=0.0,
SDL_Surface* ellipse_back=NULL, SDL_Surface* ellipse_front=NULL);
void draw_unit(int x, int y, surface image,
bool upside_down=false,double alpha=1.0, Uint32 blendto=0, double submerged=0.0,
surface ellipse_back=surface(NULL),
surface ellipse_front=surface(NULL));
//rebuild the dynamic terrain at the given location.
void rebuild_terrain(const gamemap::location &location);
void rebuild_terrain(const gamemap::location &location);
//rebuild all dynamic terrain.
void rebuild_all();
@ -355,32 +362,32 @@ private:
SDL_Rect unitDescriptionRect_;
SDL_Rect unitProfileRect_;
void draw_image_for_report(scoped_sdl_surface& img,
scoped_sdl_surface& surf, SDL_Rect& rect);
void draw_image_for_report(surface& img,
surface& surf, SDL_Rect& rect);
void draw_report(reports::TYPE report_num);
SDL_Rect reportRects_[reports::NUM_REPORTS];
scoped_sdl_surface reportSurfaces_[reports::NUM_REPORTS];
surface reportSurfaces_[reports::NUM_REPORTS];
reports::report reports_[reports::NUM_REPORTS];
void bounds_check_position();
// std::vector<shared_sdl_surface> getAdjacentTerrain(int x, int y, image::TYPE type, ADJACENT_TERRAIN_TYPE terrain_type);
std::vector<shared_sdl_surface> get_terrain_images(int x, int y, image::TYPE type, ADJACENT_TERRAIN_TYPE terrain_type);
// std::vector<surface> getAdjacentTerrain(int x, int y, image::TYPE type, ADJACENT_TERRAIN_TYPE terrain_type);
std::vector<surface> get_terrain_images(int x, int y, image::TYPE type, ADJACENT_TERRAIN_TYPE terrain_type);
std::vector<std::string> get_fog_shroud_graphics(const gamemap::location& loc);
//this surface must be freed by the caller
//SDL_Surface* get_terrain(gamemap::TERRAIN, image::TYPE type,
//surface get_terrain(gamemap::TERRAIN, image::TYPE type,
// int x, int y, const std::string& dir="");
//this surface must be freed by the caller
SDL_Surface* get_terrain(const image::locator &image, image::TYPE type,
surface get_terrain(const image::locator &image, image::TYPE type,
int x, int y, bool search_tod);
//this surface must be freed by the caller
SDL_Surface* get_flag(gamemap::TERRAIN, int x, int y);
surface get_flag(gamemap::TERRAIN, int x, int y);
//this surface must be freed by the caller
SDL_Surface* get_minimap(int w, int h);
surface get_minimap(int w, int h);
CVideo& screen_;
mutable CKey keys_;
@ -396,10 +403,10 @@ private:
//function which finds the start and end rows on the energy bar image
//where white pixels are substituted for the colour of the energy
const SDL_Rect& calculate_energy_bar(SDL_Surface* surf);
std::map<SDL_Surface*,SDL_Rect> energy_bar_rects_;
const SDL_Rect& calculate_energy_bar(surface surf);
std::map<surface,SDL_Rect> energy_bar_rects_;
SDL_Surface* minimap_;
surface minimap_;
bool redrawMinimap_;
const paths* pathsList_;
@ -474,7 +481,7 @@ private:
//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
shared_sdl_surface tod_hex_mask1, tod_hex_mask2;
surface tod_hex_mask1, tod_hex_mask2;
typedef std::map<gamemap::location,int> halo_map;
halo_map haloes_;

View file

@ -195,7 +195,7 @@ SDL_Rect text_size(TTF_Font* font, const std::string& str, const SDL_Color& colo
return res;
}
SDL_Surface* render_text_internal(TTF_Font* font,const std::string& str,
surface render_text_internal(TTF_Font* font,const std::string& str,
const SDL_Color& colour, int style)
{
const font_style_setter style_setter(font,style);
@ -212,15 +212,15 @@ SDL_Surface* render_text_internal(TTF_Font* font,const std::string& str,
}
SDL_Surface* render_text(TTF_Font* font,const std::string& text, const SDL_Color& colour, int style)
surface render_text(TTF_Font* font,const std::string& text, const SDL_Color& colour, int style)
{
// XXX Changed by erl, to not strip when rendering text. Works everywhere?
const std::vector<std::string> lines = config::split(text,'\n', config::REMOVE_EMPTY);
std::vector<shared_sdl_surface> surfaces;
std::vector<surface> surfaces;
size_t width = 0, height = 0;
for(std::vector<std::string>::const_iterator ln = lines.begin(); ln != lines.end(); ++ln) {
if(*ln != "" && font != NULL) {
shared_sdl_surface res(render_text_internal(font,*ln,colour,style));
surface res(render_text_internal(font,*ln,colour,style));
if(res != NULL) {
surfaces.push_back(res);
@ -233,24 +233,22 @@ SDL_Surface* render_text(TTF_Font* font,const std::string& text, const SDL_Color
if(surfaces.empty()) {
return NULL;
} else if(surfaces.size() == 1) {
sdl_add_ref(surfaces.front());
return surfaces.front();
} else {
shared_sdl_surface res(create_compatible_surface(surfaces.front(),width,height));
surface res(create_compatible_surface(surfaces.front(),width,height));
if(res == NULL) {
return NULL;
}
size_t ypos = 0;
for(std::vector<shared_sdl_surface>::const_iterator i = surfaces.begin(); i != surfaces.end(); ++i) {
for(std::vector<surface>::const_iterator i = surfaces.begin(); i != surfaces.end(); ++i) {
SDL_SetAlpha(*i,0,0);
SDL_Rect dstrect = {0,ypos,(*i)->w,(*i)->h};
SDL_BlitSurface(*i,NULL,res,&dstrect);
ypos += (*i)->h;
}
sdl_add_ref(res);
return res;
}
}
@ -310,7 +308,7 @@ std::string::const_iterator parse_markup(std::string::const_iterator i1, std::st
}
SDL_Surface* get_rendered_text(const std::string& str, int size, const SDL_Color& colour, int style)
surface get_rendered_text(const std::string& str, int size, const SDL_Color& colour, int style)
{
TTF_Font* const font = get_font(size);
if(font == NULL) {
@ -318,7 +316,7 @@ SDL_Surface* get_rendered_text(const std::string& str, int size, const SDL_Color
return NULL;
}
SDL_Surface *res = render_text(font,str,colour,style);
surface res = render_text(font,str,colour,style);
if(res == NULL) {
return NULL;
}
@ -326,9 +324,9 @@ SDL_Surface* get_rendered_text(const std::string& str, int size, const SDL_Color
}
SDL_Rect draw_text_line(SDL_Surface *gui_surface, const SDL_Rect& area, int size,
SDL_Rect draw_text_line(surface gui_surface, const SDL_Rect& area, int size,
const SDL_Color& colour, const std::string& text,
int x, int y, SDL_Surface* bg, bool use_tooltips, int style)
int x, int y, surface bg, bool use_tooltips, int style)
{
TTF_Font* const font = get_font(size);
@ -344,7 +342,7 @@ SDL_Rect draw_text_line(SDL_Surface *gui_surface, const SDL_Rect& area, int size
return text_size(font,etext,colour,style);
}
scoped_sdl_surface surface(render_text(font,etext,colour,style));
surface surface(render_text(font,etext,colour,style));
if(surface == NULL) {
SDL_Rect res = {0,0,0,0};
return res;
@ -390,9 +388,9 @@ SDL_Rect draw_text_line(SDL_Surface *gui_surface, const SDL_Rect& area, int size
SDL_Rect draw_text_line(display* gui, const SDL_Rect& area, int size,
const SDL_Color& colour, const std::string& text,
int x, int y, SDL_Surface* bg, bool use_tooltips, int style)
int x, int y, surface bg, bool use_tooltips, int style)
{
SDL_Surface* surface;
surface surface;
if(gui == NULL) {
surface = NULL;
@ -411,7 +409,7 @@ SDL_Rect text_area(const std::string& text, int size, int style)
SDL_Rect draw_text(display* gui, const SDL_Rect& area, int size,
const SDL_Color& colour, const std::string& txt,
int x, int y, SDL_Surface* bg, bool use_tooltips,
int x, int y, surface bg, bool use_tooltips,
MARKUP use_markup, int style)
{
//make sure there's always at least a space, so we can ensure
@ -603,7 +601,7 @@ namespace font {
SDL_Rect draw_wrapped_text(display* gui, const SDL_Rect& area, int font_size,
const SDL_Color& colour, const std::string& text,
int x, int y, int max_width, SDL_Surface* bg)
int x, int y, int max_width, surface bg)
{
std::string wrapped_text = word_wrap_text(text, font_size, max_width);
return font::draw_text(gui, area, font_size, colour, wrapped_text, x, y, bg, false, NO_MARKUP);
@ -627,10 +625,10 @@ public:
void move(double xmove, double ymove);
void draw(SDL_Surface* screen);
void undraw(SDL_Surface* screen);
void draw(surface screen);
void undraw(surface screen);
SDL_Surface* create_surface();
surface create_surface();
bool expired() const;
@ -644,7 +642,7 @@ private:
int xpos(size_t width) const;
shared_sdl_surface surf_, buf_, foreground_;
surface surf_, buf_, foreground_;
std::string text_;
int font_size_;
SDL_Color colour_, bgcolour_;
@ -683,12 +681,12 @@ int floating_label::xpos(size_t width) const
return xpos;
}
SDL_Surface* floating_label::create_surface()
surface floating_label::create_surface()
{
if(surf_ == NULL) {
const std::vector<std::string> lines = config::split(text_,'\n');
std::vector<shared_sdl_surface> surfaces;
std::vector<surface> surfaces;
for(std::vector<std::string>::const_iterator ln = lines.begin(); ln != lines.end(); ++ln) {
SDL_Color colour = colour_;
int size = font_size_;
@ -699,7 +697,7 @@ SDL_Surface* floating_label::create_surface()
TTF_Font* const font = get_font(size);
if(str != "" && font != NULL) {
surfaces.push_back(shared_sdl_surface(font::render_text(font,str,colour,style)));
surfaces.push_back(surface(font::render_text(font,str,colour,style)));
}
}
@ -709,7 +707,7 @@ SDL_Surface* floating_label::create_surface()
surf_.assign(surfaces.front());
} else {
size_t width = 0, height = 0;
std::vector<shared_sdl_surface>::const_iterator i;
std::vector<surface>::const_iterator i;
for(i = surfaces.begin(); i != surfaces.end(); ++i) {
width = maximum<size_t>((*i)->w,width);
height += (*i)->h;
@ -733,14 +731,14 @@ SDL_Surface* floating_label::create_surface()
//if the surface has to be created onto some kind of background, then do that here
if(bgalpha_ != 0) {
shared_sdl_surface tmp(create_compatible_surface(surf_,surf_->w+border_*2,surf_->h+border_*2));
surface tmp(create_compatible_surface(surf_,surf_->w+border_*2,surf_->h+border_*2));
if(tmp == NULL) {
return NULL;
}
SDL_FillRect(tmp,NULL,SDL_MapRGB(tmp.get()->format,bgcolour_.r,bgcolour_.g,bgcolour_.b));
SDL_FillRect(tmp,NULL,SDL_MapRGB(tmp->format,bgcolour_.r,bgcolour_.g,bgcolour_.b));
if(bgalpha_ != 255) {
tmp.assign(adjust_surface_alpha_add(tmp.get(),bgalpha_ - 255));
tmp.assign(adjust_surface_alpha_add(tmp,bgalpha_ - 255));
if(tmp == NULL) {
return NULL;
}
@ -754,7 +752,7 @@ SDL_Surface* floating_label::create_surface()
return surf_;
}
void floating_label::draw(SDL_Surface* screen)
void floating_label::draw(surface screen)
{
if(!visible_) {
buf_.assign(NULL);
@ -790,7 +788,7 @@ void floating_label::draw(SDL_Surface* screen)
update_rect(rect);
}
void floating_label::undraw(SDL_Surface* screen)
void floating_label::undraw(surface screen)
{
if(screen == NULL || buf_ == NULL) {
return;
@ -896,7 +894,7 @@ SDL_Rect get_floating_label_rect(int handle)
static const SDL_Rect empty_rect = {0,0,0,0};
const label_map::iterator i = labels.find(handle);
if(i != labels.end()) {
const SDL_Surface* const surf = i->second.create_surface();
const surface surf = i->second.create_surface();
if(surf != NULL) {
SDL_Rect rect = {0,0,surf->w,surf->h};
return rect;
@ -908,7 +906,7 @@ SDL_Rect get_floating_label_rect(int handle)
floating_label_context::floating_label_context()
{
SDL_Surface* const screen = SDL_GetVideoSurface();
surface const screen = SDL_GetVideoSurface();
if(screen != NULL) {
draw_floating_labels(screen);
}
@ -925,13 +923,13 @@ floating_label_context::~floating_label_context()
label_contexts.pop();
SDL_Surface* const screen = SDL_GetVideoSurface();
surface const screen = SDL_GetVideoSurface();
if(screen != NULL) {
undraw_floating_labels(screen);
}
}
void draw_floating_labels(SDL_Surface* screen)
void draw_floating_labels(surface screen)
{
if(label_contexts.empty()) {
return;
@ -948,7 +946,7 @@ void draw_floating_labels(SDL_Surface* screen)
}
}
void undraw_floating_labels(SDL_Surface* screen)
void undraw_floating_labels(surface screen)
{
if(label_contexts.empty()) {
return;

View file

@ -61,14 +61,14 @@ extern const char LARGE_TEXT, SMALL_TEXT, GOOD_TEXT, BAD_TEXT, NORMAL_TEXT, BLAC
SDL_Rect draw_text(display* gui, const SDL_Rect& area, int size,
const SDL_Color& colour, const std::string& text,
int x, int y, SDL_Surface* bg=NULL,
int x, int y, surface bg=NULL,
bool use_tooltips=false, MARKUP use_markup=USE_MARKUP, int style=0);
//function which returns the size of text if it were to be drawn.
SDL_Rect text_area(const std::string& text, int size, int style=0);
// Returns a SDL surface containing the text rendered in a given colour.
SDL_Surface* get_rendered_text(const std::string& text, int size, const SDL_Color& colour, int style=0);
surface get_rendered_text(const std::string& text, int size, const SDL_Color& colour, int style=0);
// Returns the maximum height of a font, in pixels
int get_max_height(int size);
@ -105,7 +105,7 @@ std::string make_text_ellipsis(const std::string& text, int font_size, int max_w
///
SDL_Rect draw_wrapped_text(display* gui, const SDL_Rect& area, int font_size,
const SDL_Color& colour, const std::string& text,
int x, int y, int max_width, SDL_Surface* bg = NULL);
int x, int y, int max_width, surface bg = NULL);
/// structure which will hide all current floating labels, and cause floating labels
@ -150,8 +150,8 @@ const std::string& get_floating_label_text(int handle);
SDL_Rect get_floating_label_rect(int handle);
void draw_floating_labels(SDL_Surface* screen);
void undraw_floating_labels(SDL_Surface* screen);
void draw_floating_labels(surface screen);
void undraw_floating_labels(surface screen);
}

View file

@ -1096,9 +1096,9 @@ int main(int argc, char** argv)
//just means the game should quit
} catch(end_level_exception&) {
std::cerr << "caught end_level_exception (quitting)\n";
} catch(...) {
} /*catch(...) {
std::cerr << "Unhandled exception. Exiting\n";
}
}*/
return 0;
}

View file

@ -776,7 +776,7 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
}
if(cfg["silent"] != "yes") {
scoped_sdl_surface surface(NULL);
surface surface(NULL);
if(image.empty() == false) {
surface.assign(image::get_image(image,image::UNSCALED));
@ -872,7 +872,7 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
option_events.push_back((*mi)->child_range("command"));
}
scoped_sdl_surface surface(NULL);
surface surface(NULL);
if(image.empty() == false) {
surface.assign(image::get_image(image,image::UNSCALED));
}

View file

@ -525,4 +525,4 @@ void extract_summary_data_from_save(const game_state& state, config& out)
}
}
}
}
}

View file

@ -30,35 +30,15 @@ private:
const std::string& current_image();
void rezoom();
struct frame {
frame() : time(50) {}
animated<std::string> images_;
frame(const std::string& str) : time(50) {
if(std::find(str.begin(),str.end(),':') != str.end()) {
const std::vector<std::string>& items = config::split(str,':');
if(items.size() > 1) {
file = items.front();
time = lexical_cast<int>(items.back());
return;
}
}
file = str;
}
int time;
std::string file;
};
std::vector<frame> images_;
std::string current_image_;
bool reverse_;
int start_cycle_, cycle_time_, lifetime_;
int origx_, origy_, x_, y_;
double origzoom_, zoom_;
shared_sdl_surface surf_, buffer_;
surface surf_, buffer_;
SDL_Rect rect_;
};
@ -70,28 +50,21 @@ bool hide_halo = false;
static const SDL_Rect empty_rect = {0,0,0,0};
effect::effect(int xpos, int ypos, const std::string& img, ORIENTATION orientation, int lifetime)
: reverse_(orientation == REVERSE), start_cycle_(-1), cycle_time_(50), lifetime_(lifetime), origx_(xpos), origy_(ypos), x_(xpos), y_(ypos), origzoom_(disp->zoom()), zoom_(disp->zoom()), surf_(NULL), buffer_(NULL), rect_(empty_rect)
: reverse_(orientation == REVERSE), origx_(xpos), origy_(ypos), x_(xpos), y_(ypos), origzoom_(disp->zoom()), zoom_(disp->zoom()), surf_(NULL), buffer_(NULL), rect_(empty_rect), images_(img)
{
if(std::find(img.begin(),img.end(),',') != img.end()) {
const std::vector<std::string>& imgs = config::split(img,',');
images_.resize(imgs.size());
std::copy(imgs.begin(),imgs.end(),images_.begin());
cycle_time_ = 0;
for(std::vector<frame>::const_iterator i = images_.begin(); i != images_.end(); ++i) {
cycle_time_ += i->time;
}
}
if(images_.empty()) {
images_.push_back(img);
}
assert(disp != NULL);
// std::cerr << "Constructing halo sequence from image " << img << "\n";
set_location(xpos,ypos);
current_image_ = images_.front().file;
images_.start_animation(0, -1);
if(!images_.animation_finished()) {
images_.update_current_frame();
SDL_Delay(20);
}
current_image_ = "";
rezoom();
}
@ -109,20 +82,11 @@ void effect::set_location(int x, int y)
const std::string& effect::current_image()
{
assert(!images_.empty());
if(images_.size() == 1 || cycle_time_ <= 0) {
return images_.front().file;
} else {
int current_time = (SDL_GetTicks() - start_cycle_)%cycle_time_;
for(std::vector<frame>::const_iterator i = images_.begin(); i != images_.end(); ++i) {
current_time -= i->time;
if(current_time < 0) {
return i->file;
}
}
}
static const std::string r = "";
return images_.front().file;
const std::string& res = images_.get_current_frame();
return res;
}
void effect::rezoom()
@ -147,10 +111,7 @@ void effect::render()
return;
}
if(start_cycle_ == -1) {
start_cycle_ = SDL_GetTicks();
}
images_.update_current_frame();
const std::string& img = current_image();
if(surf_ == NULL || zoom_ != disp->zoom() || current_image_ != img) {
current_image_ = img;
@ -176,7 +137,7 @@ void effect::render()
return;
}
SDL_Surface* const screen = disp->video().getSurface();
surface const screen = disp->video().getSurface();
const clip_rect_setter clip_setter(screen,clip_rect);
if(buffer_ == NULL || buffer_->w != rect.w || buffer_->h != rect.h) {
@ -198,7 +159,7 @@ void effect::unrender()
return;
}
SDL_Surface* const screen = disp->video().getSurface();
surface const screen = disp->video().getSurface();
SDL_Rect clip_rect = disp->map_area();
const clip_rect_setter clip_setter(screen,clip_rect);
@ -209,7 +170,7 @@ void effect::unrender()
bool effect::expired() const
{
return lifetime_ >= 0 && start_cycle_ >= 0 && SDL_GetTicks() - start_cycle_ > lifetime_*cycle_time_;
return images_.animation_finished();
}
}

View file

@ -2,6 +2,7 @@
#define HALO_HPP_INCLUDED
#include "display.hpp"
#include "animated.hpp"
#include <string>

View file

@ -970,7 +970,7 @@ void help_text_area::show_topic(const topic &t) {
}
help_text_area::item::item(shared_sdl_surface surface, int x, int y, const std::string _text,
help_text_area::item::item(surface surface, int x, int y, const std::string _text,
const std::string reference_to, bool _floating,
bool _box, ALIGNMENT alignment)
: surf(surface), text(_text), ref_to(reference_to), floating(_floating), box(_box),
@ -981,7 +981,7 @@ help_text_area::item::item(shared_sdl_surface surface, int x, int y, const std::
rect.h = box ? surface->h + box_width * 2 : surface->h;
}
help_text_area::item::item(shared_sdl_surface surface, int x, int y, bool _floating,
help_text_area::item::item(surface surface, int x, int y, bool _floating,
bool _box, ALIGNMENT alignment)
: surf(surface), text(""), ref_to(""), floating(_floating), box(_box), align(alignment) {
rect.x = x;
@ -1000,7 +1000,7 @@ void help_text_area::set_items(const std::vector<std::string> &parsed_items,
// Add the title item.
const std::string show_title =
font::make_text_ellipsis(shown_topic_->title, title_size, text_width());
shared_sdl_surface surf(font::get_rendered_text(show_title, title_size,
surface surf(font::get_rendered_text(show_title, title_size,
font::NORMAL_COLOUR, TTF_STYLE_BOLD));
if (surf != NULL) {
add_item(item(surf, 0, 0, show_title));
@ -1270,7 +1270,7 @@ void help_text_area::add_text_item(const std::string text, const std::string ref
state |= italic ? TTF_STYLE_ITALIC : 0;
// Always override the color if we have a cross reference.
const SDL_Color color = ref_dst == "" ? text_color : font::YELLOW_COLOUR;
shared_sdl_surface surf(font::get_rendered_text(first_part, font_size, color, state));
surface surf(font::get_rendered_text(first_part, font_size, color, state));
add_item(item(surf, curr_loc_.first, curr_loc_.second, first_part, ref_dst));
if (parts.size() > 1) {
// Parts remain, remove the first part from the string and
@ -1295,7 +1295,7 @@ void help_text_area::add_text_item(const std::string text, const std::string ref
void help_text_area::add_img_item(const std::string path, const std::string alignment,
const bool floating, const bool box) {
shared_sdl_surface surf(image::get_image(path, image::UNSCALED));
surface surf(image::get_image(path, image::UNSCALED));
if (surf == NULL) {
std::stringstream msg;
msg << "Image " << path << " could not be loaded.";
@ -1458,7 +1458,7 @@ void help_text_area::draw() {
uparrow_.hide(scrollbar_pos == 0 || !scrollbar_.enabled());
downarrow_.hide(scrollbar_pos + scrollbar_.get_grip_height() == (int)scrollbar_.height()
|| !scrollbar_.enabled());
SDL_Surface* const screen = disp_.video().getSurface();
surface const screen = disp_.video().getSurface();
clip_rect_setter clip_rect_set(screen, clip_rect);
std::list<item>::const_iterator it;
for (it = items_.begin(); it != items_.end(); it++) {
@ -2039,7 +2039,7 @@ void show_help(display &disp, const section &toplevel_sec, const std::string sho
const events::resize_lock prevent_resizing;
CVideo& screen = disp.video();
SDL_Surface* const scr = screen.getSurface();
surface const scr = screen.getSurface();
const int width = minimum<int>(900, scr->w - 20);
const int height = minimum<int>(800, scr->h - 150);

View file

@ -223,17 +223,17 @@ private:
/// that should be blitted along with some other information.
struct item {
item(shared_sdl_surface surface, int x, int y, const std::string text="",
item(surface surface, int x, int y, const std::string text="",
const std::string reference_to="", bool floating=false,
bool box=false, ALIGNMENT alignment=HERE);
item(shared_sdl_surface surface, int x, int y,
item(surface surface, int x, int y,
bool floating, bool box=false, ALIGNMENT=HERE);
/// Relative coordinates of this item.
SDL_Rect rect;
shared_sdl_surface surf;
surface surf;
// If this item contains text, this will contain that text.
std::string text;

View file

@ -16,16 +16,22 @@
namespace {
typedef std::map<gamemap::TERRAIN,SDL_Surface*> mini_terrain_cache_map;
typedef std::map<gamemap::TERRAIN, surface> mini_terrain_cache_map;
mini_terrain_cache_map mini_terrain_cache;
typedef std::map<image::locator,SDL_Surface*> image_map;
image_map images_,scaledImages_,unmaskedImages_,greyedImages_;
image_map brightenedImages_,semiBrightenedImages_;
typedef std::map<image::locator::value, int> locator_finder_t;
typedef std::pair<image::locator::value, int> locator_finder_pair;
locator_finder_t locator_finder;
// Definition of all image maps
image::cache images_,scaled_images_,unmasked_images_,greyed_images_;
image::cache brightened_images_,semi_brightened_images_;
// const int cache_version_ = 0;
std::map<image::locator,bool> image_existance_map;
std::map<SDL_Surface*,SDL_Surface*> reversedImages_;
std::map<surface, surface> reversed_images_;
int red_adjust = 0, green_adjust = 0, blue_adjust = 0;
@ -36,144 +42,222 @@ SDL_PixelFormat* pixel_format = NULL;
const int tile_size = 72;
int zoom = tile_size;
//we have to go through all this trickery on clear_surfaces because
//some compilers don't support 'typename type::iterator'
template<typename Map,typename FwIt>
void clear_surfaces_internal(Map& surfaces, FwIt beg, FwIt end)
//The "pointer to surfaces" vector is not cleared anymore (the surface are
//still freed, of course.) I do not think it is a problem, as the number of
//different surfaces the program may lookup has an upper limit, so its
//memory usage won't grow indefinitely over time
void reset_image_cache(image::cache& cache)
{
image::cache::iterator beg = cache.begin();
image::cache::iterator end = cache.end();
for(; beg != end; ++beg) {
SDL_FreeSurface(beg->second);
beg->loaded = false;
beg->image = surface(NULL);
}
surfaces.clear();
}
template<typename Map>
void clear_surfaces(Map& surfaces)
{
clear_surfaces_internal(surfaces,surfaces.begin(),surfaces.end());
}
enum TINT { GREY_IMAGE, BRIGHTEN_IMAGE, SEMI_BRIGHTEN_IMAGE };
SDL_Surface* get_tinted(const image::locator& i_locator, TINT tint)
{
image_map* images;
if (tint == GREY_IMAGE) {
images = &greyedImages_;
} else if (tint == BRIGHTEN_IMAGE) {
images = &brightenedImages_;
} else {
images = &semiBrightenedImages_;
}
const image_map::iterator itor = images->find(i_locator);
if(itor != images->end()) {
return itor->second;
}
scoped_sdl_surface base(image::get_image(i_locator,image::SCALED));
SDL_Surface* surface;
if (tint == GREY_IMAGE) {
surface = greyscale_image(base);
} else if (tint == BRIGHTEN_IMAGE) {
surface = brighten_image(base,1.5);
} else {
surface = brighten_image(base, 1.25);
}
images->insert(std::pair<image::locator,SDL_Surface*>(i_locator,surface));
return surface;
}
void flush_cache()
{
clear_surfaces(images_);
clear_surfaces(scaledImages_);
clear_surfaces(unmaskedImages_);
clear_surfaces(greyedImages_);
clear_surfaces(brightenedImages_);
clear_surfaces(semiBrightenedImages_);
clear_surfaces(mini_terrain_cache);
clear_surfaces(reversedImages_);
}
SDL_Surface* load_image_file(image::locator i_locator)
{
const std::string& location = get_binary_file_location("images",i_locator.filename);
if(location.empty()) {
return NULL;
} else {
SDL_Surface* const res = IMG_Load(location.c_str());
if(res == NULL) {
std::cerr << "Error: could not open image '" << location << "'\n";
}
return res;
}
}
SDL_Surface * load_image_sub_file(image::locator i_locator)
{
SDL_Surface *surf = NULL;
SDL_Surface *tmp = NULL;
scoped_sdl_surface mother_surface(image::get_image(i_locator.filename, image::UNSCALED, image::NO_ADJUST_COLOUR));
scoped_sdl_surface mask(image::get_image(game_config::terrain_mask_image, image::UNSCALED, image::NO_ADJUST_COLOUR));
if(mother_surface == NULL)
return NULL;
if(mask == NULL)
return NULL;
SDL_Rect srcrect = {
((tile_size*3) / 4) * i_locator.loc.x,
tile_size * i_locator.loc.y + (tile_size/2) * (i_locator.loc.x % 2),
tile_size, tile_size
};
tmp = cut_surface(mother_surface, srcrect);
surf = mask_surface(tmp, mask);
SDL_FreeSurface(tmp);
return surf;
}
}
namespace image {
bool locator::operator==(const locator& a) const
void flush_cache()
{
if(a.type != type) {
reset_image_cache(images_);
reset_image_cache(scaled_images_);
reset_image_cache(unmasked_images_);
reset_image_cache(greyed_images_);
reset_image_cache(brightened_images_);
reset_image_cache(semi_brightened_images_);
mini_terrain_cache.clear();
reversed_images_.clear();
}
int locator::last_index_ = 0;
void locator::init_index()
{
locator_finder_t::iterator i = locator_finder.find(val_);
if(i == locator_finder.end()) {
index_ = last_index_++;
locator_finder.insert(locator_finder_pair(val_, index_));
images_.push_back(cache_item());
scaled_images_.push_back(cache_item());
unmasked_images_.push_back(cache_item());
greyed_images_.push_back(cache_item());
brightened_images_.push_back(cache_item());
semi_brightened_images_.push_back(cache_item());
} else {
index_ = i->second;
}
}
locator::locator() :
val_(), index_(-1)
{
}
locator::locator(const locator &a):
val_(a.val_), index_(a.index_)
{
}
locator::locator(const char *filename) :
val_(filename)
{
init_index();
}
locator::locator(const std::string &filename) :
val_(filename)
{
init_index();
}
locator::locator(const std::string &filename, const gamemap::location &loc) :
val_(filename, loc)
{
init_index();
}
locator& locator::operator=(const locator &a)
{
index_ = a.index_;
val_ = a.val_;
return *this;
}
locator::value::value(const locator::value& a) :
type_(a.type_), filename_(a.filename_), loc_(a.loc_)
{
}
locator::value::value() :
type_(NONE)
{}
locator::value::value(const char *filename) :
type_(FILE), filename_(filename)
{
}
locator::value::value(const std::string& filename) :
type_(FILE), filename_(filename)
{
}
locator::value::value(const std::string& filename, const gamemap::location& loc) :
type_(SUB_FILE), filename_(filename), loc_(loc)
{
}
bool locator::value::operator==(const value& a) const
{
if(a.type_ != type_) {
return false;
} else if(type == FILE) {
return filename == a.filename;
} else if(type == SUB_FILE) {
return filename == a.filename && loc == a.loc;
} else if(type_ == FILE) {
return filename_ == a.filename_;
} else if(type_ == SUB_FILE) {
return filename_ == a.filename_ && loc_ == a.loc_;
} else {
return false;
}
}
bool locator::operator<(const locator &a) const
bool locator::value::operator<(const value& a) const
{
if(type != a.type) {
return type < a.type;
} else if(type == FILE) {
return filename < a.filename;
} else if(type == SUB_FILE) {
if(filename != a.filename)
return filename < a.filename;
if(type_ != a.type_) {
return type_ < a.type_;
} else if(type_ == FILE) {
return filename_ < a.filename_;
} else if(type_ == SUB_FILE) {
if(filename_ != a.filename_)
return filename_ < a.filename_;
return loc < a.loc;
return loc_ < a.loc_;
} else {
return false;
}
}
surface locator::load_image_file() const
{
const std::string& location = get_binary_file_location("images", val_.filename_);
if(location.empty()) {
return surface(NULL);
} else {
const surface res(IMG_Load(location.c_str()));
if(res == NULL) {
std::cerr << "Error: could not open image '" << val_.filename_ << "'\n";
}
return res;
}
}
surface locator::load_image_sub_file() const
{
const surface mother_surface(get_image(val_.filename_, UNSCALED, NO_ADJUST_COLOUR));
const surface mask(get_image(game_config::terrain_mask_image, UNSCALED, NO_ADJUST_COLOUR));
if(mother_surface == NULL)
return surface(NULL);
if(mask == NULL)
return surface(NULL);
SDL_Rect srcrect = {
((tile_size*3) / 4) * val_.loc_.x,
tile_size * val_.loc_.y + (tile_size/2) * (val_.loc_.x % 2),
tile_size, tile_size
};
surface tmp(cut_surface(mother_surface, srcrect));
surface surf(mask_surface(tmp, mask));
return surf;
}
surface locator::load_from_disk() const
{
switch(val_.type_) {
case FILE:
return load_image_file();
case SUB_FILE:
return load_image_sub_file();
default:
return surface(NULL);
}
assert(false);
}
bool locator::in_cache(const cache& cache) const
{
if(index_ == -1)
return surface(NULL);
return cache[index_].loaded;
}
surface locator::locate_in_cache(const cache& cache) const
{
if(index_ == -1)
return surface(NULL);
return cache[index_].image;
}
void locator::add_to_cache(cache& cache, const surface& image) const
{
if(index_ == -1)
return;
cache[index_] = cache_item(image);
}
manager::manager() {}
manager::~manager()
@ -184,7 +268,7 @@ manager::~manager()
void set_wm_icon()
{
#if !(defined(__APPLE__))
scoped_sdl_surface icon(get_image(game_config::game_icon,UNSCALED));
surface icon(get_image(game_config::game_icon,UNSCALED));
if(icon != NULL) {
::SDL_WM_SetIcon(icon,NULL);
}
@ -203,14 +287,15 @@ void set_colour_adjustment(int r, int g, int b)
red_adjust = r;
green_adjust = g;
blue_adjust = b;
clear_surfaces(scaledImages_);
clear_surfaces(greyedImages_);
clear_surfaces(brightenedImages_);
clear_surfaces(semiBrightenedImages_);
clear_surfaces(reversedImages_);
reset_image_cache(scaled_images_);
reset_image_cache(greyed_images_);
reset_image_cache(brightened_images_);
reset_image_cache(semi_brightened_images_);
reversed_images_.clear();
}
}
void get_colour_adjustment(int *r, int *g, int *b)
{
if(r != NULL) {
@ -226,15 +311,16 @@ void get_colour_adjustment(int *r, int *g, int *b)
}
}
void set_image_mask(const std::string& image)
{
if(image_mask != image) {
image_mask = image;
clear_surfaces(scaledImages_);
clear_surfaces(greyedImages_);
clear_surfaces(brightenedImages_);
clear_surfaces(semiBrightenedImages_);
clear_surfaces(reversedImages_);
reset_image_cache(scaled_images_);
reset_image_cache(greyed_images_);
reset_image_cache(brightened_images_);
reset_image_cache(semi_brightened_images_);
reversed_images_.clear();
}
}
@ -243,203 +329,192 @@ void set_zoom(int amount)
{
if(amount != zoom) {
zoom = amount;
clear_surfaces(scaledImages_);
clear_surfaces(greyedImages_);
clear_surfaces(brightenedImages_);
clear_surfaces(semiBrightenedImages_);
clear_surfaces(unmaskedImages_);
clear_surfaces(reversedImages_);
reset_image_cache(scaled_images_);
reset_image_cache(greyed_images_);
reset_image_cache(brightened_images_);
reset_image_cache(semi_brightened_images_);
reset_image_cache(unmasked_images_);
reversed_images_.clear();
}
}
SDL_Surface* get_image(const image::locator& i_locator, TYPE type, COLOUR_ADJUSTMENT adjust_colour)
surface get_unmasked(const locator i_locator, COLOUR_ADJUSTMENT adj)
{
SDL_Surface* result = NULL;
if(type == GREYED) {
result = get_tinted(i_locator,GREY_IMAGE);
} else if(type == BRIGHTENED) {
result = get_tinted(i_locator,BRIGHTEN_IMAGE);
} else if(type == SEMI_BRIGHTENED) {
result = get_tinted(i_locator,SEMI_BRIGHTEN_IMAGE);
surface image(get_image(i_locator, UNSCALED));
surface res(scale_surface(image, zoom, zoom));
return res;
}
surface get_scaled(const locator i_locator, COLOUR_ADJUSTMENT adj)
{
surface res(get_image(i_locator, UNMASKED, adj));
// Adjusts colour if necessary.
if(adj == ADJUST_COLOUR && (red_adjust != 0 ||
green_adjust != 0 || blue_adjust != 0)) {
res = surface(adjust_surface_colour(res,
red_adjust, green_adjust, blue_adjust));
}
const surface mask(get_image(image_mask,UNMASKED,NO_ADJUST_COLOUR));
if(mask != NULL) {
SDL_SetAlpha(mask,SDL_SRCALPHA|SDL_RLEACCEL,SDL_ALPHA_OPAQUE);
SDL_SetAlpha(res,SDL_SRCALPHA|SDL_RLEACCEL,SDL_ALPHA_OPAQUE);
//commented out pending reply from SDL team about bug report
//SDL_BlitSurface(mask,NULL,result,NULL);
}
return res;
}
surface get_greyed(const locator i_locator, COLOUR_ADJUSTMENT adj)
{
surface image(get_image(i_locator, SCALED, adj));
return surface(greyscale_image(image));
}
surface get_brightened(const locator i_locator, COLOUR_ADJUSTMENT adj)
{
surface image(get_image(i_locator, SCALED, adj));
return surface(brighten_image(image, 1.5));
}
surface get_semi_brightened(const locator i_locator, COLOUR_ADJUSTMENT adj)
{
surface image(get_image(i_locator, SCALED, adj));
return surface(brighten_image(image, 1.25));
}
surface get_image(const image::locator& i_locator, TYPE type, COLOUR_ADJUSTMENT adj)
{
surface res(NULL);
cache *imap;
if(i_locator.is_void())
return surface(NULL);
switch(type) {
case UNSCALED:
imap = &images_;
break;
case SCALED:
imap = &scaled_images_;
break;
case UNMASKED:
imap = &unmasked_images_;
break;
case GREYED:
imap = &greyed_images_;
break;
case BRIGHTENED:
imap = &brightened_images_;
break;
case SEMI_BRIGHTENED:
imap = &semi_brightened_images_;
break;
default:
return surface(NULL);
}
if(i_locator.in_cache(*imap))
return i_locator.locate_in_cache(*imap);
// If type is unscaled, directly load the image from the disk. Else,
// create it from the unscaled image
if(type == UNSCALED) {
res = i_locator.load_from_disk();
if(res == NULL) {
i_locator.add_to_cache(*imap, surface(NULL));
return surface(NULL);
}
} else {
image_map::iterator i;
// surface base_image(get_image(i_locator, UNSCALED));
if(type == SCALED) {
i = scaledImages_.find(i_locator);
if(i != scaledImages_.end()) {
result = i->second;
sdl_add_ref(result);
return result;
}
}
if(type == UNMASKED) {
i = unmaskedImages_.find(i_locator);
if(i != unmaskedImages_.end()) {
result = i->second;
sdl_add_ref(result);
return result;
}
}
i = images_.find(i_locator);
if(i == images_.end()) {
SDL_Surface* surf = NULL;
switch(i_locator.type)
{
case locator::FILE:
surf = load_image_file(i_locator);
break;
case locator::SUB_FILE:
surf = load_image_sub_file(i_locator);
break;
default:
surf = NULL;
}
if(surf == NULL) {
images_.insert(std::pair<image::locator,SDL_Surface*>(i_locator,NULL));
return NULL;
}
if(pixel_format != NULL) {
SDL_Surface* const conv = display_format_alpha(surf);
SDL_FreeSurface(surf);
surf = conv;
}
i = images_.insert(std::pair<image::locator,SDL_Surface*>(i_locator,surf)).first;
}
if(i->second == NULL)
return NULL;
if(type == UNSCALED) {
result = i->second;
} else {
const scoped_sdl_surface scaled_surf(scale_surface(i->second,zoom,zoom));
if(scaled_surf == NULL) {
return NULL;
}
if(adjust_colour == ADJUST_COLOUR && (red_adjust != 0 || green_adjust != 0 || blue_adjust != 0)) {
const scoped_sdl_surface scoped_surface(result);
result = adjust_surface_colour(scaled_surf,red_adjust,green_adjust,blue_adjust);
} else {
result = create_optimized_surface(scaled_surf);
}
if(result == NULL) {
return NULL;
}
if(type == SCALED && adjust_colour == ADJUST_COLOUR && image_mask != "") {
const scoped_sdl_surface mask(get_image(image_mask,UNMASKED,NO_ADJUST_COLOUR));
if(mask != NULL) {
SDL_SetAlpha(mask,SDL_SRCALPHA|SDL_RLEACCEL,SDL_ALPHA_OPAQUE);
SDL_SetAlpha(result,SDL_SRCALPHA|SDL_RLEACCEL,SDL_ALPHA_OPAQUE);
//commented out pending reply from SDL team about bug report
//SDL_BlitSurface(mask,NULL,result,NULL);
}
}
if(type == UNMASKED) {
unmaskedImages_.insert(std::pair<image::locator,SDL_Surface*>(i_locator,result));
} else {
scaledImages_.insert(std::pair<image::locator,SDL_Surface*>(i_locator,result));
}
switch(type) {
case SCALED:
res = get_scaled(i_locator, adj);
break;
case UNMASKED:
res = get_unmasked(i_locator, adj);
break;
case GREYED:
res = get_greyed(i_locator, adj);
break;
case BRIGHTENED:
res = get_brightened(i_locator, adj);
break;
case SEMI_BRIGHTENED:
res = get_semi_brightened(i_locator, adj);
break;
default:
return surface(NULL);
}
}
if(result != NULL) {
SDL_SetAlpha(result,SDL_SRCALPHA|SDL_RLEACCEL,SDL_ALPHA_OPAQUE);
}
sdl_add_ref(result);
return result;
// optimizes surface before storing it
res = create_optimized_surface(res);
i_locator.add_to_cache(*imap, res);
return res;
}
SDL_Surface* get_image_dim(const image::locator& i_locator, size_t x, size_t y)
surface get_image_dim(const image::locator& i_locator, size_t x, size_t y)
{
SDL_Surface* const surf = get_image(i_locator,UNSCALED);
const surface surf(get_image(i_locator,UNSCALED));
if(surf != NULL && (size_t(surf->w) != x || size_t(surf->h) != y)) {
SDL_Surface* const new_image = scale_surface(surf,x,y);
images_.erase(i_locator);
const surface new_image(scale_surface(surf,x,y));
//free surf twice: once because calling get_image adds a reference.
//again because we also want to remove the cache reference, since
//we're removing it from the cache
SDL_FreeSurface(surf);
SDL_FreeSurface(surf);
images_[i_locator] = new_image;
sdl_add_ref(new_image);
i_locator.add_to_cache(images_, new_image);
return new_image;
}
return surf;
}
SDL_Surface* reverse_image(SDL_Surface* surf)
surface reverse_image(const surface& surf)
{
if(surf == NULL) {
return NULL;
return surface(NULL);
}
const std::map<SDL_Surface*,SDL_Surface*>::iterator itor = reversedImages_.find(surf);
if(itor != reversedImages_.end()) {
sdl_add_ref(itor->second);
const std::map<surface,surface>::iterator itor = reversed_images_.find(surf);
if(itor != reversed_images_.end()) {
// sdl_add_ref(itor->second);
return itor->second;
}
SDL_Surface* const rev = flip_surface(surf);
const surface rev(flip_surface(surf));
if(rev == NULL) {
return NULL;
return surface(NULL);
}
reversedImages_.insert(std::pair<SDL_Surface*,SDL_Surface*>(surf,rev));
sdl_add_ref(rev);
reversed_images_.insert(std::pair<surface,surface>(surf,rev));
// sdl_add_ref(rev);
return rev;
}
void register_image(const image::locator& id, SDL_Surface* surf)
void register_image(const image::locator& id, const surface& surf)
{
if(surf == NULL) {
return;
}
image_map::iterator i = images_.find(id);
if(i != images_.end()) {
SDL_FreeSurface(i->second);
}
images_[id] = surf;
}
void register_image(const std::string &id, SDL_Surface* surf)
{
register_image(locator(id), surf);
id.add_to_cache(images_, surf);
}
bool exists(const image::locator& i_locator)
{
bool ret=false;
if(i_locator.type != image::locator::FILE &&
i_locator.type != image::locator::SUB_FILE)
if(i_locator.get_type() != image::locator::FILE &&
i_locator.get_type() != image::locator::SUB_FILE)
return false;
if(image_existance_map.find(i_locator) != image_existance_map.end())
return image_existance_map[i_locator];
if(get_binary_file_location("images",i_locator.filename).empty() == false) {
if(get_binary_file_location("images",i_locator.get_filename()).empty() == false) {
ret = true;
}
@ -448,7 +523,7 @@ bool exists(const image::locator& i_locator)
return ret;
}
SDL_Surface* getMinimap(int w, int h, const gamemap& map,
surface getMinimap(int w, int h, const gamemap& map,
int lawful_bonus, const team* tm)
{
std::cerr << "generating minimap\n";
@ -459,20 +534,20 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
const size_t map_width = map.x()*scale*3/4;
const size_t map_height = map.y()*scale;
if(map_width == 0 || map_height == 0) {
return NULL;
return surface(NULL);
}
SDL_Surface* minimap = SDL_CreateRGBSurface(SDL_SWSURFACE,
surface minimap(SDL_CreateRGBSurface(SDL_SWSURFACE,
map_width,map_height,
pixel_format->BitsPerPixel,
pixel_format->Rmask,
pixel_format->Gmask,
pixel_format->Bmask,
pixel_format->Amask);
pixel_format->Amask));
if(minimap == NULL)
return NULL;
return surface(NULL);
std::cerr << "created minimap: " << int(minimap) << "," << int(minimap->pixels) << "\n";
// std::cerr << "created minimap: " << int(minimap) << "," << int(minimap->pixels) << "\n";
typedef mini_terrain_cache_map cache_map;
cache_map& cache = mini_terrain_cache;
@ -480,8 +555,7 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
for(int y = 0; y != map.y(); ++y) {
for(int x = 0; x != map.x(); ++x) {
SDL_Surface* surf = NULL;
scoped_sdl_surface scoped_surface(NULL);
surface surf(NULL);
const gamemap::location loc(x,y);
if(map.on_board(loc)) {
@ -491,7 +565,7 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
cache_map::iterator i = cache.find(terrain);
if(i == cache.end()) {
scoped_sdl_surface tile(get_image("terrain/" + map.get_terrain_info(terrain).default_image() + ".png",image::UNSCALED));
surface tile(get_image("terrain/" + map.get_terrain_info(terrain).default_image() + ".png",image::UNSCALED));
if(tile == NULL) {
std::cerr << "Could not get image for terrrain '"
@ -499,7 +573,7 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
continue;
}
surf = scale_surface_blended(tile,scale,scale);
surf = surface(scale_surface_blended(tile,scale,scale));
if(surf == NULL) {
continue;
@ -507,12 +581,11 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
i = cache.insert(cache_map::value_type(terrain,surf)).first;
} else {
surf = i->second;
surf = surface(i->second);
}
if(fogged) {
scoped_surface.assign(adjust_surface_colour(surf,-50,-50,-50));
surf = scoped_surface;
surf = surface(adjust_surface_colour(surf,-50,-50,-50));
}
assert(surf != NULL);
@ -523,11 +596,11 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
}
}
std::cerr << "scaling minimap..." << int(minimap) << "." << int(minimap->pixels) << "\n";
// std::cerr << "scaling minimap..." << int(minimap) << "." << int(minimap->pixels) << "\n";
if((minimap->w != w || minimap->h != h) && w != 0) {
const scoped_sdl_surface surf(minimap);
minimap = scale_surface(surf,w,h);
const surface surf(minimap);
minimap = surface(scale_surface(surf,w,h));
}
std::cerr << "done generating minimap\n";

View file

@ -6,6 +6,7 @@
#include "SDL.h"
#include <string>
#include <vector>
class team;
@ -22,21 +23,82 @@ class team;
/// - greyed: images are scaled and in greyscale
/// - brightened: images are scaled and brighter than normal.
namespace image {
///a generic image locator. Abstracts the location of an image.
///used as a key for a std::map
struct locator
struct cache_item {
cache_item() : loaded(false), image(NULL) {}
cache_item(surface image) : loaded(true), image(image) {}
bool loaded;
surface image;
};
typedef std::vector<cache_item> cache;
//a generic image locator. Abstracts the location of an image.
class locator
{
locator(const char *filename) : filename(filename) { type = FILE; }
locator(const std::string& filename) : filename(filename) { type = FILE; }
locator(const std::string& filename, const gamemap::location& loc) : filename(filename), loc(loc)
{ type = SUB_FILE; }
private:
// Called by each constructor after actual construction to
// initialize the index_ field
void init_index();
public:
enum type { NONE, FILE, SUB_FILE };
bool operator==(const locator &a) const;
bool operator<(const locator &a) const;
struct value {
value();
value(const value &a);
value(const char *filename);
value(const std::string& filename);
value(const std::string& filename, const gamemap::location& loc);
bool operator==(const value& a) const;
bool operator<(const value& a) const;
enum { FILE, SUB_FILE } type;
std::string filename;
gamemap::location loc;
type type_;
std::string filename_;
gamemap::location loc_;
};
// Constructing locators is somewhat slow, accessing image
// through locators is fast. The idea is that calling functions
// should store locators, and not strings to construct locators
// (the second will work, of course, but will be slower)
locator();
locator(const locator &a);
locator(const char *filename);
locator(const std::string& filename);
locator(const std::string& filename, const gamemap::location& loc);
locator& operator=(const locator &a);
bool operator==(const locator &a) const { return index_ == a.index_; }
bool operator<(const locator &a) const { return index_ < a.index_; }
const std::string &get_filename() const { return val_.filename_; }
const gamemap::location& get_loc() const { return val_.loc_ ; }
const type get_type() const { return val_.type_; };
// const int get_index() const { return index_; };
// returns true if the locator does not correspond to any
// actual image
bool is_void() const { return val_.type_ == NONE; }
// returns true if the locator already was stored in the given
// cache
bool locator::in_cache(const cache& cache) const;
// loads the image it is pointing to from the disk
surface load_from_disk() const;
// returns the image it is corresponding to in the given cache
surface locate_in_cache(const cache& cache) const;
// adds the given image to the given cache, indexed with the
// current locator
void add_to_cache(cache& cache, const surface &image) const;
protected:
static int last_index_;
private:
surface load_image_file() const;
surface load_image_sub_file() const;
int index_;
value val_;
};
///the image manager is responsible for setting up images, and destroying
@ -80,32 +142,32 @@ namespace image {
///function to get the surface corresponding to an image.
///note that this surface must be freed by the user by calling
///SDL_FreeSurface()
SDL_Surface* get_image(const locator& i_locator,TYPE type=SCALED, COLOUR_ADJUSTMENT adj=ADJUST_COLOUR);
surface get_image(const locator& i_locator,TYPE type=SCALED, COLOUR_ADJUSTMENT adj=ADJUST_COLOUR);
///function to get a scaled image, but scale it to specific dimensions.
///if you later try to get the same image using get_image() the image will
///have the dimensions specified here.
///Note that this surface must be freed by the user by calling SDL_FreeSurface
SDL_Surface* get_image_dim(const locator& i_locator, size_t x, size_t y);
surface get_image_dim(const locator& i_locator, size_t x, size_t y);
///function to reverse an image. The image MUST have originally been returned from
///an image:: function. Returned images have the same semantics as for get_image()
///and must be freed using SDL_FreeSurface()
SDL_Surface* reverse_image(SDL_Surface* surf);
surface reverse_image(const surface &surf);
///function to register an image with the given id. Calls to get_image(id,UNSCALED) will
///return this image. register_image() will take ownership of this image and free
///it when the cache is cleared (change of video mode or colour adjustment).
///If there is already an image registered with this id, that image will be freed
///and replaced with this image.
void register_image(const locator& i_locator, SDL_Surface* surf);
void register_image(const locator& i_locator, const surface& surf);
//returns true if the given image actually exists, without loading it.
bool exists(const locator& i_locator);
///function to create the minimap for a given map
///the surface returned must be freed by the user
SDL_Surface* getMinimap(int w, int h, const gamemap& map_, int lawful_bonus, const team* tm=NULL);
surface getMinimap(int w, int h, const gamemap& map_, int lawful_bonus, const team* tm=NULL);
}
#endif

View file

@ -94,7 +94,7 @@ bool show_intro_part(display& screen, const config& part,
0,0,0,1.0,screen.video().getSurface());
const std::string& image_name = part["image"];
scoped_sdl_surface image(NULL);
surface image(NULL);
if(image_name.empty() == false) {
image.assign(image::get_image(image_name,image::UNSCALED));
}
@ -251,9 +251,9 @@ void show_map_scene(display& screen, config& data)
const std::string& image_file = cfg["image"];
const scoped_sdl_surface image(image::get_image(image_file,image::UNSCALED));
const scoped_sdl_surface dot_image(image::get_image(game_config::dot_image,image::UNSCALED));
const scoped_sdl_surface cross_image(image::get_image(game_config::cross_image,image::UNSCALED));
const surface image(image::get_image(image_file,image::UNSCALED));
const surface dot_image(image::get_image(game_config::dot_image,image::UNSCALED));
const surface cross_image(image::get_image(game_config::cross_image,image::UNSCALED));
if(image == NULL || dot_image == NULL || cross_image == NULL) {
std::cerr << "could not find map image: '" << image_file << "': " << (image == NULL ? "failed" : "ok") << "\n"
<< "'" << game_config::dot_image << "': " << (dot_image == NULL ? "failed" : "ok") << "\n"
@ -291,7 +291,7 @@ void show_map_scene(display& screen, config& data)
if(x < 0 || x >= image->w || y < 0 || y >= image->w)
continue;
SDL_Surface* img = dot_image;
surface img = dot_image;
if((**d)["type"] == "cross") {
img = cross_image;
}

View file

@ -132,21 +132,6 @@ void gamemap::location::write(config& cfg) const
cfg["y"] = buf;
}
bool gamemap::location::operator==(const gamemap::location& a) const
{
return x == a.x && y == a.y;
}
bool gamemap::location::operator!=(const gamemap::location& a) const
{
return !operator==(a);
}
bool gamemap::location::operator<(const gamemap::location& a) const
{
return x < a.x || x == a.x && y < a.y;
}
gamemap::location gamemap::location::operator-() const
{
location ret;

View file

@ -65,9 +65,11 @@ public:
int x, y;
bool operator<(const location& a) const;
bool operator==(const location& a) const;
bool operator!=(const location& a) const;
// Inlining those for performance reasons
bool operator<(const location& a) const { return x < a.x || x == a.x && y < a.y; }
bool operator==(const location& a) const { return x == a.x && y == a.y; }
bool operator!=(const location& a) const { return !operator==(a); }
// Adds an absolute location to a "delta" location
location operator-() const;
location operator+(const location &a) const;

View file

@ -467,7 +467,7 @@ lobby::RESULT multiplayer_game_setup_dialog::process()
}
SDL_Rect rect = minimap_restorer_.area();
const scoped_sdl_surface mini(image::getMinimap(rect.w,rect.h,map,0));
const surface mini(image::getMinimap(rect.w,rect.h,map,0));
if(mini != NULL) {
SDL_BlitSurface(mini, NULL, disp_.video().getSurface(), &rect);

View file

@ -42,7 +42,7 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
CKey key;
scoped_sdl_surface background(image::get_image("misc/lobby.png",image::UNSCALED));
surface background(image::get_image("misc/lobby.png",image::UNSCALED));
background.assign(scale_surface(background,disp.x(),disp.y()));
if(background == NULL) {
@ -110,11 +110,11 @@ RESULT enter(display& disp, config& game_data, const config& terrain_data, dialo
if(map_data != "") {
try {
gamemap map(terrain_data,map_data);
SDL_Surface* const mini = image::getMinimap(100,100,map,0);
const surface mini(image::getMinimap(100,100,map,0));
//generate a unique id to show the map as
char buf[50];
sprintf(buf,"addr %d",(int)mini);
sprintf(buf,"addr %d",(int)(SDL_Surface*)mini);
image::register_image(buf,mini);

View file

@ -118,6 +118,7 @@ void play_turn(game_data& gameinfo, game_state& state_of_game,
throw e;
}
// gui.invalidate_animations();
gui.draw();
turn_data.send_data();
@ -2361,7 +2362,7 @@ void turn_info::create_textbox(floating_textbox::MODE mode, const std::string& l
const int border_size = 10;
const int ypos = area.y+area.h-30 - (textbox_.check.get() != NULL ? textbox_.check->height() + border_size : 0);
const int ypos = area.y+area.h-30 - (textbox_.check != NULL ? textbox_.check->height() + border_size : 0);
textbox_.label = font::add_floating_label(label,14,font::YELLOW_COLOUR,area.x+border_size,ypos,0,0,-1,
area,font::LEFT_ALIGN);
if(textbox_.label == 0) {
@ -2380,7 +2381,7 @@ void turn_info::create_textbox(floating_textbox::MODE mode, const std::string& l
textbox_.box->set_volatile(true);
textbox_.box->set_location(area.x + label_area.w + border_size*2,ypos);
if(textbox_.check.get() != NULL) {
if(textbox_.check != NULL) {
textbox_.check->set_volatile(true);
textbox_.check->set_location(textbox_.box->location().x,textbox_.box->location().y + textbox_.box->location().h + border_size);
}
@ -2391,7 +2392,7 @@ void turn_info::close_textbox()
if(textbox_.active() == false) {
return;
}
if(textbox_.check.get() != NULL) {
if(textbox_.check != NULL) {
if(textbox_.mode == floating_textbox::TEXTBOX_MESSAGE) {
preferences::set_message_private(textbox_.check->checked());
}
@ -2414,7 +2415,7 @@ void turn_info::enter_textbox()
do_search(textbox_.box->text());
break;
case floating_textbox::TEXTBOX_MESSAGE:
do_speak(textbox_.box->text(),textbox_.check.get() != NULL ? textbox_.check->checked() : false);
do_speak(textbox_.box->text(),textbox_.check != NULL ? textbox_.check->checked() : false);
break;
default:
std::cerr << "unknown textbox mode\n";

View file

@ -934,4 +934,4 @@ void replay_network_sender::commit_and_sync()
upto_ = obj_.ncommands();
}
}
}

View file

@ -41,7 +41,7 @@ namespace {
if(first_time) {
first_time = false;
scoped_sdl_surface surf(SDL_CreateRGBSurface(SDL_SWSURFACE,1,1,32,0xFF0000,0xFF00,0xFF,0xFF000000));
surface surf(SDL_CreateRGBSurface(SDL_SWSURFACE,1,1,32,0xFF0000,0xFF00,0xFF,0xFF000000));
format = *surf->format;
format.palette = NULL;
}
@ -51,14 +51,33 @@ namespace {
}
SDL_Surface* make_neutral_surface(SDL_Surface* surf)
void free_sdl_surface::operator()(SDL_Surface* surf) const
{
if(surf != NULL)
SDL_FreeSurface(surf);
}
/*explicit*/ surface::surface(SDL_Surface* surf) : surface_(surf)
{
}
int surface::sdl_add_ref(SDL_Surface* surf)
{
if(surf != NULL) {
return surf->refcount++;
} else {
return 0;
}
}
surface make_neutral_surface(surface surf)
{
if(surf == NULL) {
std::cerr << "null neutral surface...\n";
return NULL;
}
SDL_Surface* const result = SDL_ConvertSurface(surf,&get_neutral_pixel_format(),SDL_SWSURFACE);
surface const result = SDL_ConvertSurface(surf,&get_neutral_pixel_format(),SDL_SWSURFACE);
if(result != NULL) {
SDL_SetAlpha(result,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
}
@ -66,21 +85,14 @@ SDL_Surface* make_neutral_surface(SDL_Surface* surf)
return result;
}
int sdl_add_ref(SDL_Surface* surface)
{
if(surface != NULL)
return surface->refcount++;
else
return 0;
}
SDL_Surface* create_optimized_surface(SDL_Surface* surface)
surface create_optimized_surface(surface surf)
{
if(surface == NULL)
if(surf == NULL)
return NULL;
SDL_Surface* const result = display_format_alpha(surface);
if(result == surface) {
surface const result = display_format_alpha(surf);
if(result == surf) {
std::cerr << "resulting surface is the same as the source!!!\n";
}
@ -91,27 +103,26 @@ SDL_Surface* create_optimized_surface(SDL_Surface* surface)
return result;
}
SDL_Surface* scale_surface(SDL_Surface* surface, int w, int h)
surface scale_surface(surface surf, int w, int h)
{
if(surface == NULL)
if(surf == NULL)
return NULL;
if(w == surface->w && h == surface->h) {
sdl_add_ref(surface);
return surface;
if(w == surf->w && h == surf->h) {
return surf;
}
scoped_sdl_surface dst(SDL_CreateRGBSurface(SDL_SWSURFACE,w,h,32,0xFF0000,0xFF00,0xFF,0xFF000000));
scoped_sdl_surface src(make_neutral_surface(surface));
surface dst(SDL_CreateRGBSurface(SDL_SWSURFACE,w,h,32,0xFF0000,0xFF00,0xFF,0xFF000000));
surface src(make_neutral_surface(surf));
if(src == NULL || dst == NULL) {
std::cerr << "Could not create surface to scale onto\n";
return NULL;
}
const double xratio = static_cast<double>(surface->w)/
const double xratio = static_cast<double>(surf->w)/
static_cast<double>(w);
const double yratio = static_cast<double>(surface->h)/
const double yratio = static_cast<double>(surf->h)/
static_cast<double>(h);
{
@ -136,27 +147,26 @@ SDL_Surface* scale_surface(SDL_Surface* surface, int w, int h)
return create_optimized_surface(dst);
}
SDL_Surface* scale_surface_blended(SDL_Surface* surface, int w, int h)
surface scale_surface_blended(surface surf, int w, int h)
{
if(surface == NULL)
if(surf== NULL)
return NULL;
if(w == surface->w && h == surface->h) {
sdl_add_ref(surface);
return surface;
if(w == surf->w && h == surf->h) {
return surf;
}
scoped_sdl_surface dst(SDL_CreateRGBSurface(SDL_SWSURFACE,w,h,32,0xFF0000,0xFF00,0xFF,0xFF000000));
scoped_sdl_surface src(make_neutral_surface(surface));
surface dst(SDL_CreateRGBSurface(SDL_SWSURFACE,w,h,32,0xFF0000,0xFF00,0xFF,0xFF000000));
surface src(make_neutral_surface(surf));
if(src == NULL || dst == NULL) {
std::cerr << "Could not create surface to scale onto\n";
return NULL;
}
const double xratio = static_cast<double>(surface->w)/
const double xratio = static_cast<double>(surf->w)/
static_cast<double>(w);
const double yratio = static_cast<double>(surface->h)/
const double yratio = static_cast<double>(surf->h)/
static_cast<double>(h);
{
@ -213,59 +223,59 @@ SDL_Surface* scale_surface_blended(SDL_Surface* surface, int w, int h)
return create_optimized_surface(dst);
}
SDL_Surface* adjust_surface_colour(SDL_Surface* surface, int r, int g, int b)
surface adjust_surface_colour(surface surf, int r, int g, int b)
{
if(r == 0 && g == 0 && b == 0 || surface == NULL)
return create_optimized_surface(surface);
if(r == 0 && g == 0 && b == 0 || surf == NULL)
return create_optimized_surface(surf);
scoped_sdl_surface surf(make_neutral_surface(surface));
surface nsurf(make_neutral_surface(surf));
if(surf == NULL) {
if(nsurf == NULL) {
std::cerr << "failed to make neutral surface\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
Uint32* beg = lock.pixels();
Uint32* end = beg + surf->w*surf->h;
Uint32* end = beg + nsurf->w*surf->h;
while(beg != end) {
Uint8 red, green, blue, alpha;
SDL_GetRGBA(*beg,surf->format,&red,&green,&blue,&alpha);
SDL_GetRGBA(*beg,nsurf->format,&red,&green,&blue,&alpha);
red = maximum<int>(8,minimum<int>(255,int(red)+r));
green = maximum<int>(0,minimum<int>(255,int(green)+g));
blue = maximum<int>(0,minimum<int>(255,int(blue)+b));
*beg = SDL_MapRGBA(surf->format,red,green,blue,alpha);
*beg = SDL_MapRGBA(nsurf->format,red,green,blue,alpha);
++beg;
}
}
return create_optimized_surface(surf);
return create_optimized_surface(nsurf);
}
SDL_Surface* greyscale_image(SDL_Surface* surface)
surface greyscale_image(surface surf)
{
if(surface == NULL)
if(surf == NULL)
return NULL;
scoped_sdl_surface surf(make_neutral_surface(surface));
if(surf == NULL) {
surface nsurf(make_neutral_surface(surf));
if(nsurf == NULL) {
std::cerr << "failed to make neutral surface\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
Uint32* beg = lock.pixels();
Uint32* end = beg + surf->w*surf->h;
Uint32* end = beg + nsurf->w*surf->h;
while(beg != end) {
Uint8 red, green, blue, alpha;
SDL_GetRGBA(*beg,surf->format,&red,&green,&blue,&alpha);
SDL_GetRGBA(*beg,nsurf->format,&red,&green,&blue,&alpha);
//const Uint8 avg = (red+green+blue)/3;
@ -278,137 +288,137 @@ SDL_Surface* greyscale_image(SDL_Surface* surface)
29*(Uint16)blue) / 256);
*beg = SDL_MapRGBA(surf->format,avg,avg,avg,alpha);
*beg = SDL_MapRGBA(nsurf->format,avg,avg,avg,alpha);
++beg;
}
}
return create_optimized_surface(surf);
return create_optimized_surface(nsurf);
}
SDL_Surface* brighten_image(SDL_Surface* surface, double amount)
surface brighten_image(surface surf, double amount)
{
if(surface == NULL) {
if(surf == NULL) {
return NULL;
}
scoped_sdl_surface surf(make_neutral_surface(surface));
surface nsurf(make_neutral_surface(surf));
if(surf == NULL) {
if(nsurf == NULL) {
std::cerr << "could not make neutral surface...\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
Uint32* beg = lock.pixels();
Uint32* end = beg + surf->w*surf->h;
Uint32* end = beg + nsurf->w*surf->h;
while(beg != end) {
Uint8 red, green, blue, alpha;
SDL_GetRGBA(*beg,surf->format,&red,&green,&blue,&alpha);
SDL_GetRGBA(*beg,nsurf->format,&red,&green,&blue,&alpha);
red = Uint8(minimum<double>(maximum<double>(double(red) * amount,0.0),255.0));
green = Uint8(minimum<double>(maximum<double>(double(green) * amount,0.0),255.0));
blue = Uint8(minimum<double>(maximum<double>(double(blue) * amount,0.0),255.0));
*beg = SDL_MapRGBA(surf->format,red,green,blue,alpha);
*beg = SDL_MapRGBA(nsurf->format,red,green,blue,alpha);
++beg;
}
}
return create_optimized_surface(surf);
return create_optimized_surface(nsurf);
}
SDL_Surface* adjust_surface_alpha(SDL_Surface* surface, double amount)
surface adjust_surface_alpha(surface surf, double amount)
{
if(surface == NULL) {
if(surf== NULL) {
return NULL;
}
scoped_sdl_surface surf(make_neutral_surface(surface));
surface nsurf(make_neutral_surface(surf));
if(surf == NULL) {
if(nsurf == NULL) {
std::cerr << "could not make neutral surface...\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
Uint32* beg = lock.pixels();
Uint32* end = beg + surf->w*surf->h;
Uint32* end = beg + nsurf->w*surf->h;
while(beg != end) {
Uint8 red, green, blue, alpha;
SDL_GetRGBA(*beg,surf->format,&red,&green,&blue,&alpha);
SDL_GetRGBA(*beg,nsurf->format,&red,&green,&blue,&alpha);
alpha = Uint8(minimum<double>(maximum<double>(double(alpha) * amount,0.0),255.0));
*beg = SDL_MapRGBA(surf->format,red,green,blue,alpha);
*beg = SDL_MapRGBA(nsurf->format,red,green,blue,alpha);
++beg;
}
}
return create_optimized_surface(surf);
return create_optimized_surface(nsurf);
}
SDL_Surface* adjust_surface_alpha_add(SDL_Surface* surface, int amount)
surface adjust_surface_alpha_add(surface surf, int amount)
{
if(surface == NULL) {
if(surf== NULL) {
return NULL;
}
scoped_sdl_surface surf(make_neutral_surface(surface));
surface nsurf(make_neutral_surface(surf));
if(surf == NULL) {
if(nsurf == NULL) {
std::cerr << "could not make neutral surface...\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
Uint32* beg = lock.pixels();
Uint32* end = beg + surf->w*surf->h;
Uint32* end = beg + nsurf->w*surf->h;
while(beg != end) {
Uint8 red, green, blue, alpha;
SDL_GetRGBA(*beg,surf->format,&red,&green,&blue,&alpha);
SDL_GetRGBA(*beg,nsurf->format,&red,&green,&blue,&alpha);
alpha = Uint8(maximum<int>(0,minimum<int>(255,int(alpha) + amount)));
*beg = SDL_MapRGBA(surf->format,red,green,blue,alpha);
*beg = SDL_MapRGBA(nsurf->format,red,green,blue,alpha);
++beg;
}
}
return create_optimized_surface(surf);
return create_optimized_surface(nsurf);
}
// Applies a mask on a surface
SDL_Surface* mask_surface(SDL_Surface* surface, SDL_Surface* mask)
surface mask_surface(surface surf, surface mask)
{
if(surface == NULL) {
if(surf == NULL) {
return NULL;
}
SDL_Surface* surf = make_neutral_surface(surface);
scoped_sdl_surface nmask(make_neutral_surface(mask));
surface nsurf = make_neutral_surface(surf);
surface nmask(make_neutral_surface(mask));
if(surf == NULL || nmask == NULL) {
if(nsurf == NULL || nmask == NULL) {
std::cerr << "could not make neutral surface...\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
surface_lock mlock(nmask);
Uint32* beg = lock.pixels();
Uint32* end = beg + surf->w*surf->h;
Uint32* end = beg + nsurf->w*surf->h;
Uint32* mbeg = mlock.pixels();
Uint32* mend = mbeg + nmask->w*nmask->h;
@ -416,42 +426,45 @@ SDL_Surface* mask_surface(SDL_Surface* surface, SDL_Surface* mask)
Uint8 red, green, blue, alpha;
Uint8 mred, mgreen, mblue, malpha;
SDL_GetRGBA(*beg,surf->format,&red,&green,&blue,&alpha);
SDL_GetRGBA(*beg,nsurf->format,&red,&green,&blue,&alpha);
SDL_GetRGBA(*mbeg,nmask->format,&mred,&mgreen,&mblue,&malpha);
alpha = Uint8(minimum<int>(malpha, alpha));
*beg = SDL_MapRGBA(surf->format,red,green,blue,alpha);
*beg = SDL_MapRGBA(nsurf->format,red,green,blue,alpha);
++beg;
++mbeg;
}
}
return surf;
//return create_optimized_surface(surf);
return nsurf;
//return create_optimized_surface(nsurf);
}
// Cuts a rectangle from a surface.
SDL_Surface* cut_surface(SDL_Surface *surface, const SDL_Rect& r)
surface cut_surface(surface surf, const SDL_Rect& r)
{
SDL_Surface* res = create_compatible_surface(surface, r.w, r.h);
surface res = create_compatible_surface(surf, r.w, r.h);
size_t sbpp = surface->format->BytesPerPixel;
size_t spitch = surface->pitch;
size_t sbpp = surf->format->BytesPerPixel;
size_t spitch = surf->pitch;
size_t rbpp = res->format->BytesPerPixel;
size_t rpitch = res->pitch;
surface_lock slock(surface);
surface_lock slock(surf);
surface_lock rlock(res);
Uint8* src = reinterpret_cast<Uint8 *>(slock.pixels());
Uint8* dest = reinterpret_cast<Uint8 *>(rlock.pixels());
for(int y = 0; y < r.h && (r.y + y) < surface->h; ++y) {
if(r.x >= surf->w)
return res;
for(int y = 0; y < r.h && (r.y + y) < surf->h; ++y) {
Uint8* line_src = src + (r.y + y) * spitch + r.x * sbpp;
Uint8* line_dest = dest + y * rpitch;
size_t size = r.w + r.x <= surface->w ? r.w : surface->w - r.x;
size_t size = r.w + r.x <= surf->w ? r.w : surf->w - r.x;
assert(rpitch >= r.w * rbpp);
memcpy(line_dest, line_src, size * rbpp);
@ -460,26 +473,26 @@ SDL_Surface* cut_surface(SDL_Surface *surface, const SDL_Rect& r)
return res;
}
SDL_Surface* blend_surface(SDL_Surface* surface, double amount, Uint32 colour)
surface blend_surface(surface surf, double amount, Uint32 colour)
{
if(surface == NULL) {
if(surf== NULL) {
return NULL;
}
scoped_sdl_surface surf(make_neutral_surface(surface));
surface nsurf(make_neutral_surface(surf));
if(surf == NULL) {
if(nsurf == NULL) {
std::cerr << "could not make neutral surface...\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
Uint32* beg = lock.pixels();
Uint32* end = beg + surf->w*surf->h;
Uint32* end = beg + nsurf->w*surf->h;
Uint8 red2, green2, blue2, alpha2;
SDL_GetRGBA(colour,surf->format,&red2,&green2,&blue2,&alpha2);
SDL_GetRGBA(colour,nsurf->format,&red2,&green2,&blue2,&alpha2);
red2 = Uint8(red2*amount);
green2 = Uint8(green2*amount);
@ -489,80 +502,80 @@ SDL_Surface* blend_surface(SDL_Surface* surface, double amount, Uint32 colour)
while(beg != end) {
Uint8 red, green, blue, alpha;
SDL_GetRGBA(*beg,surf->format,&red,&green,&blue,&alpha);
SDL_GetRGBA(*beg,nsurf->format,&red,&green,&blue,&alpha);
red = Uint8(red*amount) + red2;
green = Uint8(green*amount) + green2;
blue = Uint8(blue*amount) + blue2;
*beg = SDL_MapRGBA(surf->format,red,green,blue,alpha);
*beg = SDL_MapRGBA(nsurf->format,red,green,blue,alpha);
++beg;
}
}
return create_optimized_surface(surf);
return create_optimized_surface(nsurf);
}
SDL_Surface* flip_surface(SDL_Surface* surface)
surface flip_surface(surface surf)
{
if(surface == NULL) {
if(surf == NULL) {
return NULL;
}
scoped_sdl_surface surf(make_neutral_surface(surface));
surface nsurf(make_neutral_surface(surf));
if(surf == NULL) {
if(nsurf == NULL) {
std::cerr << "could not make neutral surface...\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
Uint32* const pixels = lock.pixels();
for(size_t y = 0; y != surf->h; ++y) {
for(size_t x = 0; x != surf->w/2; ++x) {
const size_t index1 = y*surf->w + x;
const size_t index2 = (y+1)*surf->w - x - 1;
for(size_t y = 0; y != nsurf->h; ++y) {
for(size_t x = 0; x != nsurf->w/2; ++x) {
const size_t index1 = y*nsurf->w + x;
const size_t index2 = (y+1)*nsurf->w - x - 1;
std::swap(pixels[index1],pixels[index2]);
}
}
}
return create_optimized_surface(surf);
return create_optimized_surface(nsurf);
}
SDL_Surface* flop_surface(SDL_Surface* surface)
surface flop_surface(surface surf)
{
if(surface == NULL) {
if(surf == NULL) {
return NULL;
}
scoped_sdl_surface surf(make_neutral_surface(surface));
surface nsurf(make_neutral_surface(surf));
if(surf == NULL) {
if(nsurf == NULL) {
std::cerr << "could not make neutral surface...\n";
return NULL;
}
{
surface_lock lock(surf);
surface_lock lock(nsurf);
Uint32* const pixels = lock.pixels();
for(size_t x = 0; x != surf->w; ++x) {
for(size_t y = 0; y != surf->h/2; ++y) {
const size_t index1 = y*surf->w + x;
const size_t index2 = (surf->h-y-1)*surf->w + x;
for(size_t x = 0; x != nsurf->w; ++x) {
for(size_t y = 0; y != nsurf->h/2; ++y) {
const size_t index1 = y*nsurf->w + x;
const size_t index2 = (nsurf->h-y-1)*surf->w + x;
std::swap(pixels[index1],pixels[index2]);
}
}
}
return create_optimized_surface(surf);
return create_optimized_surface(nsurf);
}
SDL_Surface* create_compatible_surface(SDL_Surface* surf, int width, int height)
surface create_compatible_surface(surface surf, int width, int height)
{
if(surf == NULL)
return NULL;
@ -577,7 +590,7 @@ SDL_Surface* create_compatible_surface(SDL_Surface* surf, int width, int height)
surf->format->Rmask,surf->format->Gmask,surf->format->Bmask,surf->format->Amask);
}
void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, SDL_Surface* target)
void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, surface target)
{
if(alpha == SDL_ALPHA_OPAQUE) {
SDL_FillRect(target,&rect,colour);
@ -586,7 +599,7 @@ void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, SDL_Surface* ta
return;
}
scoped_sdl_surface tmp(create_compatible_surface(target,rect.w,rect.h));
surface tmp(create_compatible_surface(target,rect.w,rect.h));
if(tmp == NULL) {
return;
}
@ -597,7 +610,7 @@ void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, SDL_Surface* ta
SDL_BlitSurface(tmp,NULL,target,&rect);
}
SDL_Surface* get_surface_portion(SDL_Surface* src, SDL_Rect& area)
surface get_surface_portion(surface src, SDL_Rect& area)
{
if(area.x >= src->w || area.y >= src->h) {
std::cerr << "illegal surface portion...\n";
@ -612,7 +625,7 @@ SDL_Surface* get_surface_portion(SDL_Surface* src, SDL_Rect& area)
area.h = src->h - area.y;
}
SDL_Surface* const dst = create_compatible_surface(src,area.w,area.h);
surface const dst = create_compatible_surface(src,area.w,area.h);
if(dst == NULL) {
std::cerr << "Could not create a new surface in get_surface_portion()\n";
return NULL;
@ -643,24 +656,24 @@ private:
}
SDL_Rect get_non_transperant_portion(SDL_Surface* surface)
SDL_Rect get_non_transperant_portion(surface surf)
{
SDL_Rect res = {0,0,0,0};
const scoped_sdl_surface surf(make_neutral_surface(surface));
if(surf == NULL) {
const surface nsurf(make_neutral_surface(surf));
if(nsurf == NULL) {
std::cerr << "failed to make neutral surface\n";
return res;
}
const not_alpha calc(*(surf->format));
const not_alpha calc(*(nsurf->format));
surface_lock lock(surf);
surface_lock lock(nsurf);
const Uint32* const pixels = lock.pixels();
size_t n;
for(n = 0; n != surf->h; ++n) {
const Uint32* const start_row = pixels + n*surf->w;
const Uint32* const end_row = start_row + surf->w;
for(n = 0; n != nsurf->h; ++n) {
const Uint32* const start_row = pixels + n*nsurf->w;
const Uint32* const end_row = start_row + nsurf->w;
if(std::find_if(start_row,end_row,calc) != end_row)
break;
@ -668,9 +681,9 @@ SDL_Rect get_non_transperant_portion(SDL_Surface* surface)
res.y = n;
for(n = 0; n != surf->h-res.y; ++n) {
const Uint32* const start_row = pixels + (surf->h-n-1)*surf->w;
const Uint32* const end_row = start_row + surf->w;
for(n = 0; n != nsurf->h-res.y; ++n) {
const Uint32* const start_row = pixels + (nsurf->h-n-1)*surf->w;
const Uint32* const end_row = start_row + nsurf->w;
if(std::find_if(start_row,end_row,calc) != end_row)
break;
@ -678,35 +691,35 @@ SDL_Rect get_non_transperant_portion(SDL_Surface* surface)
//the height is the height of the surface, minus the distance from the top and the
//distance from the bottom
res.h = surf->h - res.y - n;
res.h = nsurf->h - res.y - n;
for(n = 0; n != surf->w; ++n) {
for(n = 0; n != nsurf->w; ++n) {
size_t y;
for(y = 0; y != surf->h; ++y) {
const Uint32 pixel = pixels[y*surf->w + n];
for(y = 0; y != nsurf->h; ++y) {
const Uint32 pixel = pixels[y*nsurf->w + n];
if(calc(pixel))
break;
}
if(y != surf->h)
if(y != nsurf->h)
break;
}
res.x = n;
for(n = 0; n != surf->w-res.x; ++n) {
for(n = 0; n != nsurf->w-res.x; ++n) {
size_t y;
for(y = 0; y != surf->h; ++y) {
const Uint32 pixel = pixels[y*surf->w + surf->w - n - 1];
for(y = 0; y != nsurf->h; ++y) {
const Uint32 pixel = pixels[y*nsurf->w + surf->w - n - 1];
if(calc(pixel))
break;
}
if(y != surf->h)
if(y != nsurf->h)
break;
}
res.w = surf->w - res.x - n;
res.w = nsurf->w - res.x - n;
return res;
}
@ -759,4 +772,4 @@ void surface_restorer::update()
void surface_restorer::cancel()
{
surface_.assign(NULL);
}
}

View file

@ -38,34 +38,71 @@ bool point_in_rect(int x, int y, const SDL_Rect& rect);
bool rects_overlap(const SDL_Rect& rect1, const SDL_Rect& rect2);
struct free_sdl_surface {
void operator()(SDL_Surface* surface) const { SDL_FreeSurface(surface); }
void operator()(SDL_Surface* surface) const;
};
int sdl_add_ref(SDL_Surface* surface);
typedef util::scoped_resource<SDL_Surface*,free_sdl_surface> scoped_sdl_surface;
struct surface
{
private:
int sdl_add_ref(SDL_Surface* surf);
typedef util::scoped_resource<SDL_Surface*,free_sdl_surface> scoped_sdl_surface;
public:
surface() : surface_(NULL)
{}
SDL_Surface* make_neutral_surface(SDL_Surface* surf);
SDL_Surface* create_optimized_surface(SDL_Surface* surface);
SDL_Surface* scale_surface(SDL_Surface* surface, int w, int h);
SDL_Surface* scale_surface_blended(SDL_Surface* surface, int w, int h);
SDL_Surface* adjust_surface_colour(SDL_Surface* surface, int r, int g, int b);
SDL_Surface* greyscale_image(SDL_Surface* surface);
SDL_Surface* brighten_image(SDL_Surface* surface, double amount);
SDL_Surface* get_surface_portion(SDL_Surface* src, SDL_Rect& rect);
SDL_Surface* adjust_surface_alpha(SDL_Surface* surface, double amount);
SDL_Surface* adjust_surface_alpha_add(SDL_Surface* surface, int amount);
SDL_Surface* mask_surface(SDL_Surface* surface, SDL_Surface* mask);
SDL_Surface* cut_surface(SDL_Surface* surface, const SDL_Rect& r);
SDL_Surface* blend_surface(SDL_Surface* surface, double amount, Uint32 colour);
SDL_Surface* flip_surface(SDL_Surface* surface);
SDL_Surface* flop_surface(SDL_Surface* surface);
surface(SDL_Surface* surf);
SDL_Surface* create_compatible_surface(SDL_Surface* surf, int width=-1, int height=-1);
surface(const surface& o) : surface_(o.surface_.get())
{
sdl_add_ref(get());
}
void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, SDL_Surface* target);
surface& operator=(const surface& o)
{
surface_.assign(o.surface_.get());
sdl_add_ref(get());
return *this;
}
SDL_Rect get_non_transperant_portion(SDL_Surface* surf);
operator SDL_Surface*() const { return surface_; }
SDL_Surface* get() const { return surface_.get(); }
SDL_Surface* operator->() const { return surface_.get(); }
void assign(const surface& o)
{
operator=(o);
}
void assign(SDL_Surface* surf) { surface_.assign(surf); }
private:
scoped_sdl_surface surface_;
};
surface make_neutral_surface(surface surf);
surface create_optimized_surface(surface surface);
surface scale_surface(surface surface, int w, int h);
surface scale_surface_blended(surface surface, int w, int h);
surface adjust_surface_colour(surface surface, int r, int g, int b);
surface greyscale_image(surface surface);
surface brighten_image(surface surface, double amount);
surface get_surface_portion(surface src, SDL_Rect& rect);
surface adjust_surface_alpha(surface surface, double amount);
surface adjust_surface_alpha_add(surface surface, int amount);
surface mask_surface(surface surface, surface mask);
surface cut_surface(surface surface, const SDL_Rect& r);
surface blend_surface(surface surface, double amount, Uint32 colour);
surface flip_surface(surface surface);
surface flop_surface(surface surface);
surface create_compatible_surface(surface surf, int width=-1, int height=-1);
void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, surface target);
SDL_Rect get_non_transperant_portion(surface surf);
bool operator==(const SDL_Rect& a, const SDL_Rect& b);
bool operator!=(const SDL_Rect& a, const SDL_Rect& b);
@ -122,7 +159,7 @@ struct pixel_data
struct surface_lock
{
surface_lock(SDL_Surface* surface) : surface_(surface), locked_(false)
surface_lock(surface surface) : surface_(surface), locked_(false)
{
if(SDL_MUSTLOCK(surface_)) {
const int res = SDL_LockSurface(surface_);
@ -141,44 +178,10 @@ struct surface_lock
Uint32* pixels() { return reinterpret_cast<Uint32*>(surface_->pixels); }
private:
SDL_Surface* const surface_;
surface const surface_;
bool locked_;
};
struct shared_sdl_surface
{
explicit shared_sdl_surface(SDL_Surface* surf) : surface_(surf)
{}
shared_sdl_surface(const shared_sdl_surface& o) : surface_(o.surface_.get())
{
sdl_add_ref(get());
}
shared_sdl_surface& operator=(const shared_sdl_surface& o)
{
surface_.assign(o.surface_.get());
sdl_add_ref(get());
return *this;
}
operator SDL_Surface*() const { return surface_; }
SDL_Surface* get() const { return surface_.get(); }
SDL_Surface* operator->() const { return surface_.get(); }
void assign(const shared_sdl_surface& o)
{
operator=(o);
}
void assign(SDL_Surface* surf) { surface_.assign(surf); }
private:
scoped_sdl_surface surface_;
};
struct surface_restorer
{
surface_restorer();
@ -194,21 +197,21 @@ struct surface_restorer
private:
class CVideo* target_;
SDL_Rect rect_;
shared_sdl_surface surface_;
surface surface_;
};
struct clip_rect_setter
{
clip_rect_setter(SDL_Surface* surf, SDL_Rect& r) : surface(surf)
clip_rect_setter(surface surf, SDL_Rect& r) : surface_(surf)
{
SDL_GetClipRect(surface,&rect);
SDL_SetClipRect(surface,&r);
SDL_GetClipRect(surface_,&rect);
SDL_SetClipRect(surface_,&r);
}
~clip_rect_setter() { SDL_SetClipRect(surface,&rect); }
~clip_rect_setter() { SDL_SetClipRect(surface_,&rect); }
private:
SDL_Surface* surface;
surface surface_;
SDL_Rect rect;
};

View file

@ -62,10 +62,10 @@ void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::str
dialog_style = &default_style;
}
const scoped_sdl_surface top(image::get_image("misc/" + *dialog_style + "-border-top.png",image::UNSCALED));
const scoped_sdl_surface bot(image::get_image("misc/" + *dialog_style + "-border-bottom.png",image::UNSCALED));
const scoped_sdl_surface left(image::get_image("misc/" + *dialog_style + "-border-left.png",image::UNSCALED));
const scoped_sdl_surface right(image::get_image("misc/" + *dialog_style + "-border-right.png",image::UNSCALED));
const surface top(image::get_image("misc/" + *dialog_style + "-border-top.png",image::UNSCALED));
const surface bot(image::get_image("misc/" + *dialog_style + "-border-bottom.png",image::UNSCALED));
const surface left(image::get_image("misc/" + *dialog_style + "-border-left.png",image::UNSCALED));
const surface right(image::get_image("misc/" + *dialog_style + "-border-right.png",image::UNSCALED));
const bool have_border = top != NULL && bot != NULL && left != NULL && right != NULL;
@ -83,36 +83,36 @@ void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::str
return;
}
scoped_sdl_surface top_image(scale_surface(top,w,top->h));
surface top_image(scale_surface(top,w,top->h));
if(top_image.get() != NULL) {
disp.blit_surface(x,y-top->h,top_image.get());
if(top_image != NULL) {
disp.blit_surface(x,y-top->h,top_image);
}
scoped_sdl_surface bot_image(scale_surface(bot,w,bot->h));
surface bot_image(scale_surface(bot,w,bot->h));
if(bot_image.get() != NULL) {
disp.blit_surface(x,y+h,bot_image.get());
if(bot_image != NULL) {
disp.blit_surface(x,y+h,bot_image);
}
scoped_sdl_surface left_image(scale_surface(left,left->w,h));
surface left_image(scale_surface(left,left->w,h));
if(left_image.get() != NULL) {
disp.blit_surface(x-left->w,y,left_image.get());
if(left_image != NULL) {
disp.blit_surface(x-left->w,y,left_image);
}
scoped_sdl_surface right_image(scale_surface(right,right->w,h));
surface right_image(scale_surface(right,right->w,h));
if(right_image.get() != NULL) {
disp.blit_surface(x+w,y,right_image.get());
if(right_image != NULL) {
disp.blit_surface(x+w,y,right_image);
}
update_rect(x-left->w,y-top->h,w+left->w+right->w,h+top->h+bot->h);
const scoped_sdl_surface top_left(image::get_image("misc/" + *dialog_style + "-border-topleft.png",image::UNSCALED));
const scoped_sdl_surface bot_left(image::get_image("misc/" + *dialog_style + "-border-botleft.png",image::UNSCALED));
const scoped_sdl_surface top_right(image::get_image("misc/" + *dialog_style + "-border-topright.png",image::UNSCALED));
const scoped_sdl_surface bot_right(image::get_image("misc/" + *dialog_style + "-border-botright.png",image::UNSCALED));
const surface top_left(image::get_image("misc/" + *dialog_style + "-border-topleft.png",image::UNSCALED));
const surface bot_left(image::get_image("misc/" + *dialog_style + "-border-botleft.png",image::UNSCALED));
const surface top_right(image::get_image("misc/" + *dialog_style + "-border-topright.png",image::UNSCALED));
const surface bot_right(image::get_image("misc/" + *dialog_style + "-border-botright.png",image::UNSCALED));
if(top_left == NULL || bot_left == NULL || top_right == NULL || bot_right == NULL) {
return;
}
@ -127,7 +127,7 @@ void draw_dialog_background(int x, int y, int w, int h, display& disp, const std
{
const std::string menu_background = "misc/" + style + "-background.png";
const scoped_sdl_surface bg(image::get_image(menu_background,image::UNSCALED));
const surface bg(image::get_image(menu_background,image::UNSCALED));
if(bg == NULL) {
std::cerr << "could not find dialog background '" << style << "'\n";
return;
@ -245,7 +245,7 @@ void draw_dialog(int x, int y, int w, int h, display& disp, const std::string& t
}
}
void draw_rectangle(int x, int y, int w, int h, Uint32 colour,SDL_Surface* target)
void draw_rectangle(int x, int y, int w, int h, Uint32 colour,surface target)
{
if(x < 0 || y < 0 || x+w >= target->w || y+h >= target->h) {
std::cerr << "Rectangle has illegal co-ordinates: " << x << "," << y
@ -266,7 +266,7 @@ void draw_rectangle(int x, int y, int w, int h, Uint32 colour,SDL_Surface* targe
void draw_solid_tinted_rectangle(int x, int y, int w, int h,
int r, int g, int b,
double alpha, SDL_Surface* target)
double alpha, surface target)
{
if(x < 0 || y < 0 || x+w >= target->w || y+h >= target->h) {
std::cerr << "Rectangle has illegal co-ordinates: " << x << "," << y
@ -355,7 +355,7 @@ private:
}
int show_dialog(display& disp, SDL_Surface* image,
int show_dialog(display& disp, surface image,
const std::string& caption, const std::string& msg,
DIALOG_TYPE type,
const std::vector<std::string>* menu_items_ptr,
@ -389,7 +389,7 @@ int show_dialog(display& disp, SDL_Surface* image,
static const int caption_font_size = 18;
CVideo& screen = disp.video();
SDL_Surface* const scr = screen.getSurface();
surface const scr = screen.getSurface();
SDL_Rect clipRect = disp.screen_area();

View file

@ -51,11 +51,11 @@ void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::str
void draw_dialog_background(int x, int y, int w, int h, display& disp, const std::string& dialog_style);
void draw_rectangle(int x, int y, int w, int h, Uint32 colour, SDL_Surface* tg);
void draw_rectangle(int x, int y, int w, int h, Uint32 colour, surface tg);
void draw_solid_tinted_rectangle(int x, int y, int w, int h,
int r, int g, int b,
double alpha, SDL_Surface* target);
double alpha, surface target);
//given the location of a dialog, will draw its title.
//Returns the area the title takes up
@ -131,7 +131,7 @@ size_t text_to_lines(std::string& text, size_t max_length);
//if a menu is given, then returns -1 if the dialog was cancelled, and the
//index of the selection otherwise. If no menu is given, returns the index
//of the button that was pressed
int show_dialog(display& screen, SDL_Surface* image,
int show_dialog(display& screen, surface image,
const std::string& caption, const std::string& message,
DIALOG_TYPE type=MESSAGE,
const std::vector<std::string>* menu_items=NULL,

View file

@ -794,4 +794,4 @@ int team::get_side_colour_index(int side)
}
return side;
}
}

View file

@ -19,13 +19,13 @@ namespace {
void fade_logo(display& screen, int xpos, int ypos)
{
const scoped_sdl_surface logo(image::get_image(game_config::game_logo,image::UNSCALED));
const surface logo(image::get_image(game_config::game_logo,image::UNSCALED));
if(logo == NULL) {
std::cerr << "Could not find game logo\n";
return;
}
SDL_Surface* const fb = screen.video().getSurface();
surface const fb = screen.video().getSurface();
if(fb == NULL || xpos < 0 || ypos < 0 || xpos + logo->w > fb->w || ypos + logo->h > fb->h) {
return;
@ -118,8 +118,8 @@ TITLE_RESULT show_title(display& screen, int* ntip)
const font::floating_label_context label_manager;
const scoped_sdl_surface title_surface_unscaled(image::get_image(game_config::game_title,image::UNSCALED));
const scoped_sdl_surface title_surface(scale_surface(title_surface_unscaled,screen.x(),screen.y()));
const surface title_surface_unscaled(image::get_image(game_config::game_title,image::UNSCALED));
const surface title_surface(scale_surface(title_surface_unscaled,screen.x(),screen.y()));
if(title_surface == NULL) {
std::cerr << "Could not find title image\n";

View file

@ -38,7 +38,7 @@ std::vector<tooltip>::const_iterator current_tooltip = tips.end();
int tooltip_handle = 0;
SDL_Rect current_rect;
SDL_Surface* current_background = NULL;
surface current_background = NULL;
SDL_Rect get_text_size(const std::string& msg)
{
@ -155,7 +155,7 @@ void process(int mousex, int mousey, bool lbutton)
SDL_Rect draw_text(display* gui, const SDL_Rect& area, int size,
const SDL_Color& colour, const std::string& text,
int x, int y, SDL_Surface* bg)
int x, int y, surface bg)
{
return font::draw_text(gui,area,size,colour,text,x,y,bg,true);
}

View file

@ -24,7 +24,7 @@ void process(int mousex, int mousey, bool lbutton);
//a tooltip
SDL_Rect draw_text(display* gui, const SDL_Rect& area, int size,
const SDL_Color& colour, const std::string& text,
int x, int y, SDL_Surface* bg=NULL);
int x, int y, surface bg=NULL);
}

View file

@ -808,7 +808,8 @@ const std::string& unit::image() const
const attack_type::RANGE range = (state_ == STATE_DEFENDING_LONG) ? attack_type::LONG_RANGE : attack_type::SHORT_RANGE;
const unit_animation* const anim = type_->defend_animation(getsHit_,range);
if(anim != NULL) {
const std::string* img = anim->get_frame(attackingMilliseconds_);
const unit_animation::frame& anim_frame = anim->get_current_frame();
const std::string* img = &anim_frame.image;
if(img != NULL) {
return *img;
}
@ -820,8 +821,8 @@ const std::string& unit::image() const
if(attackType_ == NULL)
return type_->image();
const std::string* const img =
attackType_->animation().get_frame(attackingMilliseconds_);
const unit_animation::frame& anim_frame = attackType_->animation().get_current_frame();
const std::string* const img = &anim_frame.image;
if(img == NULL)
return type_->image_fighting(attackType_->range());
@ -841,7 +842,9 @@ void unit::set_defending(bool newval, bool hits, int ms, attack_type::RANGE rang
{
state_ = newval ? (range == attack_type::LONG_RANGE ? STATE_DEFENDING_LONG :
STATE_DEFENDING_SHORT): STATE_NORMAL;
attackingMilliseconds_ = ms;
// attackingMilliseconds_ = ms;
const unit_animation* const anim = type_->defend_animation(getsHit_,range);
getsHit_ = hits;
}

View file

@ -47,11 +47,15 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
int skips = 0;
const std::string& halo = u.type().image_halo();
util::scoped_resource<int,halo::remover> halo_effect(0);
if(halo.empty() == false && !disp.fogged(b.x,b.y)) {
halo_effect.assign(halo::add(0,0,halo));
}
for(int i = 0; i < nsteps; ++i) {
events::pump();
scoped_sdl_surface image(image::get_image(u.type().image_moving()));
surface image(image::get_image(u.type().image_moving()));
if(!face_left) {
image.assign(image::reverse_image(image));
}
@ -113,13 +117,12 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
const int xpos = static_cast<int>(xloc);
const int ypos = static_cast<int>(yloc) - height_adjust;
// disp.invalidate_animations();
disp.draw(false);
disp.draw_unit(xpos,ypos,image,false,1.0,0,submerge);
util::scoped_resource<int,halo::remover> halo_effect(0);
if(halo.empty() == false && !disp.fogged(b.x,b.y)) {
halo_effect.assign(halo::add(xpos+disp.hex_size()/2,ypos+disp.hex_size()/2,halo));
}
if(halo_effect != 0)
halo::set_location(halo_effect, xpos+disp.hex_size()/2, ypos+disp.hex_size()/2);
const int new_ticks = SDL_GetTicks();
const int wait_time = time_between_frames - (new_ticks - ticks);
@ -213,8 +216,8 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
//the missile frames are based around the time when the missile impacts.
//the 'real' frames are based around the time when the missile launches.
const int first_missile = minimum<int>(-100,attack.animation().get_first_frame(unit_animation::MISSILE_FRAME));
const int last_missile = attack.animation().get_last_frame(unit_animation::MISSILE_FRAME);
const int first_missile = minimum<int>(-100,attack.animation().get_first_frame_time(unit_animation::MISSILE_FRAME));
const int last_missile = attack.animation().get_last_frame_time(unit_animation::MISSILE_FRAME);
const int real_last_missile = last_missile - first_missile;
const int missile_impact = -first_missile;
@ -230,9 +233,9 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
const int play_hit_sound_at = 0;
const bool hits = damage > 0;
const int begin_at = attack.animation().get_first_frame();
const int begin_at = attack.animation().get_first_frame_time(unit_animation::UNIT_FRAME);
const int end_at = maximum((damage+1)*time_resolution+missile_impact,
maximum(attack.animation().get_last_frame(),real_last_missile));
maximum(attack.animation().get_last_frame_time(),real_last_missile));
const double xsrc = disp.get_location_x(a);
const double ysrc = disp.get_location_y(a);
@ -260,14 +263,22 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
const std::string* unit_halo_image = NULL;
int missile_halo_x = -1, missile_halo_y = -1, unit_halo_x = -1, unit_halo_y = -1;
for(int i = begin_at; i < end_at; i += time_resolution*acceleration) {
unit_animation attack_anim = attack.animation();
attack_anim.start_animation(begin_at, unit_animation::UNIT_FRAME, acceleration);
attack_anim.start_animation(begin_at + first_missile, unit_animation::MISSILE_FRAME, acceleration);
attack_anim.update_current_frames();
int animation_time = attack_anim.get_animation_time();
while(animation_time < end_at) {
events::pump();
def->second.set_defending(true,hits,i - missile_impact,attack_type::LONG_RANGE);
def->second.set_defending(true,hits,animation_time - missile_impact,attack_type::LONG_RANGE);
//this is a while instead of an if, because there might be multiple
//sounds playing simultaneously or close together
while(!hide && sfx_it != sounds.end() && i >= sfx_it->time) {
while(!hide && sfx_it != sounds.end() && animation_time >= sfx_it->time) {
const std::string& sfx = hits ? sfx_it->on_hit : sfx_it->on_miss;
if(sfx.empty() == false) {
sound::play_sound(hits ? sfx_it->on_hit : sfx_it->on_miss);
@ -276,27 +287,35 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
++sfx_it;
}
if(!hide && hits && !played_hit_sound && i >= play_hit_sound_at) {
if(!hide && hits && !played_hit_sound && animation_time >= play_hit_sound_at) {
sound::play_sound(hit_sound);
played_hit_sound = true;
}
const std::string* new_halo = NULL;
int new_halo_x = 0, new_halo_y = 0;
const std::string* unit_image = attack.animation().get_frame(i,NULL,unit_animation::UNIT_FRAME,unit_animation::VERTICAL,&new_halo,&new_halo_x,&new_halo_y);
const unit_animation::frame& unit_frame = attack_anim.get_current_frame(unit_animation::UNIT_FRAME);
std::cerr << "Animation time :" << animation_time << ", image " << unit_frame.image << "\n";
int new_halo_x = unit_frame.halo_x;
int new_halo_y = unit_frame.halo_y;
const std::string* unit_image = &unit_frame.image;
if(att->second.facing_left() == false) {
new_halo_x *= -1;
}
if(unit_halo_image != new_halo || unit_halo_x != new_halo_x || unit_halo_y != new_halo_y) {
if(unit_halo_image != &unit_frame.halo ||
unit_halo_x != new_halo_x ||
unit_halo_y != new_halo_y) {
unit_halo_image = new_halo;
unit_halo_image = &unit_frame.halo;
unit_halo_x = new_halo_x;
unit_halo_y = new_halo_y;
if(unit_halo_image != NULL && !disp.fogged(a.x,a.y)) {
const int halo_xpos = int(disp.get_location_x(a)+disp.hex_size()/2.0 + unit_halo_x*disp.zoom());
const int halo_ypos = int(disp.get_location_y(a)+disp.hex_size()/2.0 + unit_halo_y*disp.zoom());
if(!unit_frame.halo.empty() && !disp.fogged(a.x,a.y)) {
const int halo_xpos = int(disp.get_location_x(a) +
disp.hex_size()/2.0 + unit_halo_x*disp.zoom());
const int halo_ypos = int(disp.get_location_y(a) +
disp.hex_size()/2.0 + unit_halo_y*disp.zoom());
unit_halo_effect.assign(halo::add(halo_xpos,halo_ypos,*unit_halo_image));
} else {
@ -304,16 +323,16 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
}
}
if(unit_image == NULL) {
if(unit_image->empty()) {
unit_image = &att->second.type().image_fighting(attack_type::LONG_RANGE);
}
if(!hide) {
const scoped_sdl_surface image((unit_image == NULL) ? NULL : image::get_image(*unit_image));
const surface image((unit_image == NULL) ? surface(NULL) : image::get_image(*unit_image));
disp.draw_tile(a.x,a.y,image);
}
if(damage > 0 && i >= missile_impact && shown_label == false) {
if(damage > 0 && animation_time >= missile_impact && shown_label == false) {
shown_label = true;
disp.float_label(b,lexical_cast<std::string>(damage),255,0,0);
}
@ -321,7 +340,8 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
Uint32 defensive_colour = 0;
double defensive_alpha = 1.0;
if(damage > 0 && i >= missile_impact) {
std::cerr << "Waiting for missile impact at " << missile_impact << "\n";
if(damage > 0 && animation_time >= missile_impact) {
if(def->second.gets_hit(minimum<int>(drain_speed,damage))) {
dead = true;
damage = 0;
@ -348,13 +368,14 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
disp.draw_tile(leader_loc.x,leader_loc.y);
}
if(i >= 0 && i < real_last_missile && !hide) {
const int missile_frame = i + first_missile;
if(animation_time >= 0 && animation_time < real_last_missile && !hide) {
const int missile_frame_time = animation_time + first_missile;
const std::string* new_halo = NULL;
int new_halo_x = 0, new_halo_y = 0;
const std::string* missile_image = attack.animation().get_frame(missile_frame,NULL,
unit_animation::MISSILE_FRAME,dir,&new_halo,&new_halo_x,&new_halo_y);
const unit_animation::frame& missile_frame = attack_anim.get_current_frame(unit_animation::MISSILE_FRAME);
std::cerr << "Missile: animation time :" << animation_time << ", image " << missile_frame.image << ", halo: " << missile_frame.halo << "\n";
new_halo_x = missile_frame.halo_x;
new_halo_y = missile_frame.halo_y;
if(att->second.facing_left() == false) {
new_halo_x *= -1;
@ -363,22 +384,29 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
new_halo_x = int(new_halo_x*disp.zoom());
new_halo_y = int(new_halo_y*disp.zoom());
const std::string *missile_image = NULL;
if(dir == unit_animation::VERTICAL) {
missile_image = &missile_frame.image;
} else {
missile_image = &missile_frame.image_diagonal;
}
static const std::string default_missile(game_config::missile_n_image);
static const std::string default_diag_missile(game_config::missile_ne_image);
if(missile_image == NULL) {
if(missile_image->empty()) {
if(dir == unit_animation::VERTICAL)
missile_image = &default_missile;
else
missile_image = &default_diag_missile;
}
scoped_sdl_surface img(image::get_image(*missile_image));
surface img(image::get_image(*missile_image));
if(hflip) {
img.assign(image::reverse_image(img));
}
double pos = double(missile_impact - i)/double(missile_impact);
double pos = double(missile_impact - animation_time)/double(missile_impact);
if(pos < 0.0) {
pos = 0.0;
}
@ -393,12 +421,14 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
const int halo_xpos = xpos+disp.hex_size()/2;
const int halo_ypos = ypos+disp.hex_size()/2;
if(missile_halo_image != new_halo || missile_halo_x != new_halo_x || missile_halo_y != new_halo_y) {
missile_halo_image = new_halo;
if(missile_halo_image != &missile_frame.halo || missile_halo_x != new_halo_x || missile_halo_y != new_halo_y) {
missile_halo_image = &missile_frame.halo;
missile_halo_x = new_halo_x;
missile_halo_y = new_halo_y;
if(missile_halo_image != NULL && !disp.fogged(b.x,b.y)) {
if(missile_halo_image != NULL &&
!missile_halo_image->empty() &&
!disp.fogged(b.x,b.y)) {
missile_halo_effect.assign(halo::add(halo_xpos,halo_ypos,*missile_halo_image));
} else {
missile_halo_effect.assign(0);
@ -413,6 +443,9 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
missile_halo_effect.assign(0);
}
//TODO: fix this
SDL_Delay(20);
#if 0
const int wait_time = ticks + time_resolution - SDL_GetTicks();
if(wait_time > 0 && !hide) {
SDL_Delay(wait_time);
@ -420,9 +453,12 @@ bool unit_attack_ranged(display& disp, unit_map& units, const gamemap& map,
//if we're not keeping up, then skip frames
i += minimum<int>(time_resolution*4,-wait_time);
}
#endif
ticks = SDL_GetTicks();
// ticks = SDL_GetTicks();
attack_anim.update_current_frames();
animation_time = attack_anim.get_animation_time();
disp.update_display();
}
@ -543,9 +579,9 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
leader->second.set_leading(true);
}
const int begin_at = minimum<int>(-200,attack.animation().get_first_frame());
const int begin_at = minimum<int>(-200,attack.animation().get_first_frame_time());
const int end_at = maximum<int>((damage+1)*time_resolution,
maximum<int>(200,attack.animation().get_last_frame()));
maximum<int>(200,attack.animation().get_last_frame_time()));
const double xsrc = disp.get_location_x(a);
const double ysrc = disp.get_location_y(a);
@ -579,14 +615,18 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
const std::string* halo_image = NULL;
int halo_x = -1, halo_y = -1;
for(int i = begin_at; i < end_at; i += time_resolution*acceleration) {
unit_animation attack_anim = attack.animation();
attack_anim.start_animation(begin_at, unit_animation::UNIT_FRAME, acceleration);
while(!attack_anim.animation_finished()) {
events::pump();
def->second.set_defending(true,hits,i,attack_type::SHORT_RANGE);
int animation_time = attack_anim.get_animation_time();
def->second.set_defending(true,hits,animation_time,attack_type::SHORT_RANGE);
//this is a while instead of an if, because there might be multiple
//sounds playing simultaneously or close together
while(!hide && sfx_it != sounds.end() && i >= sfx_it->time) {
while(!hide && sfx_it != sounds.end() && animation_time >= sfx_it->time) {
const std::string& sfx = hits ? sfx_it->on_hit : sfx_it->on_miss;
if(sfx.empty() == false) {
sound::play_sound(hits ? sfx_it->on_hit : sfx_it->on_miss);
@ -595,7 +635,7 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
++sfx_it;
}
if(!hide && hits && !played_hit_sound && i >= play_hit_sound_at) {
if(!hide && hits && !played_hit_sound && animation_time >= play_hit_sound_at) {
sound::play_sound(hit_sound);
played_hit_sound = true;
}
@ -607,12 +647,12 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
Uint32 defender_colour = 0;
double defender_alpha = 1.0;
if(damage > 0 && i >= 0 && shown_label == false) {
if(damage > 0 && animation_time >= 0 && shown_label == false) {
shown_label = true;
disp.float_label(b,lexical_cast<std::string>(damage),255,0,0);
}
if(damage > 0 && i >= 0) {
if(damage > 0 && animation_time >= 0) {
if(def->second.gets_hit(minimum<int>(drain_speed,damage))) {
dead = true;
damage = 0;
@ -633,12 +673,13 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
disp.draw_tile(leader_loc.x,leader_loc.y);
}
const std::string* new_halo_image = NULL;
int new_halo_x = 0, new_halo_y = 0;
int xoffset = 0;
const std::string* unit_image = attack.animation().get_frame(i,&xoffset,unit_animation::UNIT_FRAME,unit_animation::VERTICAL,
&new_halo_image,&new_halo_x,&new_halo_y);
const unit_animation::frame& unit_frame = attack_anim.get_current_frame(unit_animation::UNIT_FRAME);
int new_halo_x = unit_frame.halo_x;
int new_halo_y = unit_frame.halo_y;
const std::string* unit_image = &unit_frame.image;
if(!attacker.facing_left()) {
xoffset *= -1;
@ -649,27 +690,31 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
xoffset = int(double(xoffset)*disp.zoom());
if(unit_image == NULL) {
if(unit_image->empty()) {
unit_image = &attacker.image();
}
scoped_sdl_surface image((unit_image == NULL) ? NULL : image::get_image(*unit_image));
surface image((unit_image == NULL) ? surface(NULL) : image::get_image(*unit_image));
if(attacker.facing_left() == false) {
image.assign(image::reverse_image(image));
}
const double pos = double(i)/double(i < 0 ? begin_at : end_at);
const double pos = double(animation_time)/double(animation_time < 0 ? begin_at : end_at);
const int posx = int(pos*xsrc + (1.0-pos)*xdst) + xoffset;
const int posy = int(pos*ysrc + (1.0-pos)*ydst);
const int halo_xpos = posx+disp.hex_size()/2;
const int halo_ypos = posy+disp.hex_size()/2;
if(new_halo_image != halo_image || new_halo_x != halo_x || new_halo_y != halo_y) {
halo_image = new_halo_image;
if(&unit_frame.halo != halo_image ||
new_halo_x != halo_x ||
new_halo_y != halo_y) {
halo_image = &unit_frame.halo;
halo_x = new_halo_x;
halo_y = new_halo_y;
if(halo_image != NULL && (!disp.fogged(b.x,b.y) || !disp.fogged(a.x,a.y))) {
if(!unit_frame.halo.empty() &&
(!disp.fogged(b.x,b.y) || !disp.fogged(a.x,a.y))) {
halo_effect.assign(halo::add(halo_xpos,halo_ypos,*halo_image));
} else {
halo_effect.assign(0);
@ -694,6 +739,7 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
ticks = SDL_GetTicks();
attack_anim.update_current_frames();
disp.update_display();
}

View file

@ -28,38 +28,35 @@
#include <unistd.h>
#endif
unit_animation::unit_animation(const config& cfg)
unit_animation::frame::frame(const config& cfg)
{
xoffset = atoi(cfg["xoffset"].c_str());
image = cfg["image"];
image_diagonal = cfg["image_diagonal"];
halo = cfg["halo"];
halo_x = atoi(cfg["halo_x"].c_str());
halo_y = atoi(cfg["halo_y"].c_str());
}
unit_animation::unit_animation(const config& cfg)
{
config::const_child_itors range = cfg.child_range("frame");
for(; range.first != range.second; ++range.first){
const int beg = atoi((**range.first)["begin"].c_str());
const int end = atoi((**range.first)["end"].c_str());
const int xoff = atoi((**range.first)["xoffset"].c_str());
const std::string& img = (**range.first)["image"];
const std::string& halo = (**range.first)["halo"];
const int halo_x = atoi((**range.first)["halo_x"].c_str());
const int halo_y = atoi((**range.first)["halo_y"].c_str());
frames_[UNIT_FRAME].push_back(frame(beg,end,img,halo,xoff,halo_x,halo_y));
int last_end = INT_MIN;
for(; range.first != range.second; ++range.first) {
unit_frames_.add_frame(atoi((**range.first)["begin"].c_str()), frame(**range.first));
last_end = maximum<int>(atoi((**range.first)["end"].c_str()), last_end);
}
//unit_frames_.set_animation_end(last_end);
unit_frames_.add_frame(last_end);
last_end = INT_MIN;
range = cfg.child_range("missile_frame");
for(; range.first != range.second; ++range.first){
const int beg = atoi((**range.first)["begin"].c_str());
const int end = atoi((**range.first)["end"].c_str());
const int xoff = atoi((**range.first)["xoffset"].c_str());
const std::string& img = (**range.first)["image"];
const std::string& img_diag = (**range.first)["image_diagonal"];
const std::string& halo = (**range.first)["halo"];
const int halo_x = atoi((**range.first)["halo_x"].c_str());
const int halo_y = atoi((**range.first)["halo_y"].c_str());
if(img_diag.empty())
frames_[MISSILE_FRAME].push_back(frame(beg,end,img,halo,xoff,halo_x,halo_y));
else
frames_[MISSILE_FRAME].push_back(frame(beg,end,img,img_diag,halo,xoff,halo_x,halo_y));
for(; range.first != range.second; ++range.first) {
missile_frames_.add_frame(atoi((**range.first)["begin"].c_str()), frame(**range.first));
last_end = maximum<int>(atoi((**range.first)["end"].c_str()), last_end);
}
missile_frames_.add_frame(last_end);
range = cfg.child_range("sound");
for(; range.first != range.second; ++range.first){
@ -77,62 +74,56 @@ unit_animation::unit_animation(const config& cfg)
}
}
int unit_animation::get_first_frame(unit_animation::FRAME_TYPE type) const
int unit_animation::get_first_frame_time(unit_animation::FRAME_TYPE type) const
{
if(frames_[type].empty())
return 0;
else
return minimum<int>(frames_[type].front().start,0);
}
int unit_animation::get_last_frame(unit_animation::FRAME_TYPE type) const
{
if(frames_[type].empty())
return 0;
else
return maximum<int>(frames_[type].back().end,0);
}
const std::string* unit_animation::get_frame(int milliseconds, int* xoff,
unit_animation::FRAME_TYPE type,
unit_animation::FRAME_DIRECTION dir,
const std::string** halo, int* halo_x, int* halo_y) const
{
for(std::vector<frame>::const_iterator i = frames_[type].begin();
i != frames_[type].end(); ++i) {
if(i->start > milliseconds)
return NULL;
if(i->start <= milliseconds && i->end > milliseconds) {
if(xoff != NULL) {
*xoff = i->xoffset;
}
if(halo != NULL) {
if(i->halo.empty()) {
*halo = NULL;
} else {
*halo = &i->halo;
}
if(halo_x != NULL) {
*halo_x = i->halo_x;
}
if(halo_y != NULL) {
*halo_y = i->halo_y;
}
}
if(dir == DIAGONAL && i->image_diagonal != "") {
return &i->image_diagonal;
} else {
return &i->image;
}
}
if(type == UNIT_FRAME) {
return unit_frames_.get_first_frame_time();
} else {
return missile_frames_.get_first_frame_time();
}
}
return NULL;
int unit_animation::get_last_frame_time(unit_animation::FRAME_TYPE type) const
{
if(type == UNIT_FRAME) {
return unit_frames_.get_last_frame_time();
} else {
return missile_frames_.get_last_frame_time();
}
}
void unit_animation::start_animation(int start_frame, FRAME_TYPE type, int acceleration)
{
if (type == UNIT_FRAME) {
unit_frames_.start_animation(start_frame, 1, acceleration);
} else {
missile_frames_.start_animation(start_frame, 1, acceleration);
}
}
void unit_animation::update_current_frames()
{
unit_frames_.update_current_frame();
missile_frames_.update_current_frame();
}
bool unit_animation::animation_finished() const
{
return unit_frames_.animation_finished() && missile_frames_.animation_finished();
}
const unit_animation::frame& unit_animation::get_current_frame(FRAME_TYPE type) const
{
if(type == UNIT_FRAME) {
return unit_frames_.get_current_frame();
} else {
return missile_frames_.get_current_frame();
}
}
int unit_animation::get_animation_time() const
{
return unit_frames_.get_animation_time();
}
const std::vector<unit_animation::sfx>& unit_animation::sound_effects() const

View file

@ -17,6 +17,7 @@
#include "map.hpp"
#include "race.hpp"
#include "team.hpp"
#include "animated.hpp"
#include <string>
#include <vector>
@ -25,22 +26,30 @@
class unit_animation
{
public:
struct frame {
frame() {};
frame(const config& cfg);
// int start, end;
int xoffset;
std::string image;
std::string image_diagonal;
std::string halo;
int halo_x, halo_y;
};
unit_animation(const config& cfg);
enum FRAME_TYPE { UNIT_FRAME, MISSILE_FRAME };
enum FRAME_DIRECTION { VERTICAL, DIAGONAL };
int get_first_frame(FRAME_TYPE type=UNIT_FRAME) const;
int get_last_frame(FRAME_TYPE type=UNIT_FRAME) const;
//function which gets an attack animation frame. The argument
//is 0 for the frame at the time of impact, and negative for
//frames before the time of impact
const std::string* get_frame(int milliseconds, int* xoffset=NULL,
FRAME_TYPE type=UNIT_FRAME,
FRAME_DIRECTION direction=VERTICAL,
const std::string** halo=NULL,
int* halo_x=NULL, int* halo_y=NULL) const;
void start_animation(int start_frame, FRAME_TYPE type, int acceleration);
void update_current_frames();
bool animation_finished() const;
const frame& get_current_frame(FRAME_TYPE type=UNIT_FRAME) const;
int get_animation_time() const;
int get_first_frame_time(FRAME_TYPE type=UNIT_FRAME) const;
int get_last_frame_time(FRAME_TYPE type=UNIT_FRAME) const;
struct sfx {
int time;
@ -50,26 +59,10 @@ public:
const std::vector<sfx>& sound_effects() const;
private:
struct frame {
frame(int i1, int i2, const std::string& img, const std::string& halo, int offset, int halo_x, int halo_y)
: start(i1), end(i2), xoffset(offset), image(img), halo(halo), halo_x(halo_x), halo_y(halo_y)
{}
frame(int i1, int i2, const std::string& img, const std::string& diag,
const std::string& halo, int offset, int halo_x, int halo_y)
: start(i1), end(i2), xoffset(offset),
image(img), image_diagonal(diag), halo(halo), halo_x(halo_x), halo_y(halo_y)
{}
int start, end;
int xoffset;
std::string image;
std::string image_diagonal;
std::string halo;
int halo_x, halo_y;
};
std::vector<frame> frames_[2];
// std::vector<frame> frames_[2];
animated<frame> unit_frames_;
animated<frame> missile_frames_;
std::vector<sfx> sfx_;
};

View file

@ -94,7 +94,7 @@ void clear_updates()
update_rects.clear();
}
SDL_Surface* frameBuffer = NULL;
surface frameBuffer = NULL;
}
@ -103,7 +103,7 @@ bool non_interactive()
return SDL_GetVideoSurface() == NULL;
}
SDL_Surface* display_format_alpha(SDL_Surface* surf)
surface display_format_alpha(surface surf)
{
if(SDL_GetVideoSurface() != NULL)
return SDL_DisplayFormatAlpha(surf);
@ -113,7 +113,7 @@ SDL_Surface* display_format_alpha(SDL_Surface* surf)
return NULL;
}
SDL_Surface* get_video_surface()
surface get_video_surface()
{
return frameBuffer;
}
@ -131,7 +131,7 @@ void update_rect(const SDL_Rect& rect_value)
SDL_Rect rect = rect_value;
SDL_Surface* const fb = SDL_GetVideoSurface();
surface const fb = SDL_GetVideoSurface();
if(fb != NULL) {
if(rect.x < 0) {
if(rect.x*-1 >= int(rect.w))
@ -337,7 +337,7 @@ int CVideo::mustLock()
return SDL_MUSTLOCK(frameBuffer);
}
SDL_Surface* CVideo::getSurface( void )
surface CVideo::getSurface( void )
{
return frameBuffer;
}

View file

@ -20,8 +20,8 @@
#define VIDEO_MEMORY SDL_HWSURFACE
#define SYSTEM_MEMORY SDL_SWSURFACE
SDL_Surface* display_format_alpha(SDL_Surface* surf);
SDL_Surface* get_video_surface();
surface display_format_alpha(surface surf);
surface get_video_surface();
bool non_interactive();
@ -57,7 +57,7 @@ class CVideo {
void flip();
SDL_Surface* getSurface( void );
surface getSurface( void );
bool isFullScreen() const;

View file

@ -42,10 +42,10 @@ button::button(display& disp, const std::string& label, button::TYPE type,
}
const std::string button_image_file = "buttons/" + button_image_name + ".png";
scoped_sdl_surface button_image(image::get_image(button_image_file,image::UNSCALED));
scoped_sdl_surface pressed_image(image::get_image("buttons/" + button_image_name + "-pressed.png", image::UNSCALED));
scoped_sdl_surface active_image(image::get_image("buttons/" + button_image_name + "-active.png", image::UNSCALED));
scoped_sdl_surface pressed_active_image(image::get_image("buttons/" + button_image_name + "-active-pressed.png", image::UNSCALED));
surface button_image(image::get_image(button_image_file,image::UNSCALED));
surface pressed_image(image::get_image("buttons/" + button_image_name + "-pressed.png", image::UNSCALED));
surface active_image(image::get_image("buttons/" + button_image_name + "-active.png", image::UNSCALED));
surface pressed_active_image(image::get_image("buttons/" + button_image_name + "-active-pressed.png", image::UNSCALED));
if(pressed_image == NULL) {
pressed_image.assign(image::get_image(button_image_file,image::UNSCALED));
@ -129,7 +129,7 @@ void button::draw()
bg_restore();
}
SDL_Surface* image = image_;
surface image = image_;
const int image_w = image_->w;
int offset = 0;
@ -155,7 +155,7 @@ void button::draw()
textx = location().x + image_w + checkbox_horizontal_padding/2;
}
scoped_sdl_surface greyed_image(NULL);
surface greyed_image(NULL);
if(!enabled_) {
greyed_image.assign(greyscale_image(image));
image = greyed_image;

View file

@ -64,7 +64,7 @@ private:
std::string label_;
display* display_;
shared_sdl_surface image_, pressedImage_, activeImage_, pressedActiveImage_;
surface image_, pressedImage_, activeImage_, pressedActiveImage_;
SDL_Rect textRect_;
bool button_;

View file

@ -144,7 +144,7 @@ void menu::set_loc(int x, int y)
const int w = width();
SDL_Rect portion = {x_,y_,w,height()};
SDL_Surface* const screen = display_->video().getSurface();
surface const screen = display_->video().getSurface();
buffer_.assign(get_surface_portion(screen, portion));
if(show_scrollbar()) {
@ -569,7 +569,7 @@ namespace {
const std::string str = *it;
if(str.empty() == false && str[0] == ImagePrefix) {
const std::string image_name(str.begin()+1,str.end());
SDL_Surface* const img = image::get_image(image_name,image::UNSCALED);
surface const img = image::get_image(image_name,image::UNSCALED);
if(img != NULL) {
res.w += img->w;
res.h = maximum<int>(img->h, res.h);
@ -650,7 +650,7 @@ void menu::draw_item(int item)
str = *it;
if(str.empty() == false && str[0] == ImagePrefix) {
const std::string image_name(str.begin()+1,str.end());
SDL_Surface* const img = image::get_image(image_name,image::UNSCALED);
surface const img = image::get_image(image_name,image::UNSCALED);
const int max_width = max_width_ < 0 ? display_->x() :
minimum<int>(max_width_, display_->x() - xpos);
if(img != NULL && (xpos - rect.x) + img->w < max_width

View file

@ -98,7 +98,7 @@ private:
mutable std::vector<int> column_widths_;
scoped_sdl_surface buffer_;
surface buffer_;
int selected_;
bool click_selects_;
bool previous_button_;

View file

@ -17,7 +17,7 @@ void progress_bar::set_progress_percent(int progress)
void progress_bar::draw()
{
SDL_Surface* const surf = disp().video().getSurface();
surface const surf = disp().video().getSurface();
SDL_Rect area = location();
if(area.w >= 2 && area.h >= 2) {
@ -40,4 +40,4 @@ void progress_bar::draw()
update_rect(location());
}
}
}

View file

@ -20,4 +20,4 @@ private:
}
#endif
#endif

View file

@ -41,7 +41,7 @@ scrollbar::scrollbar(display& d, scrollable* callback)
grip_position_(0), grip_height_(0), enabled_(false), width_(0),
minimum_grip_height_(0), groove_click_code_(0)
{
static const scoped_sdl_surface img(image::get_image(scrollbar_mid,
static const surface img(image::get_image(scrollbar_mid,
image::UNSCALED));
if (img != NULL) {
@ -120,16 +120,16 @@ void scrollbar::draw()
set_dirty(false);
const scoped_sdl_surface mid_img(image::get_image(highlight_ ?
const surface mid_img(image::get_image(highlight_ ?
scrollbar_mid_hl : scrollbar_mid, image::UNSCALED));
const scoped_sdl_surface bottom_img(image::get_image(highlight_ ?
const surface bottom_img(image::get_image(highlight_ ?
scrollbar_bottom_hl : scrollbar_bottom, image::UNSCALED));
const scoped_sdl_surface top_img(image::get_image(highlight_ ?
const surface top_img(image::get_image(highlight_ ?
scrollbar_top_hl : scrollbar_top, image::UNSCALED));
const scoped_sdl_surface top_grv(image::get_image(groove_top,image::UNSCALED));
const scoped_sdl_surface mid_grv(image::get_image(groove_mid,image::UNSCALED));
const scoped_sdl_surface bottom_grv(image::get_image(groove_bottom,image::UNSCALED));
const surface top_grv(image::get_image(groove_top,image::UNSCALED));
const surface mid_grv(image::get_image(groove_mid,image::UNSCALED));
const surface bottom_grv(image::get_image(groove_bottom,image::UNSCALED));
if (mid_img == NULL || bottom_img == NULL || top_img == NULL
|| top_grv == NULL || bottom_grv == NULL || mid_grv == NULL){
@ -144,14 +144,14 @@ void scrollbar::draw()
// of a larger problem, I think.
mid_height = 1;
}
const scoped_sdl_surface mid_scaled(scale_surface_blended(mid_img,
const surface mid_scaled(scale_surface_blended(mid_img,
mid_img->w, mid_height));
int groove_height = location().h - top_grv->h - bottom_grv->h;
if (groove_height <= 0) {
groove_height = 1;
}
const scoped_sdl_surface groove_scaled(scale_surface_blended(mid_grv,
const surface groove_scaled(scale_surface_blended(mid_grv,
mid_grv->w, groove_height));
if (mid_scaled == NULL || groove_scaled == NULL) {
@ -164,7 +164,7 @@ void scrollbar::draw()
return;
}
SDL_Surface* const screen = disp().video().getSurface();
surface const screen = disp().video().getSurface();
bg_restore();

View file

@ -78,7 +78,7 @@ int slider::max_value() const
SDL_Rect slider::slider_area() const
{
static const SDL_Rect default_value = {0,0,0,0};
const scoped_sdl_surface img(image::get_image(slider_image,image::UNSCALED));
const surface img(image::get_image(slider_image,image::UNSCALED));
if(img == NULL)
return default_value;
@ -98,14 +98,14 @@ void slider::draw()
return;
}
const scoped_sdl_surface image(image::get_image(highlight_ ? selected_image : slider_image,image::UNSCALED));
const surface image(image::get_image(highlight_ ? selected_image : slider_image,image::UNSCALED));
if(image == NULL || dirty() == false)
return;
if(image->w >= location().w)
return;
SDL_Surface* const screen = disp().video().getSurface();
surface const screen = disp().video().getSurface();
bg_restore();
@ -130,7 +130,7 @@ void slider::process()
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
const bool button = mouse_flags&SDL_BUTTON_LMASK;
const scoped_sdl_surface img(image::get_image(slider_image,image::UNSCALED));
const surface img(image::get_image(slider_image,image::UNSCALED));
if(img == NULL)
return;

View file

@ -77,7 +77,7 @@ void textbox::draw_cursor(int pos, display &disp) const
{
if(show_cursor_ && editable_) {
SDL_Rect rect = {location().x + pos, location().y, 1, location().h };
SDL_Surface* const frame_buffer = disp.video().getSurface();
surface const frame_buffer = disp.video().getSurface();
SDL_FillRect(frame_buffer,&rect,SDL_MapRGB(frame_buffer->format,255,255,255));
}
}

View file

@ -71,7 +71,7 @@ private:
//the cursor should be inverted every 500 ms.
//this will be reset when keyboard input events occur
int show_cursor_at_;
shared_sdl_surface text_image_;
surface text_image_;
SDL_Rect text_size_;
//variables used for multi-line textboxes which support scrolling