The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
image.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Routines for images: load, scale, re-color, etc.
18  */
19 
20 #define GETTEXT_DOMAIN "wesnoth-lib"
21 
22 #include "global.hpp"
23 
24 #include "color_range.hpp"
25 #include "config.hpp"
26 #include "filesystem.hpp"
27 #include "game_config.hpp"
28 #include "image.hpp"
29 #include "image_modifications.hpp"
30 #include "log.hpp"
31 #include "gettext.hpp"
33 #include "preferences.hpp"
34 #include "sdl/rect.hpp"
35 
36 #ifdef HAVE_LIBPNG
37 #include "SDL_SavePNG/savepng.h"
38 #endif
39 
41 #include "video.hpp"
42 
43 #include <SDL_image.h>
44 
45 #include "utils/functional.hpp"
46 #include <boost/functional/hash.hpp>
47 
48 #include <list>
49 #include <set>
50 
51 static lg::log_domain log_display("display");
52 #define ERR_DP LOG_STREAM(err, log_display)
53 #define LOG_DP LOG_STREAM(info, log_display)
54 
55 static lg::log_domain log_config("config");
56 #define ERR_CFG LOG_STREAM(err , log_config)
57 
59 
60 template<typename T>
61 struct cache_item
62 {
63  cache_item(): item(), loaded(false)
64  {}
65 
66  cache_item(const T &item): item(item), loaded(true)
67  {}
68 
69  T item;
70  bool loaded;
71 };
72 
73 
74 
75 namespace image {
76 
77 template<typename T>
79 {
80 public:
82  {}
83 
85  if (static_cast<unsigned>(index) >= content_.size())
86  content_.resize(index + 1);
87  return content_[index];
88  }
89 
90  void flush() { content_.clear(); }
91 
92 private:
93  std::vector<cache_item<T> > content_;
94 };
95 
96 template <typename T>
98 {
99  return index_ < 0 ? false : cache.get_element(index_).loaded;
100 }
101 
102 template <typename T>
104 {
105  static T dummy;
106  return index_ < 0 ? dummy : cache.get_element(index_).item;
107 }
108 
109 template <typename T>
111 {
112  static T dummy;
113  return index_ < 0 ? dummy : cache.get_element(index_).item;
114 }
115 
116 template <typename T>
118 {
119  if (index_ >= 0)
121 }
122 
123 }
124 
125 namespace {
126 
127 image::locator::locator_finder_t locator_finder;
128 
129 /** Definition of all image maps */
130 image::image_cache images_,
131  scaled_to_zoom_,
132  hexed_images_,
133  scaled_to_hex_images_,
134  tod_colored_images_,
135  brightened_images_;
136 
137 #ifdef SDL_GPU
138 image::texture_cache txt_images_,
139  txt_hexed_images_,
140  txt_brightened_images_;
141 #endif
142 
143 // cache storing if each image fit in a hex
144 image::bool_cache in_hex_info_;
145 
146 // cache storing if this is an empty hex
147 image::bool_cache is_empty_hex_;
148 
149 // caches storing the different lighted cases for each image
150 image::lit_cache lit_images_,
151  lit_scaled_images_;
152 #ifdef SDL_GPU
153 image::lit_texture_cache lit_textures_;
154 #endif
155 // caches storing each lightmap generated
156 image::lit_variants lightmaps_;
157 
158 // const int cache_version_ = 0;
159 
160 std::map<std::string,bool> image_existence_map;
161 
162 // directories where we already cached file existence
163 std::set<std::string> precached_dirs;
164 
165 std::map<surface, surface> reversed_images_;
166 
167 int red_adjust = 0, green_adjust = 0, blue_adjust = 0;
168 
169 /** List of colors used by the TC image modification */
170 std::vector<std::string> team_colors;
171 
172 int zoom = tile_size;
173 int cached_zoom = 0;
174 
175 /** Algorithm choices */
176 //typedef std::function<surface(const surface &, int, int)> scaling_function;
177 typedef surface(*scaling_function)(const surface &, int, int);
178 scaling_function scale_to_zoom_func;
179 scaling_function scale_to_hex_func;
180 
181 } // end anon namespace
182 
183 namespace image {
184 
188 
189 static int last_index_ = 0;
190 
192 {
193 #ifdef _OPENMP
194 #pragma omp critical(image_cache)
195 #endif //_OPENMP
196  {
197  images_.flush();
198  hexed_images_.flush();
199  tod_colored_images_.flush();
200  scaled_to_zoom_.flush();
201  scaled_to_hex_images_.flush();
202  brightened_images_.flush();
203  lit_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();
213  }
214  /* We can't reset last_index_, since some locators are still alive
215  when using :refresh. That would cause them to point to the wrong
216  images. Not resetting the variable causes a memory leak, though. */
217  // last_index_ = 0;
218 }
219 
221 {
222  locator_finder_t::iterator i = locator_finder.find(val_);
223 
224  if ( i == locator_finder.end() ) {
225  index_ = last_index_++;
226  locator_finder.insert(std::make_pair(val_, index_));
227  } else {
228  index_ = i->second;
229  }
230 }
231 
233 {
234  std::string& fn = val_.filename_;
235  if(fn.empty()) {
236  return;
237  }
238  size_t markup_field = fn.find('~');
239 
240  if(markup_field != std::string::npos) {
241  val_.type_ = SUB_FILE;
242  val_.modifications_ = fn.substr(markup_field, fn.size() - markup_field);
243  fn = fn.substr(0,markup_field);
244  }
245 }
246 
248  index_(-1),
249  val_()
250 {
251 }
252 
253 locator::locator(const locator &a, const std::string& mods):
254  index_(-1),
255  val_(a.val_)
256 {
257  if(!mods.empty()){
258  val_.modifications_ += mods;
260  init_index();
261  }
262  else index_=a.index_;
263 }
264 
265 locator::locator(const char *filename) :
266  index_(-1),
267  val_(filename)
268 {
269  parse_arguments();
270  init_index();
271 }
272 
273 locator::locator(const std::string &filename) :
274  index_(-1),
275  val_(filename)
276 {
277  parse_arguments();
278  init_index();
279 }
280 
282  index_(-1),
283  val_(filename, modifications)
284 {
285  init_index();
286 }
287 
288 locator::locator(const std::string &filename, const map_location &loc,
289  int center_x, int center_y, const std::string& modifications) :
290  index_(-1),
291  val_(filename, loc, center_x, center_y, modifications)
292 {
293  init_index();
294 }
295 
297 {
298  index_ = a.index_;
299  val_ = a.val_;
300 
301  return *this;
302 }
303 
305  type_(a.type_), filename_(a.filename_), loc_(a.loc_),
306  modifications_(a.modifications_),
307  center_x_(a.center_x_), center_y_(a.center_y_)
308 {}
309 
311  type_(NONE), filename_(), loc_(),
312  modifications_(),
313  center_x_(0), center_y_(0)
314 {}
315 
316 locator::value::value(const char *filename) :
317  type_(FILE), filename_(filename), loc_(),
318  modifications_(),
319  center_x_(0), center_y_(0)
320 {}
321 
323  type_(FILE), filename_(filename), loc_(),
324  modifications_(),
325  center_x_(0), center_y_(0)
326 {}
327 
329  type_(SUB_FILE), filename_(filename), loc_(), modifications_(modifications),
330  center_x_(0), center_y_(0)
331 {}
332 
333 locator::value::value(const std::string& filename, const map_location& loc, int center_x, int center_y, const std::string& modifications) :
334  type_(SUB_FILE), filename_(filename), loc_(loc), modifications_(modifications),
335  center_x_(center_x), center_y_(center_y)
336 {}
337 
339 {
340  if(a.type_ != type_) {
341  return false;
342  } else if(type_ == FILE) {
343  return filename_ == a.filename_;
344  } else if(type_ == SUB_FILE) {
345  return filename_ == a.filename_ && loc_ == a.loc_
346  && modifications_ == a.modifications_
347  && center_x_ == a.center_x_ && center_y_ == a.center_y_;
348  } else {
349  return false;
350  }
351 }
352 
354 {
355  if(type_ != a.type_) {
356  return type_ < a.type_;
357  } else if(type_ == FILE) {
358  return filename_ < a.filename_;
359  } else if(type_ == SUB_FILE) {
360  if(filename_ != a.filename_)
361  return filename_ < a.filename_;
362  if(loc_ != a.loc_)
363  return loc_ < a.loc_;
364  if(center_x_ != a.center_x_)
365  return center_x_ < a.center_x_;
366  if(center_y_ != a.center_y_)
367  return center_y_ < a.center_y_;
368  return (modifications_ < a.modifications_);
369  } else {
370  return false;
371  }
372 }
373 
374 size_t hash_value(const locator::value& val) {
375  using boost::hash_value;
376  using boost::hash_combine;
377 
378  /*
379  * Boost 1.51.0 seems not longer accept an enumerate value in its hash
380  * function so cast it to a type it does like.
381  */
382  size_t hash = hash_value(static_cast<unsigned>(val.type_));
383  if (val.type_ == locator::FILE || val.type_ == locator::SUB_FILE) {
384  hash_combine(hash, val.filename_);
385  }
386  if (val.type_ == locator::SUB_FILE) {
387  hash_combine(hash, val.loc_.x);
388  hash_combine(hash, val.loc_.y);
389  hash_combine(hash, val.center_x_);
390  hash_combine(hash, val.center_y_);
391  hash_combine(hash, val.modifications_);
392  }
393 
394  return hash;
395 }
396 
397 // Check if localized file is up-to-date according to l10n track index.
398 // Make sure only that the image is not explicitly recorded as fuzzy,
399 // in order to be able to use non-tracked images (e.g. from UMC).
400 static std::set<std::string> fuzzy_localized_files;
401 static bool localized_file_uptodate (const std::string& loc_file)
402 {
403  if (fuzzy_localized_files.empty()) {
404  // First call, parse track index to collect fuzzy files by path.
405  std::string fsep = "\xC2\xA6"; // UTF-8 for "broken bar"
406  std::string trackpath = filesystem::get_binary_file_location("", "l10n-track");
407  std::string contents = filesystem::read_file(trackpath);
408  std::vector<std::string> lines = utils::split(contents, '\n');
409  for (const std::string &line : lines) {
410  size_t p1 = line.find(fsep);
411  if (p1 == std::string::npos)
412  continue;
413  std::string state = line.substr(0, p1);
414  utils::strip(state);
415  if (state == "fuzzy") {
416  size_t p2 = line.find(fsep, p1 + fsep.length());
417  if (p2 == std::string::npos)
418  continue;
419  std::string relpath = line.substr(p1 + fsep.length(), p2 - p1 - fsep.length());
420  fuzzy_localized_files.insert(game_config::path + '/' + relpath);
421  }
422  }
423  fuzzy_localized_files.insert(""); // make sure not empty any more
424  }
425  return fuzzy_localized_files.count(loc_file) == 0;
426 }
427 
428 // Return path to localized counterpart of the given file, if any, or empty string.
429 // Localized counterpart may also be requested to have a suffix to base name.
430 static std::string get_localized_path (const std::string& file, const std::string& suff = "")
431 {
433  std::string base = filesystem::base_name(file);
434  const size_t pos_ext = base.rfind(".");
435  std::string loc_base;
436  if (pos_ext != std::string::npos) {
437  loc_base = base.substr(0, pos_ext) + suff + base.substr(pos_ext);
438  } else {
439  loc_base = base + suff;
440  }
441  // TRANSLATORS: This is the language code which will be used
442  // to store and fetch localized non-textual resources, such as images,
443  // when they exist. Normally it is just the code of the PO file itself,
444  // e.g. "de" of de.po for German. But it can also be a comma-separated
445  // list of language codes by priority, when the localized resource
446  // found for first of those languages will be used. This is useful when
447  // two languages share sufficient commonality, that they can use each
448  // other's resources rather than duplicating them. For example,
449  // Swedish (sv) and Danish (da) are such, so Swedish translator could
450  // translate this message as "sv,da", while Danish as "da,sv".
451  std::vector<std::string> langs = utils::split(_("language code for localized resources^en_US"));
452  // In case even the original image is split into base and overlay,
453  // add en_US with lowest priority, since the message above will
454  // not have it when translated.
455  langs.push_back("en_US");
456  for (const std::string &lang : langs) {
457  std::string loc_file = dir + "/" + "l10n" + "/" + lang + "/" + loc_base;
458  if (filesystem::file_exists(loc_file) && localized_file_uptodate(loc_file)) {
459  return loc_file;
460  }
461  }
462  return "";
463 }
464 
465 // Load overlay image and compose it with the original surface.
466 static void add_localized_overlay (const std::string& ovr_file, surface &orig_surf)
467 {
468  SDL_RWops *rwops = filesystem::load_RWops(ovr_file);
469  surface ovr_surf = IMG_Load_RW(rwops, true); // SDL takes ownership of rwops
470  if (ovr_surf.null()) {
471  return;
472  }
473  SDL_Rect area;
474  area.x = 0;
475  area.y = 0;
476  area.w = ovr_surf->w;
477  area.h = ovr_surf->h;
478  sdl_blit(ovr_surf, 0, orig_surf, &area);
479 }
480 
482 {
483  surface res;
484 
486 
487 
488  {
489  if (!location.empty()) {
490  // Check if there is a localized image.
491  const std::string loc_location = get_localized_path(location);
492  if (!loc_location.empty()) {
493  location = loc_location;
494  }
495  SDL_RWops *rwops = filesystem::load_RWops(location);
496  res = IMG_Load_RW(rwops, true); // SDL takes ownership of rwops
497  // If there was no standalone localized image, check if there is an overlay.
498  if (!res.null() && loc_location.empty()) {
499  const std::string ovr_location = get_localized_path(location, "--overlay");
500  if (!ovr_location.empty()) {
501  add_localized_overlay(ovr_location, res);
502  }
503  }
504  }
505  }
506 
507  if (res.null() && !loc.get_filename().empty()) {
508  ERR_DP << "could not open image '" << loc.get_filename() << "'" << std::endl;
511  }
512 
513  return res;
514 }
515 
517 {
519  if(surf == nullptr)
520  return nullptr;
521 
523 
524  while(!mods.empty()) {
525  modification* mod = mods.top();
526  mods.pop();
527 
528  try {
529  surf = (*mod)(surf);
530  } catch(const image::modification::texception& e) {
531  ERR_CFG << "Failed to apply a modification to an image:\n"
532  << "Image: " << loc.get_filename() << ".\n"
533  << "Modifications: " << loc.get_modifications() << ".\n"
534  << "Error: " << e.message;
535  }
536  delete mod;
537  }
538 
539  if(loc.get_loc().valid()) {
540  SDL_Rect srcrect = sdl::create_rect(
541  ((tile_size*3) / 4) * loc.get_loc().x
542  , tile_size * loc.get_loc().y + (tile_size / 2) * (loc.get_loc().x % 2)
543  , tile_size
544  , tile_size);
545 
546  if(loc.get_center_x() >= 0 && loc.get_center_y() >= 0){
547  srcrect.x += surf->w/2 - loc.get_center_x();
548  srcrect.y += surf->h/2 - loc.get_center_y();
549  }
550 
551  // cut and hex mask, but also check and cache if empty result
552  surface cut(cut_surface(surf, srcrect));
553  bool is_empty = false;
554  surf = mask_surface(cut, get_hexmask(), &is_empty);
555  // discard empty images to free memory
556  if(is_empty) {
557  // Safe because those images are only used by terrain rendering
558  // and it filters them out.
559  // A safer and more general way would be to keep only one copy of it
560  surf = nullptr;
561  }
562  loc.add_to_cache(is_empty_hex_, is_empty);
563  }
564 
565  return surf;
566 }
567 
568 //small utility function to store an int from (-256,254) to an signed char
569 static signed char col_to_uchar(int i) {
570  return static_cast<signed char>(std::min<int>(127, std::max<int>(-128, i/2)));
571 }
572 
573 light_string get_light_string(int op, int r, int g, int b){
574  light_string ls;
575  ls.reserve(4);
576  ls.push_back(op);
577  ls.push_back(col_to_uchar(r));
578  ls.push_back(col_to_uchar(g));
579  ls.push_back(col_to_uchar(b));
580  return ls;
581 }
582 
584  // atomic lightmap operation are handled directly (important to end recursion)
585  if(ls.size() == 4){
586  //if no lightmap (first char = -1) then we need the initial value
587  //(before the halving done for lightmap)
588  int m = ls[0] == -1 ? 2 : 1;
589  return adjust_surface_color(surf, ls[1]*m, ls[2]*m, ls[3]*m);
590  }
591 
592  // check if the lightmap is already cached or need to be generated
593  surface lightmap = nullptr;
594  lit_variants::iterator i = lightmaps_.find(ls);
595  if(i != lightmaps_.end()) {
596  lightmap = i->second;
597  } else {
598  //build all the 7 paths for lightmap sources
599  static const std::string p = "terrain/light";
600  static const std::string lm_img[7] = {
601  p+"-n.png", p+"-ne.png", p+"-se.png",
602  p+"-s.png", p+"-sw.png", p+"-nw.png",
603  p+".png"
604  };
605 
606  //decompose into atomic lightmap operations (4 chars)
607  for(size_t c = 0; c+3 < ls.size(); c+=4){
608  light_string sls = ls.substr(c,4);
609  //get the corresponding image and apply the lightmap operation to it
610  //This allows to also cache lightmap parts.
611  //note that we avoid infinite recursion by using only atomic operation
612  surface lts = image::get_lighted_image(lm_img[sls[0]], sls, HEXED);
613  //first image will be the base where we blit the others
614  if(lightmap == nullptr) {
615  //copy the cached image to avoid modifying the cache
616  lightmap = make_neutral_surface(lts);
617  } else{
618  blit_surface(lts, nullptr, lightmap, nullptr);
619  }
620  }
621  //cache the result
622  lightmaps_[ls] = lightmap;
623  }
624  // apply the final lightmap
625  return light_surface(surf, lightmap);
626 }
627 
629 {
630  return !filesystem::get_binary_file_location("images", val_.filename_).empty();
631 }
632 
634 {
635  switch(loc.get_type()) {
636  case locator::FILE:
637  return load_image_file(loc);
638  case locator::SUB_FILE:
639  return load_image_sub_file(loc);
640  default:
641  return surface(nullptr);
642  }
643 }
644 
645 #ifdef SDL_GPU
646 sdl::timage load_texture(const locator &loc)
647 {
648  surface img = load_from_disk(loc);
649  if (!img.null()) {
650  return sdl::timage(img);
651  } else {
652  return sdl::timage();
653  }
654 }
655 #endif
656 
658 
660 {
661  flush_cache();
662 }
663 
664 static SDL_PixelFormat last_pixel_format;
665 
666 void set_pixel_format(SDL_PixelFormat* format)
667 {
668  assert(format != nullptr);
669 
670  SDL_PixelFormat &f = *format;
671  SDL_PixelFormat &l = last_pixel_format;
672  // if the pixel format change, we clear the cache,
673  // because some images are now optimized for the wrong display format
674  // FIXME: 8 bpp use palette, need to compare them. For now assume a change
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
681 // || f.Amask != l.Amask This field in not checked, not sure why.
682  || f.Rloss != l.Rloss
683  || f.Gloss != l.Gloss
684  || f.Bloss != l.Bloss
685 // || f.Aloss != l.Aloss This field in not checked, not sure why.
686  || f.Rshift != l.Rshift
687  || f.Gshift != l.Gshift
688  || f.Bshift != l.Bshift
689 // || f.Ashift != l.Ashift This field in not checked, not sure why.
690  )
691  {
692  LOG_DP << "detected a new display format\n";
693  flush_cache();
694  }
695  last_pixel_format = *format;
696 }
697 
698 void set_color_adjustment(int r, int g, int b)
699 {
700  if(r != red_adjust || g != green_adjust || b != blue_adjust) {
701  red_adjust = r;
702  green_adjust = g;
703  blue_adjust = b;
704  tod_colored_images_.flush();
705  brightened_images_.flush();
706  lit_images_.flush();
707  lit_scaled_images_.flush();
708  reversed_images_.clear();
709  }
710 }
711 
713 : r_(red_adjust), g_(green_adjust), b_(blue_adjust)
714 {
715 }
716 
718 {
720 }
721 
722 void set_team_colors(const std::vector<std::string>* colors)
723 {
724  if (colors == nullptr)
725  team_colors.clear();
726  else {
727  team_colors = *colors;
728  }
729 }
730 
731 const std::vector<std::string>& get_team_colors()
732 {
733  return team_colors;
734 }
735 
736 void set_zoom(int amount)
737 {
738  if(amount != zoom) {
739  zoom = amount;
740  tod_colored_images_.flush();
741  brightened_images_.flush();
742  reversed_images_.clear();
743 
744  // We keep these caches if:
745  // we use default zoom (it doesn't need those)
746  // or if they are already at the wanted zoom.
747  if (zoom != tile_size && zoom != cached_zoom) {
748  scaled_to_zoom_.flush();
749  scaled_to_hex_images_.flush();
750  lit_scaled_images_.flush();
751  cached_zoom = zoom;
752  }
753  }
754 }
755 
756 // F should be a scaling algorithm without "integral" zoom limitations
757 template <scaling_function F>
758 static surface scale_xbrz_helper(const surface & res, int w, int h)
759 {
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);
762  return F(scale_surface_xbrz(res, legal_zoom), w, h);
763 }
764 
765 static scaling_function select_algorithm(gui2::tadvanced_graphics_options::SCALING_ALGORITHM algo)
766 {
767  switch (algo.v)
768  {
769  case gui2::tadvanced_graphics_options::SCALING_ALGORITHM::LINEAR:
770  {
771  scaling_function result = &scale_surface;
772  return result;
773  }
774  case gui2::tadvanced_graphics_options::SCALING_ALGORITHM::NEAREST_NEIGHBOR:
775  {
776  scaling_function result = &scale_surface_nn;
777  return result;
778  }
779  case gui2::tadvanced_graphics_options::SCALING_ALGORITHM::XBRZ_LIN:
780  {
781  scaling_function result = &scale_xbrz_helper<scale_surface>;
782  return result;
783  }
784  case gui2::tadvanced_graphics_options::SCALING_ALGORITHM::XBRZ_NN:
785  {
786  scaling_function result = &scale_xbrz_helper<scale_surface_nn>;
787  return result;
788  }
789  default:
790  assert(false && "I don't know how to implement this scaling algorithm");
791  throw 42;
792  }
793 }
794 
795 static surface get_hexed(const locator& i_locator)
796 {
797  surface image(get_image(i_locator, UNSCALED));
798  // hex cut tiles, also check and cache if empty result
799  bool is_empty = false;
800  surface res = mask_surface(image, get_hexmask(), &is_empty, i_locator.get_filename());
801  i_locator.add_to_cache(is_empty_hex_, is_empty);
802  return res;
803 }
804 
805 static surface get_scaled_to_hex(const locator& i_locator)
806 {
807  surface img = get_image(i_locator, HEXED);
808  //return scale_surface(img, zoom, zoom);
809 
810  if (!img.null()) {
811  return scale_to_hex_func(img, zoom, zoom);
812  } else {
813  return surface(nullptr);
814  }
815 }
816 
817 static surface get_tod_colored(const locator& i_locator)
818 {
819  surface img = get_image(i_locator, SCALED_TO_HEX);
820  return adjust_surface_color(img, red_adjust, green_adjust, blue_adjust);
821 }
822 
823 static surface get_scaled_to_zoom(const locator& i_locator)
824 {
825  assert(zoom != tile_size);
826  assert(tile_size != 0);
827 
828  surface res(get_image(i_locator, UNSCALED));
829  // For some reason haloes seems to have invalid images, protect against crashing
830  if(!res.null()) {
831  return scale_to_zoom_func(res, ((res.get()->w * zoom) / tile_size), ((res.get()->h * zoom) / tile_size));
832  } else {
833  return surface(nullptr);
834  }
835 }
836 
837 static surface get_brightened(const locator& i_locator)
838 {
839  surface image(get_image(i_locator, TOD_COLORED));
841 }
842 
843 ///translate type to a simpler one when possible
844 static TYPE simplify_type(const image::locator& i_locator, TYPE type){
845  switch(type) {
846  case SCALED_TO_ZOOM:
847  if(zoom == tile_size)
848  type = UNSCALED;
849  break;
850  case BRIGHTENED:
852  type = TOD_COLORED;
853  break;
854  default:
855  break;
856  }
857 
858  if(type == TOD_COLORED) {
859  if (red_adjust==0 && green_adjust==0 && blue_adjust==0)
860  type = SCALED_TO_HEX;
861  }
862 
863  if(type == SCALED_TO_HEX) {
864  if(zoom == tile_size)
865  type = HEXED;
866  }
867 
868  if(type == HEXED) {
869  // check if the image is already hex-cut by the location system
870  if(i_locator.get_loc().valid())
871  type = UNSCALED;
872  }
873 
874  return type;
875 }
876 
877 
879 {
880  surface res;
881 
882  if(i_locator.is_void())
883  return res;
884 
885  type = simplify_type(i_locator, type);
886 
887  image_cache *imap;
888  // select associated cache
889  switch(type) {
890  case UNSCALED:
891  imap = &images_;
892  break;
893  case TOD_COLORED:
894  imap = &tod_colored_images_;
895  break;
896  case SCALED_TO_ZOOM:
897  imap = &scaled_to_zoom_;
898  break;
899  case HEXED:
900  imap = &hexed_images_;
901  break;
902  case SCALED_TO_HEX:
903  imap = &scaled_to_hex_images_;
904  break;
905  case BRIGHTENED:
906  imap = &brightened_images_;
907  break;
908  default:
909  return res;
910  }
911 
912  // return the image if already cached
913  bool tmp;
914 #ifdef _OPENMP
915 #pragma omp critical(image_cache)
916 #endif //_OPENMP
917  tmp=i_locator.in_cache(*imap);
918 
919  if(tmp) {
920  surface result;
921 #ifdef _OPENMP
922 #pragma omp critical(image_cache)
923 #endif //_OPENMP
924  result = i_locator.locate_in_cache(*imap);
925  return result;
926  }
927 
928  // not cached, generate it
929  switch(type) {
930  case UNSCALED:
931  // If type is unscaled, directly load the image from the disk.
932  res = load_from_disk(i_locator);
933  break;
934  case TOD_COLORED:
935  res = get_tod_colored(i_locator);
936  break;
937  case SCALED_TO_ZOOM:
938  res = get_scaled_to_zoom(i_locator);
939  break;
940  case HEXED:
941  res = get_hexed(i_locator);
942  break;
943  case SCALED_TO_HEX:
944  res = get_scaled_to_hex(i_locator);
945  break;
946  case BRIGHTENED:
947  res = get_brightened(i_locator);
948  break;
949  default:
950  return res;
951  }
952 
953  // Optimizes surface before storing it
954  if(res)
955  res = create_optimized_surface(res);
956 
957 #ifdef _OPENMP
958 #pragma omp critical(image_cache)
959 #endif //_OPENMP
960  i_locator.add_to_cache(*imap, res);
961 
962  return res;
963 }
964 
965 #ifdef SDL_GPU
966 sdl::timage get_texture(const locator& loc, TYPE type)
967 {
968  if (loc.is_void()) {
969  return sdl::timage();
970  }
971 
972  texture_cache *cache;
973 
974  switch (type) {
975  case UNSCALED:
976  case SCALED_TO_ZOOM:
977  cache = &txt_images_;
978  break;
979  case BRIGHTENED:
980  cache = &txt_brightened_images_;
981  break;
982  case HEXED:
983  case SCALED_TO_HEX:
984  case TOD_COLORED:
985  cache = &txt_hexed_images_;
986  break;
987  default:
988  return sdl::timage();
989  }
990 
991  if (!loc.in_cache(*cache)) {
992  if (type == UNSCALED || type == SCALED_TO_ZOOM) {
993  sdl::timage txt = load_texture(loc);
994  loc.add_to_cache(*cache, txt);
995  } else if (type == BRIGHTENED) {
996  surface surf = get_brightened(loc);
997  sdl::timage txt(surf);
998  loc.add_to_cache(*cache, txt);
999  } else {
1000  surface surf = get_hexed(loc);
1001  sdl::timage txt(surf);
1002  loc.add_to_cache(*cache, txt);
1003  }
1004  }
1005 
1006  sdl::timage result = loc.locate_in_cache(*cache);
1007 
1008  switch (type) {
1009  case UNSCALED:
1010  case HEXED:
1011  case BRIGHTENED:
1012  break;
1013  case TOD_COLORED:
1014  result.set_color_mod(red_adjust, green_adjust, blue_adjust);
1015  case SCALED_TO_ZOOM:
1016  case SCALED_TO_HEX:
1017  result.set_scale(zoom / 72.0f, zoom / 72.0f);
1018  break;
1019  default:
1020  return sdl::timage();
1021  }
1022 
1023  return result;
1024 }
1025 #endif
1026 
1027 #ifdef SDL_GPU
1028 sdl::timage get_lighted_texture(const locator &i_locator, const light_string &ls, TYPE type)
1029 {
1030  sdl::timage res;
1031  if(i_locator.is_void())
1032  return res;
1033 
1034  // if no light variants yet, need to add an empty map
1035  if(!i_locator.in_cache(lit_textures_)){
1036  i_locator.add_to_cache(lit_textures_, lit_texture_variants());
1037  }
1038 
1039  //need access to add it if not found
1040  { // enclose reference pointing to data stored in a changing vector
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()) {
1044  return lvi->second;
1045  }
1046  }
1047 
1048  // not cached yet, generate it
1049  surface surf = get_image(i_locator, HEXED);
1050  surf = apply_light(surf, ls);
1051 
1052  res = sdl::timage(surf);
1053 
1054  if (type == SCALED_TO_HEX) {
1055  res.set_scale(zoom / 72.0f, zoom / 72.0f);
1056  }
1057  // record the lighted surface in the corresponding variants cache
1058  i_locator.access_in_cache(lit_textures_)[ls] = res;
1059 
1060  return res;
1061 }
1062 #endif
1063 surface get_lighted_image(const image::locator& i_locator, const light_string& ls, TYPE type)
1064 {
1065  surface res;
1066  if(i_locator.is_void())
1067  return res;
1068 
1069  if(type == SCALED_TO_HEX && zoom == tile_size){
1070  type = HEXED;
1071  }
1072 
1073  // select associated cache
1074  lit_cache* imap = &lit_images_;
1075  if(type == SCALED_TO_HEX)
1076  imap = &lit_scaled_images_;
1077 
1078  // if no light variants yet, need to add an empty map
1079  if(!i_locator.in_cache(*imap)){
1080  i_locator.add_to_cache(*imap, lit_variants());
1081  }
1082 
1083  //need access to add it if not found
1084  { // enclose reference pointing to data stored in a changing vector
1085  const lit_variants& lvar = i_locator.locate_in_cache(*imap);
1086  lit_variants::const_iterator lvi = lvar.find(ls);
1087  if(lvi != lvar.end()) {
1088  return lvi->second;
1089  }
1090  }
1091 
1092  // not cached yet, generate it
1093  switch(type) {
1094  case HEXED:
1095  res = get_image(i_locator, HEXED);
1096  res = apply_light(res, ls);
1097  break;
1098  case SCALED_TO_HEX:
1099  //we light before scaling to reuse the unscaled cache
1100  res = get_lighted_image(i_locator, ls, HEXED);
1101  res = scale_surface(res, zoom, zoom);;
1102  break;
1103  default:
1104  ;
1105  }
1106 
1107  // Optimizes surface before storing it
1108  res = create_optimized_surface(res);
1109  // record the lighted surface in the corresponding variants cache
1110  i_locator.access_in_cache(*imap)[ls] = res;
1111 
1112  return res;
1113 }
1114 
1116 {
1118  return get_image(terrain_mask, UNSCALED);
1119 }
1120 
1121 bool is_in_hex(const locator& i_locator)
1122 {
1123  bool result;
1124 #ifdef _OPENMP
1125 #pragma omp critical(in_hex_info_)
1126 #endif //_OPENMP
1127  {
1128  if(i_locator.in_cache(in_hex_info_)) {
1129  result= i_locator.locate_in_cache(in_hex_info_);
1130  } else {
1131  const surface image(get_image(i_locator, UNSCALED));
1132 
1133  bool res = in_mask_surface(image, get_hexmask());
1134 
1135  i_locator.add_to_cache(in_hex_info_, res);
1136 
1137  //std::cout << "in_hex : " << i_locator.get_filename()
1138  // << " " << (res ? "yes" : "no") << "\n";
1139 
1140  result= res;
1141  }
1142  }
1143  return result;
1144 }
1145 
1146 bool is_empty_hex(const locator& i_locator)
1147 {
1148  if(!i_locator.in_cache(is_empty_hex_)) {
1149  const surface surf = get_image(i_locator, HEXED);
1150  // emptiness of terrain image is checked during hex cut
1151  // so, maybe in cache now, let's recheck
1152  if(!i_locator.in_cache(is_empty_hex_)) {
1153  //should never reach here
1154  //but do it manually if it happens
1155  //assert(false);
1156  bool is_empty = false;
1157  mask_surface(surf, get_hexmask(), &is_empty);
1158  i_locator.add_to_cache(is_empty_hex_, is_empty);
1159  }
1160  }
1161  return i_locator.locate_in_cache(is_empty_hex_);
1162 }
1163 
1164 
1166 {
1167  if(surf == nullptr) {
1168  return surface(nullptr);
1169  }
1170 
1171  const std::map<surface,surface>::iterator itor = reversed_images_.find(surf);
1172  if(itor != reversed_images_.end()) {
1173  // sdl_add_ref(itor->second);
1174  return itor->second;
1175  }
1176 
1177  const surface rev(flip_surface(surf));
1178  if(rev == nullptr) {
1179  return surface(nullptr);
1180  }
1181 
1182  reversed_images_.insert(std::pair<surface,surface>(surf,rev));
1183  // sdl_add_ref(rev);
1184  return rev;
1185 }
1186 
1187 bool exists(const image::locator& i_locator)
1188 {
1189  typedef image::locator loc;
1190  loc::type type = i_locator.get_type();
1191  if (type != loc::FILE && type != loc::SUB_FILE)
1192  return false;
1193 
1194  // The insertion will fail if there is already an element in the cache
1196  it = image_existence_map.insert(std::make_pair(i_locator.get_filename(), false));
1197  bool &cache = it.first->second;
1198  if (it.second)
1199  cache = !filesystem::get_binary_file_location("images", i_locator.get_filename()).empty();
1200  return cache;
1201 }
1202 
1203 static void precache_file_existence_internal(const std::string& dir, const std::string& subdir)
1204 {
1205  const std::string checked_dir = dir + "/" + subdir;
1206  if (precached_dirs.find(checked_dir) != precached_dirs.end())
1207  return;
1208  precached_dirs.insert(checked_dir);
1209 
1210  if (!filesystem::is_directory(checked_dir))
1211  return;
1212 
1213  std::vector<std::string> files_found;
1214  std::vector<std::string> dirs_found;
1215  filesystem::get_files_in_dir(checked_dir, &files_found, &dirs_found,
1217 
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;
1221  }
1222 
1223  for(std::vector<std::string>::const_iterator d = dirs_found.begin();
1224  d != dirs_found.end(); ++d) {
1225  precache_file_existence_internal(dir, subdir + *d + "/");
1226  }
1227 }
1228 
1230 {
1231  const std::vector<std::string>& paths = filesystem::get_binary_paths("images");
1232 
1233  for(std::vector<std::string>::const_iterator p = paths.begin();
1234  p != paths.end(); ++p) {
1235 
1237  }
1238 }
1239 
1241 {
1242  std::map<std::string, bool>::const_iterator b = image_existence_map.find(file);
1243  if (b != image_existence_map.end())
1244  return b->second;
1245  else
1246  return false;
1247 }
1248 
1249 bool save_image(const locator & i_locator, const std::string & filename)
1250 {
1251  return save_image(get_image(i_locator), filename);
1252 }
1253 
1254 bool save_image(const surface & surf, const std::string & filename)
1255 {
1256  if (surf.null()) {
1257  return false;
1258  }
1259 #ifdef HAVE_LIBPNG
1260  if (!filesystem::ends_with(filename, ".bmp")) {
1261  LOG_DP << "Writing a png image to " << filename << std::endl;
1262 
1263  surface tmp = SDL_PNGFormatAlpha(surf.get());
1264  //SDL_SavePNG_RW(tmp, filesystem::load_RWops(filename), 1); //1 means to close the file (RWops) when we finish
1265  //^ This doesn't work, load_RWops is only for reading not writing
1266  return SDL_SavePNG(tmp, filename.c_str()) == 0;
1267  }
1268 #endif
1269 
1270  LOG_DP << "Writing a bmp image to " << filename << std::endl;
1271  return SDL_SaveBMP(surf, filename.c_str()) == 0;
1272 }
1273 
1275 {
1276  typedef gui2::tadvanced_graphics_options::SCALING_ALGORITHM SCALING_ALGORITHM;
1277  SCALING_ALGORITHM algo = SCALING_ALGORITHM::LINEAR;
1278  try {
1279  algo = SCALING_ALGORITHM::string_to_enum(preferences::get("scale_hex"));
1280  } catch (bad_enum_cast &) {}
1281 
1282  scale_to_hex_func = select_algorithm(algo);
1283 
1284  algo = SCALING_ALGORITHM::LINEAR;
1285  try {
1286  algo = SCALING_ALGORITHM::string_to_enum(preferences::get("scale_zoom"));
1287  } catch (bad_enum_cast &) {}
1288 
1289  scale_to_zoom_func = select_algorithm(algo);
1290 
1291  return true;
1292 }
1293 
1294 } // end namespace image
1295 
TYPE
UNSCALED : image will be drawn "as is" without changing size, even in case of redraw SCALED_TO_ZOOM :...
Definition: image.hpp:208
static surface load_image_file(const image::locator &loc)
Definition: image.cpp:481
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:878
surface flip_surface(const surface &surf, bool optimize)
Definition: utils.cpp:2108
bool null() const
Definition: utils.hpp:104
void precache_file_existence(const std::string &subdir)
precache the existence of files in the subdir (ex: "terrain/")
Definition: image.cpp:1229
static surface scale_xbrz_helper(const surface &res, int w, int h)
Definition: image.cpp:758
std::map< t_translation::t_terrain, surface > mini_terrain_cache_map
Definition: image.hpp:140
SDL_Surface * get() const
Definition: utils.hpp:98
void set_pixel_format(SDL_PixelFormat *format)
sets the pixel format used by the images.
Definition: image.cpp:666
map_location loc_
Definition: image.hpp:57
bool is_void() const
Definition: image.hpp:96
std::string filename_
Definition: image.hpp:56
value val_
Definition: image.hpp:122
void init_index()
Definition: image.cpp:220
bool operator<(const value &a) const
Definition: image.cpp:353
const GLfloat * c
Definition: glew.h:12741
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...
Definition: image.cpp:722
variant b_
Definition: function.cpp:808
static surface get_scaled_to_hex(const locator &i_locator)
Definition: image.cpp:805
static surface get_hexed(const locator &i_locator)
Definition: image.cpp:795
bool precached_file_exists(const std::string &file)
Definition: image.cpp:1240
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
int get_center_y() const
Definition: image.hpp:89
surface reverse_image(const surface &surf)
function to reverse an image.
Definition: image.cpp:1165
static std::string get_localized_path(const std::string &file, const std::string &suff="")
Definition: image.cpp:430
surface create_optimized_surface(const surface &surf)
Definition: utils.cpp:168
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.
Definition: image.cpp:628
mini_terrain_cache_map mini_fogged_terrain_cache
Definition: image.cpp:186
type get_type() const
Definition: image.hpp:91
cache_item< T > & get_element(int index)
Definition: image.cpp:84
#define val_(o)
Definition: lobject.h:112
friend size_t hash_value(const value &)
Definition: image.cpp:374
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glew.h:3783
static signed char col_to_uchar(int i)
Definition: image.cpp:569
#define LOG_DP
Definition: image.cpp:53
GLuint const GLfloat * val
Definition: glew.h:2614
#define ERR_CFG
Definition: image.cpp:56
bool in_mask_surface(const surface &surf, const surface &mask)
Check if a surface fit into a mask.
Definition: utils.cpp:1349
#define SDL_SavePNG(surface, file)
Definition: savepng.h:16
void add_to_cache(cache_type< T > &cache, const T &data) const
Definition: image.cpp:117
void parse_arguments()
Definition: image.cpp:232
static surface get_scaled_to_zoom(const locator &i_locator)
Definition: image.cpp:823
GLboolean GLboolean g
Definition: glew.h:7319
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)
Definition: utils.cpp:443
#define d
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
cache_type< lit_variants > lit_cache
Definition: image.hpp:156
-file util.hpp
Definitions for the interface to Wesnoth Markup Language (WML).
const map_location & get_loc() const
Definition: image.hpp:87
std::string terrain_mask
Definition: game_config.cpp:84
cache_type< surface > image_cache
Definition: image.hpp:134
GLdouble l
Definition: glew.h:6966
bool save_image(const locator &i_locator, const std::string &filename)
Definition: image.cpp:1249
void flush_cache()
Definition: image.cpp:191
static std::set< std::string > fuzzy_localized_files
Definition: image.cpp:400
std::string filename_
Definition: action_wml.cpp:506
map_location loc_
static scaling_function select_algorithm(gui2::tadvanced_graphics_options::SCALING_ALGORITHM algo)
Definition: image.cpp:765
void blit_surface(const surface &surf, const SDL_Rect *srcrect, surface &dst, const SDL_Rect *dstrect)
Replacement for sdl_blit.
Definition: utils.cpp:2185
std::string & strip(std::string &str)
Remove whitespace from the front and back of the string 'str'.
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
static TYPE simplify_type(const image::locator &i_locator, TYPE type)
translate type to a simpler one when possible
Definition: image.cpp:844
bool exists(const image::locator &i_locator)
returns true if the given image actually exists, without loading it.
Definition: image.cpp:1187
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
surface mask_surface(const surface &surf, const surface &mask, bool *empty_result, const std::string &filename)
Applies a mask on a surface.
Definition: utils.cpp:1279
std::string get(const std::string &key)
bool in_cache(cache_type< T > &cache) const
Definition: image.cpp:97
static surface get_brightened(const locator &i_locator)
Definition: image.cpp:837
GLuint64EXT * result
Definition: glew.h:10727
static surface load_image_sub_file(const image::locator &loc)
Definition: image.cpp:516
static surface get_tod_colored(const locator &i_locator)
Definition: image.cpp:817
light_string get_light_string(int op, int r, int g, int b)
return light_string of one light operation(see above)
Definition: image.cpp:573
bool operator==(const value &a) const
Definition: image.cpp:338
bool valid() const
Definition: location.hpp:69
std::string modifications_
Definition: image.hpp:58
SDL_Surface * SDL_PNGFormatAlpha(SDL_Surface *src)
Definition: savepng.cpp:44
static int last_index_
Definition: image.cpp:189
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
std::string base_name(const std::string &file)
Returns the base filename of a file, with directory name stripped.
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
static SDL_PixelFormat last_pixel_format
Definition: image.cpp:664
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
std::map< light_string, surface > lit_variants
Definition: image.hpp:154
std::string path
surface light_surface(const surface &surf, const surface &lightmap, bool optimize)
Light surf using lightmap.
Definition: utils.cpp:1458
std::vector< cache_item< T > > content_
Definition: image.cpp:93
T & access_in_cache(cache_type< T > &cache) const
Definition: image.cpp:110
Base abstract class for an image-path modification.
GLfloat GLfloat p
Definition: glew.h:12766
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
surf
Definition: filter.cpp:143
static void precache_file_existence_internal(const std::string &dir, const std::string &subdir)
Definition: image.cpp:1203
surface scale_surface_nn(const surface &surf, int w, int h)
Scale a surface using the nearest neighbor algorithm (provided by xBRZ lib)
Definition: utils.cpp:404
const std::string &parameters float amount
Definition: filter.cpp:132
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.
Definition: image.cpp:698
Encapsulates the map of the game.
Definition: location.hpp:38
const std::string & get_filename() const
Definition: image.hpp:86
const std::string & get_modifications() const
Definition: image.hpp:90
surface adjust_surface_color(const surface &surf, int red, int green, int blue, bool optimize)
Definition: utils.cpp:718
surface load_from_disk(const locator &loc)
Definition: image.cpp:633
GLuint res
Definition: glew.h:9258
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
Definition: image.hpp:138
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glew.h:1222
modification * top() const
Returns the top element in the queue .
cache_item()
Definition: image.cpp:63
#define ERR_DP
Definition: image.cpp:52
surface scale_surface_xbrz(const surface &surf, size_t z)
Scale a surface using xBRZ algorithm.
Definition: utils.cpp:366
GLuint index
Definition: glew.h:1782
locator & operator=(const locator &a)
Definition: image.cpp:296
static tcache cache
Definition: minimap.cpp:139
surface get_hexmask()
function to get the standard hex mask
Definition: image.cpp:1115
std::basic_string< signed char > light_string
light_string store colors info of central and adjacent hexes.
Definition: image.hpp:149
size_t hash_value(const locator::value &val)
Definition: image.cpp:374
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:5910
size_t i
Definition: function.cpp:1057
surface brighten_image(const surface &surf, fixed_t amount, bool optimize)
Definition: utils.cpp:1160
mini_terrain_cache_map mini_highlighted_terrain_cache
Definition: image.cpp:187
Declarations for File-IO.
void set_zoom(int amount)
sets the amount scaled images should be scaled.
Definition: image.cpp:736
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
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...
Definition: image.cpp:1121
static bool localized_file_uptodate(const std::string &loc_file)
Definition: image.cpp:401
mini_terrain_cache_map mini_terrain_cache
Definition: image.cpp:185
cache_item(const T &item)
Definition: image.cpp:66
void flush()
Definition: image.cpp:90
surface get_lighted_image(const image::locator &i_locator, const light_string &ls, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:1063
const T & locate_in_cache(cache_type< T > &cache) const
Definition: image.cpp:103
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an empty SDL_Rect.
Definition: rect.cpp:28
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.
const GLdouble * m
Definition: glew.h:6968
#define g
Definition: glew.h:12730
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 ...
Definition: image.cpp:1146
Exception thrown by the operator() when an error occurs.
int get_center_x() const
Definition: image.hpp:88
static void add_localized_overlay(const std::string &ovr_file, surface &orig_surf)
Definition: image.cpp:466
GLint GLvoid * img
Definition: glew.h:1353
surface make_neutral_surface(const surface &surf)
Definition: utils.cpp:135
this module manages the cache of images.
Definition: image.cpp:75
Standard logging facilities (interface).
double hex_brightening
boost::unordered_map< value, int > locator_finder_t
Definition: image.hpp:67
static lg::log_domain log_config("config")
const std::vector< std::string > & get_team_colors()
Definition: image.cpp:731
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.
#define e
void pop()
Removes the top element from the queue.
bool update_from_preferences()
initialize any private data, e.g. algorithm choices from preferences
Definition: image.cpp:1274
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:112
SDL_RWops * load_RWops(const std::string &path)
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
static lg::log_domain log_display("display")
static surface apply_light(surface surf, const light_string &ls)
Definition: image.cpp:583
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.
Definition: utils.cpp:1782
#define ftofxp(x)
IN: float or int - OUT: fixed_t.
Definition: util.hpp:503
GLclampf f
Definition: glew.h:3024
bool loaded
Definition: image.cpp:70