20 #define GETTEXT_DOMAIN "wesnoth-lib"
43 #include <SDL_image.h>
46 #include <boost/functional/hash.hpp>
52 #define ERR_DP LOG_STREAM(err, log_display)
53 #define LOG_DP LOG_STREAM(info, log_display)
56 #define ERR_CFG LOG_STREAM(err , log_config)
85 if (static_cast<unsigned>(index) >=
content_.size())
102 template <
typename T>
109 template <
typename T>
116 template <
typename T>
133 scaled_to_hex_images_,
138 image::texture_cache txt_images_,
140 txt_brightened_images_;
153 image::lit_texture_cache lit_textures_;
160 std::map<std::string,bool> image_existence_map;
163 std::set<std::string> precached_dirs;
165 std::map<surface, surface> reversed_images_;
167 int red_adjust = 0, green_adjust = 0, blue_adjust = 0;
170 std::vector<std::string> team_colors;
178 scaling_function scale_to_zoom_func;
179 scaling_function scale_to_hex_func;
194 #pragma omp critical(image_cache)
198 hexed_images_.flush();
199 tod_colored_images_.flush();
200 scaled_to_zoom_.flush();
201 scaled_to_hex_images_.flush();
202 brightened_images_.flush();
204 lit_scaled_images_.flush();
205 in_hex_info_.flush();
206 is_empty_hex_.flush();
207 mini_terrain_cache.clear();
208 mini_fogged_terrain_cache.clear();
209 mini_highlighted_terrain_cache.clear();
210 reversed_images_.clear();
211 image_existence_map.clear();
212 precached_dirs.clear();
224 if ( i == locator_finder.end() ) {
226 locator_finder.insert(std::make_pair(
val_,
index_));
238 size_t markup_field = fn.find(
'~');
240 if(markup_field != std::string::npos) {
243 fn = fn.substr(0,markup_field);
283 val_(filename, modifications)
291 val_(filename, loc, center_x, center_y, modifications)
306 modifications_(a.modifications_),
307 center_x_(a.center_x_), center_y_(a.center_y_)
313 center_x_(0), center_y_(0)
319 center_x_(0), center_y_(0)
325 center_x_(0), center_y_(0)
330 center_x_(0), center_y_(0)
335 center_x_(center_x), center_y_(center_y)
340 if(a.
type_ != type_) {
342 }
else if(type_ ==
FILE) {
355 if(type_ != a.
type_) {
356 return type_ < a.
type_;
357 }
else if(type_ ==
FILE) {
376 using boost::hash_combine;
387 hash_combine(hash, val.
loc_.
x);
388 hash_combine(hash, val.
loc_.
y);
403 if (fuzzy_localized_files.empty()) {
408 std::vector<std::string> lines =
utils::split(contents,
'\n');
410 size_t p1 = line.find(fsep);
411 if (p1 == std::string::npos)
415 if (state ==
"fuzzy") {
416 size_t p2 = line.find(fsep, p1 + fsep.length());
417 if (p2 == std::string::npos)
419 std::string relpath = line.substr(p1 + fsep.length(), p2 - p1 - fsep.length());
423 fuzzy_localized_files.insert(
"");
425 return fuzzy_localized_files.count(loc_file) == 0;
434 const size_t pos_ext = base.rfind(
".");
436 if (pos_ext != std::string::npos) {
437 loc_base = base.substr(0, pos_ext) + suff + base.substr(pos_ext);
439 loc_base = base + suff;
451 std::vector<std::string> langs =
utils::split(
_(
"language code for localized resources^en_US"));
455 langs.push_back(
"en_US");
457 std::string loc_file = dir +
"/" +
"l10n" +
"/" + lang +
"/" + loc_base;
469 surface ovr_surf = IMG_Load_RW(rwops,
true);
470 if (ovr_surf.
null()) {
476 area.w = ovr_surf->w;
477 area.h = ovr_surf->h;
478 sdl_blit(ovr_surf, 0, orig_surf, &area);
489 if (!location.empty()) {
492 if (!loc_location.empty()) {
493 location = loc_location;
496 res = IMG_Load_RW(rwops,
true);
498 if (!res.
null() && loc_location.empty()) {
500 if (!ovr_location.empty()) {
524 while(!mods.
empty()) {
531 ERR_CFG <<
"Failed to apply a modification to an image:\n"
553 bool is_empty =
false;
570 return static_cast<signed char>(std::min<int>(127, std::max<int>(-128, i/2)));
588 int m = ls[0] == -1 ? 2 : 1;
595 if(i != lightmaps_.end()) {
596 lightmap = i->second;
601 p+
"-n.png", p+
"-ne.png", p+
"-se.png",
602 p+
"-s.png", p+
"-sw.png", p+
"-nw.png",
607 for(
size_t c = 0;
c+3 < ls.size();
c+=4){
614 if(lightmap ==
nullptr) {
622 lightmaps_[ls] = lightmap;
646 sdl::timage load_texture(
const locator &loc)
650 return sdl::timage(img);
652 return sdl::timage();
668 assert(format !=
nullptr);
675 if (format->BitsPerPixel == 8
676 || f.BitsPerPixel != l.BitsPerPixel
677 || f.BytesPerPixel != l.BytesPerPixel
678 || f.Rmask != l.Rmask
679 || f.Gmask != l.Gmask
680 || f.Bmask != l.Bmask
682 || f.Rloss != l.Rloss
683 || f.Gloss != l.Gloss
684 || f.Bloss != l.Bloss
686 || f.Rshift != l.Rshift
687 || f.Gshift != l.Gshift
688 || f.Bshift != l.Bshift
692 LOG_DP <<
"detected a new display format\n";
695 last_pixel_format = *
format;
700 if(r != red_adjust || g != green_adjust || b != blue_adjust) {
704 tod_colored_images_.flush();
705 brightened_images_.flush();
707 lit_scaled_images_.flush();
708 reversed_images_.clear();
713 : r_(red_adjust), g_(green_adjust),
b_(blue_adjust)
724 if (colors ==
nullptr)
727 team_colors = *colors;
740 tod_colored_images_.flush();
741 brightened_images_.flush();
742 reversed_images_.clear();
747 if (zoom !=
tile_size && zoom != cached_zoom) {
748 scaled_to_zoom_.flush();
749 scaled_to_hex_images_.flush();
750 lit_scaled_images_.flush();
757 template <scaling_function F>
760 int best_integer_zoom = std::min(w / res.
get()->w, h / res.
get()->h);
761 int legal_zoom = std::max(std::min(best_integer_zoom, 5), 1);
765 static scaling_function
select_algorithm(gui2::tadvanced_graphics_options::SCALING_ALGORITHM algo)
769 case gui2::tadvanced_graphics_options::SCALING_ALGORITHM::LINEAR:
774 case gui2::tadvanced_graphics_options::SCALING_ALGORITHM::NEAREST_NEIGHBOR:
779 case gui2::tadvanced_graphics_options::SCALING_ALGORITHM::XBRZ_LIN:
781 scaling_function
result = &scale_xbrz_helper<scale_surface>;
784 case gui2::tadvanced_graphics_options::SCALING_ALGORITHM::XBRZ_NN:
786 scaling_function
result = &scale_xbrz_helper<scale_surface_nn>;
790 assert(
false &&
"I don't know how to implement this scaling algorithm");
799 bool is_empty =
false;
811 return scale_to_hex_func(img, zoom, zoom);
859 if (red_adjust==0 && green_adjust==0 && blue_adjust==0)
894 imap = &tod_colored_images_;
897 imap = &scaled_to_zoom_;
900 imap = &hexed_images_;
903 imap = &scaled_to_hex_images_;
906 imap = &brightened_images_;
915 #pragma omp critical(image_cache)
922 #pragma omp critical(image_cache)
958 #pragma omp critical(image_cache)
966 sdl::timage get_texture(
const locator& loc,
TYPE type)
969 return sdl::timage();
972 texture_cache *
cache;
977 cache = &txt_images_;
980 cache = &txt_brightened_images_;
985 cache = &txt_hexed_images_;
988 return sdl::timage();
991 if (!loc.in_cache(*cache)) {
993 sdl::timage txt = load_texture(loc);
994 loc.add_to_cache(*cache, txt);
997 sdl::timage txt(surf);
998 loc.add_to_cache(*cache, txt);
1001 sdl::timage txt(surf);
1002 loc.add_to_cache(*cache, txt);
1006 sdl::timage
result = loc.locate_in_cache(*cache);
1014 result.set_color_mod(red_adjust, green_adjust, blue_adjust);
1017 result.set_scale(zoom / 72.0
f, zoom / 72.0
f);
1020 return sdl::timage();
1028 sdl::timage get_lighted_texture(
const locator &i_locator,
const light_string &ls,
TYPE type)
1031 if(i_locator.is_void())
1035 if(!i_locator.in_cache(lit_textures_)){
1036 i_locator.add_to_cache(lit_textures_, lit_texture_variants());
1041 const lit_texture_variants& lvar = i_locator.locate_in_cache(lit_textures_);
1042 lit_texture_variants::const_iterator lvi = lvar.find(ls);
1043 if(lvi != lvar.end()) {
1052 res = sdl::timage(surf);
1055 res.set_scale(zoom / 72.0
f, zoom / 72.0
f);
1058 i_locator.access_in_cache(lit_textures_)[ls] =
res;
1076 imap = &lit_scaled_images_;
1086 lit_variants::const_iterator lvi = lvar.find(ls);
1087 if(lvi != lvar.end()) {
1125 #pragma omp critical(in_hex_info_)
1128 if(i_locator.
in_cache(in_hex_info_)) {
1148 if(!i_locator.
in_cache(is_empty_hex_)) {
1152 if(!i_locator.
in_cache(is_empty_hex_)) {
1156 bool is_empty =
false;
1167 if(surf ==
nullptr) {
1172 if(itor != reversed_images_.end()) {
1174 return itor->second;
1178 if(rev ==
nullptr) {
1182 reversed_images_.insert(std::pair<surface,surface>(surf,rev));
1191 if (type != loc::FILE && type != loc::SUB_FILE)
1196 it = image_existence_map.insert(std::make_pair(i_locator.
get_filename(),
false));
1197 bool &cache = it.first->second;
1205 const std::string checked_dir = dir +
"/" + subdir;
1206 if (precached_dirs.find(checked_dir) != precached_dirs.end())
1208 precached_dirs.insert(checked_dir);
1213 std::vector<std::string> files_found;
1214 std::vector<std::string> dirs_found;
1218 for(std::vector<std::string>::const_iterator
f = files_found.begin();
1219 f != files_found.end(); ++
f) {
1220 image_existence_map[subdir + *
f] =
true;
1223 for(std::vector<std::string>::const_iterator
d = dirs_found.begin();
1224 d != dirs_found.end(); ++
d) {
1233 for(std::vector<std::string>::const_iterator
p = paths.begin();
1234 p != paths.end(); ++
p) {
1242 std::map<std::string, bool>::const_iterator
b = image_existence_map.find(file);
1243 if (b != image_existence_map.end())
1261 LOG_DP <<
"Writing a png image to " << filename << std::endl;
1270 LOG_DP <<
"Writing a bmp image to " << filename << std::endl;
1271 return SDL_SaveBMP(surf, filename.c_str()) == 0;
1276 typedef gui2::tadvanced_graphics_options::SCALING_ALGORITHM SCALING_ALGORITHM;
1277 SCALING_ALGORITHM algo = SCALING_ALGORITHM::LINEAR;
1284 algo = SCALING_ALGORITHM::LINEAR;
TYPE
UNSCALED : image will be drawn "as is" without changing size, even in case of redraw SCALED_TO_ZOOM :...
static surface load_image_file(const image::locator &loc)
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
surface flip_surface(const surface &surf, bool optimize)
void precache_file_existence(const std::string &subdir)
precache the existence of files in the subdir (ex: "terrain/")
static surface scale_xbrz_helper(const surface &res, int w, int h)
std::map< t_translation::t_terrain, surface > mini_terrain_cache_map
SDL_Surface * get() const
void set_pixel_format(SDL_PixelFormat *format)
sets the pixel format used by the images.
bool operator<(const value &a) const
void set_team_colors(const std::vector< std::string > *colors)
set the team colors used by the TC image modification use a vector with one string for each team usin...
static surface get_scaled_to_hex(const locator &i_locator)
static surface get_hexed(const locator &i_locator)
bool precached_file_exists(const std::string &file)
GLuint GLuint GLsizei GLenum type
surface reverse_image(const surface &surf)
function to reverse an image.
static std::string get_localized_path(const std::string &file, const std::string &suff="")
surface create_optimized_surface(const surface &surf)
A modified priority queue used to order image modifications.
bool ends_with(const std::string &str, const std::string &suffix)
bool file_exists() const
Tests whether the file the locater points at exists.
mini_terrain_cache_map mini_fogged_terrain_cache
cache_item< T > & get_element(int index)
color_adjustment_resetter()
friend size_t hash_value(const value &)
GLenum GLsizei GLenum GLenum const GLvoid * image
static signed char col_to_uchar(int i)
GLuint const GLfloat * val
bool in_mask_surface(const surface &surf, const surface &mask)
Check if a surface fit into a mask.
#define SDL_SavePNG(surface, file)
void add_to_cache(cache_type< T > &cache, const T &data) const
static surface get_scaled_to_zoom(const locator &i_locator)
std::string get_binary_file_location(const std::string &type, const std::string &filename)
Returns a complete path to the actual file of a given type or an empty string if the file isn't prese...
surface scale_surface(const surface &surf, int w, int h)
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
cache_type< lit_variants > lit_cache
Definitions for the interface to Wesnoth Markup Language (WML).
const map_location & get_loc() const
cache_type< surface > image_cache
bool save_image(const locator &i_locator, const std::string &filename)
static std::set< std::string > fuzzy_localized_files
static scaling_function select_algorithm(gui2::tadvanced_graphics_options::SCALING_ALGORITHM algo)
void blit_surface(const surface &surf, const SDL_Rect *srcrect, surface &dst, const SDL_Rect *dstrect)
Replacement for sdl_blit.
std::string & strip(std::string &str)
Remove whitespace from the front and back of the string 'str'.
GLdouble GLdouble GLdouble b
static TYPE simplify_type(const image::locator &i_locator, TYPE type)
translate type to a simpler one when possible
bool exists(const image::locator &i_locator)
returns true if the given image actually exists, without loading it.
static UNUSEDNOWARN std::string _(const char *str)
surface mask_surface(const surface &surf, const surface &mask, bool *empty_result, const std::string &filename)
Applies a mask on a surface.
std::string get(const std::string &key)
bool in_cache(cache_type< T > &cache) const
static surface get_brightened(const locator &i_locator)
static surface load_image_sub_file(const image::locator &loc)
static surface get_tod_colored(const locator &i_locator)
light_string get_light_string(int op, int r, int g, int b)
return light_string of one light operation(see above)
bool operator==(const value &a) const
std::string modifications_
SDL_Surface * SDL_PNGFormatAlpha(SDL_Surface *src)
GLubyte GLubyte GLubyte GLubyte w
std::string base_name(const std::string &file)
Returns the base filename of a file, with directory name stripped.
GLboolean GLboolean GLboolean GLboolean a
static SDL_PixelFormat last_pixel_format
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
std::map< light_string, surface > lit_variants
surface light_surface(const surface &surf, const surface &lightmap, bool optimize)
Light surf using lightmap.
std::vector< cache_item< T > > content_
T & access_in_cache(cache_type< T > &cache) const
Base abstract class for an image-path modification.
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
static void precache_file_existence_internal(const std::string &dir, const std::string &subdir)
surface scale_surface_nn(const surface &surf, int w, int h)
Scale a surface using the nearest neighbor algorithm (provided by xBRZ lib)
const std::string ¶meters float amount
static modification_queue decode(const std::string &)
Decodes modifications from a modification string.
void set_color_adjustment(int r, int g, int b)
will make all scaled images have these rgb values added to all their pixels.
Encapsulates the map of the game.
const std::string & get_filename() const
const std::string & get_modifications() const
surface adjust_surface_color(const surface &surf, int red, int green, int blue, bool optimize)
surface load_from_disk(const locator &loc)
const std::vector< std::string > & get_binary_paths(const std::string &type)
Returns a vector with all possible paths to a given type of binary, e.g.
void get_files_in_dir(const std::string &dir, std::vector< std::string > *files, std::vector< std::string > *dirs=nullptr, file_name_option mode=FILE_NAME_ONLY, file_filter_option filter=NO_FILTER, file_reorder_option reorder=DONT_REORDER, file_tree_checksum *checksum=nullptr)
Populates 'files' with all the files and 'dirs' with all the directories in dir.
cache_type< bool > bool_cache
std::map< std::string, tfilter >::iterator itor
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
modification * top() const
Returns the top element in the queue .
surface scale_surface_xbrz(const surface &surf, size_t z)
Scale a surface using xBRZ algorithm.
locator & operator=(const locator &a)
surface get_hexmask()
function to get the standard hex mask
std::basic_string< signed char > light_string
light_string store colors info of central and adjacent hexes.
size_t hash_value(const locator::value &val)
GLfloat GLfloat GLfloat GLfloat h
surface brighten_image(const surface &surf, fixed_t amount, bool optimize)
mini_terrain_cache_map mini_highlighted_terrain_cache
Declarations for File-IO.
void set_zoom(int amount)
sets the amount scaled images should be scaled.
GLdouble GLdouble GLdouble r
bool is_in_hex(const locator &i_locator)
function to check if an image fit into an hex return false if the image has not the standard size...
static bool localized_file_uptodate(const std::string &loc_file)
mini_terrain_cache_map mini_terrain_cache
cache_item(const T &item)
surface get_lighted_image(const image::locator &i_locator, const light_string &ls, TYPE type)
function to get the surface corresponding to an image.
const T & locate_in_cache(cache_type< T > &cache) const
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an empty SDL_Rect.
const std::string message
The error message regarding the failed operation.
const std::vector< std::string > & modifications(bool mp)
Contains the SDL_Rect helper code.
bool is_empty_hex(const locator &i_locator)
function to check if an image is empty after hex cut should be only used on terrain image (cache the ...
Exception thrown by the operator() when an error occurs.
static void add_localized_overlay(const std::string &ovr_file, surface &orig_surf)
surface make_neutral_surface(const surface &surf)
this module manages the cache of images.
Standard logging facilities (interface).
boost::unordered_map< value, int > locator_finder_t
static lg::log_domain log_config("config")
const std::vector< std::string > & get_team_colors()
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
void pop()
Removes the top element from the queue.
bool update_from_preferences()
initialize any private data, e.g. algorithm choices from preferences
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
SDL_RWops * load_RWops(const std::string &path)
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
GLsizei const GLcharARB ** string
static lg::log_domain log_display("display")
static surface apply_light(surface surf, const light_string &ls)
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
surface cut_surface(const surface &surf, SDL_Rect const &r)
Cuts a rectangle from a surface.
#define ftofxp(x)
IN: float or int - OUT: fixed_t.