minimap.cpp

Go to the documentation of this file.
00001 /* $Id: minimap.cpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2003 - 2012 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #define GETTEXT_DOMAIN "wesnoth-lib"
00017 
00018 #include "global.hpp"
00019 #include "minimap.hpp"
00020 
00021 #include "gettext.hpp"
00022 #include "image.hpp"
00023 #include "log.hpp"
00024 #include "map.hpp"
00025 #include "sdl_utils.hpp"
00026 
00027 #include "team.hpp"
00028 #include "wml_exception.hpp"
00029 #include "formula_string_utils.hpp"
00030 
00031 static lg::log_domain log_display("display");
00032 #define DBG_DP LOG_STREAM(debug, log_display)
00033 #define WRN_DP LOG_STREAM(warn, log_display)
00034 
00035 
00036 namespace image {
00037 
00038 surface getMinimap(int w, int h, const gamemap &map, const team *vw)
00039 {
00040     const int scale = 8;
00041 
00042     DBG_DP << "creating minimap " << int(map.w()*scale*0.75) << "," << int(map.h()*scale) << "\n";
00043 
00044     const size_t map_width = map.w()*scale*3/4;
00045     const size_t map_height = map.h()*scale;
00046     if(map_width == 0 || map_height == 0) {
00047         return surface(NULL);
00048     }
00049 
00050     surface minimap(create_neutral_surface(map_width, map_height));
00051     if(minimap == NULL)
00052         return surface(NULL);
00053 
00054     typedef mini_terrain_cache_map cache_map;
00055     cache_map *normal_cache = &mini_terrain_cache;
00056     cache_map *fog_cache = &mini_fogged_terrain_cache;
00057 
00058     for(int y = 0; y != map.total_height(); ++y) {
00059         for(int x = 0; x != map.total_width(); ++x) {
00060 
00061             surface surf(NULL);
00062 
00063             const map_location loc(x,y);
00064             if(map.on_board(loc)) {
00065 
00066                 const bool shrouded = (vw != NULL && vw->shrouded(loc));
00067                 // shrouded hex are not considered fogged (no need to fog a black image)
00068                 const bool fogged = (vw != NULL && !shrouded && vw->fogged(loc));
00069                 const t_translation::t_terrain terrain = shrouded ?
00070                         t_translation::VOID_TERRAIN : map[loc];
00071                 const terrain_type& terrain_info = map.get_terrain_info(terrain);
00072 
00073                 bool need_fogging = false;
00074 
00075                 cache_map* cache = fogged ? fog_cache : normal_cache;
00076                 cache_map::iterator i = cache->find(terrain);
00077 
00078                 if (fogged && i == cache->end()) {
00079                     // we don't have the fogged version in cache
00080                     // try the normal cache and ask fogging the image
00081                     cache = normal_cache;
00082                     i = cache->find(terrain);
00083                     need_fogging = true;
00084                 }
00085 
00086                 if(i == cache->end()) {
00087                     std::string base_file =
00088                             "terrain/" + terrain_info.minimap_image() + ".png";
00089                     surface tile = get_image(base_file,image::HEXED);
00090 
00091                     //Compose images of base and overlay if necessary
00092                     // NOTE we also skip overlay when base is missing (to avoid hiding the error)
00093                     if(tile != NULL && map.get_terrain_info(terrain).is_combined()) {
00094                         std::string overlay_file =
00095                                 "terrain/" + terrain_info.minimap_image_overlay() + ".png";
00096                         surface overlay = get_image(overlay_file,image::HEXED);
00097 
00098                         if(overlay != NULL && overlay != tile) {
00099                             surface combined = create_neutral_surface(tile->w, tile->h);
00100                             SDL_Rect r = create_rect(0,0,0,0);
00101                             sdl_blit(tile, NULL, combined, &r);
00102                             r.x = std::max(0, (tile->w - overlay->w)/2);
00103                             r.y = std::max(0, (tile->h - overlay->h)/2);
00104                             //blit_surface needs neutral surface
00105                             surface overlay_neutral = make_neutral_surface(overlay);
00106                             blit_surface(overlay_neutral, NULL, combined, &r);
00107                             tile = combined;
00108                         }
00109                     }
00110 
00111                     surf = scale_surface(tile, scale, scale);
00112 
00113                     i = normal_cache->insert(cache_map::value_type(terrain,surf)).first;
00114                 }
00115 
00116                 surf = i->second;
00117 
00118                 if (need_fogging) {
00119                     surf = adjust_surface_color(surf,-50,-50,-50);
00120                     fog_cache->insert(cache_map::value_type(terrain,surf));
00121                 }
00122 
00123                 // we need a balanced shift up and down of the hexes.
00124                 // if not, only the bottom half-hexes are clipped
00125                 // and it looks asymmetrical.
00126 
00127                 // also do 1-pixel shift because the scaling
00128                 // function seems to do it with its rounding
00129                 SDL_Rect maprect = create_rect(
00130                           x * scale * 3 / 4 - 1
00131                         , y * scale + scale / 4 * (is_odd(x) ? 1 : -1) - 1
00132                         , 0
00133                         , 0);
00134 
00135                 if(surf != NULL)
00136                     sdl_blit(surf, NULL, minimap, &maprect);
00137             }
00138         }
00139     }
00140 
00141     double wratio = w*1.0 / minimap->w;
00142     double hratio = h*1.0 / minimap->h;
00143     double ratio = std::min<double>(wratio, hratio);
00144 
00145     minimap = scale_surface(minimap,
00146         static_cast<int>(minimap->w * ratio), static_cast<int>(minimap->h * ratio));
00147 
00148     DBG_DP << "done generating minimap\n";
00149 
00150     return minimap;
00151 }
00152 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:55 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs