minimap.cpp

Go to the documentation of this file.
00001 /* $Id: minimap.cpp 26214 2008-04-28 17:07:38Z mog $ */
00002 /*
00003    Copyright (C) 2003 - 2008 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 version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 #include "global.hpp"
00016 
00017 #include "gettext.hpp"
00018 #include "image.hpp"
00019 #include "log.hpp"
00020 #include "minimap.hpp"
00021 #include "team.hpp"
00022 #include "wml_exception.hpp"
00023 
00024 #define DBG_DP LOG_STREAM(debug, display)
00025 
00026 namespace image {
00027 
00028 surface getMinimap(int w, int h, const gamemap& map, const viewpoint* vw)
00029 {
00030     const int scale = 8;
00031 
00032     DBG_DP << "creating minimap " << int(map.w()*scale*0.75) << "," << int(map.h()*scale) << "\n";
00033 
00034     const size_t map_width = map.w()*scale*3/4;
00035     const size_t map_height = map.h()*scale;
00036     if(map_width == 0 || map_height == 0) {
00037         return surface(NULL);
00038     }
00039 
00040     surface minimap(SDL_CreateRGBSurface(SDL_SWSURFACE,
00041                                    map_width,map_height,
00042                                    pixel_format->BitsPerPixel,
00043                                    pixel_format->Rmask,
00044                                    pixel_format->Gmask,
00045                                    pixel_format->Bmask,
00046                                    pixel_format->Amask));
00047     if(minimap == NULL)
00048         return surface(NULL);
00049 
00050     typedef mini_terrain_cache_map cache_map;
00051     cache_map *normal_cache = &mini_terrain_cache;
00052     cache_map *fog_cache = &mini_fogged_terrain_cache;
00053 
00054     for(int y = 0; y != map.total_height(); ++y) {
00055         for(int x = 0; x != map.total_width(); ++x) {
00056 
00057             surface surf(NULL);
00058 
00059             const gamemap::location loc(x,y);
00060             if(map.on_board(loc)) {
00061                 const bool shrouded = vw != NULL && vw->shrouded(loc);
00062                 // shrouded hex are not considered fogged (no need to fog a black image)
00063                 const bool fogged = vw != NULL && !shrouded && vw->fogged(loc);
00064                 const t_translation::t_terrain terrain = shrouded ? 
00065                     t_translation::VOID_TERRAIN : map[loc];
00066 
00067                 bool need_fogging = false;
00068 
00069                 cache_map* cache = fogged ? fog_cache : normal_cache;
00070                 cache_map::iterator i = cache->find(terrain);
00071 
00072                 if (fogged && i == cache->end()) {
00073                     // we don't have the fogged version in cache
00074                     // try the normal cache and ask fogging the image
00075                     cache = normal_cache;
00076                     i = cache->find(terrain);
00077                     need_fogging = true;
00078                 }
00079 
00080                 if(i == cache->end()) {
00081                     surface tile(get_image("terrain/" + map.get_terrain_info(terrain).minimap_image() + ".png",image::HEXED));
00082 
00083                     if(tile == 0) {
00084                         utils::string_map symbols;
00085                         symbols["terrain"] = t_translation::write_terrain_code(terrain);
00086                         const std::string msg = 
00087                             vgettext("Could not get image for terrain: $terrain.", symbols);
00088                         VALIDATE(false, msg);
00089                     }
00090 
00091                     //Compose images of base and overlay if neccessary
00092                     if(map.get_terrain_info(terrain).is_combined()) {
00093                         surface overlay(get_image("terrain/" + map.get_terrain_info(terrain).minimap_image_overlay() + ".png",image::HEXED));
00094                         if(overlay != 0) {
00095                             surface combined = create_compatible_surface(tile, tile->w, tile->h);
00096 
00097                             SDL_Rect r;
00098                             r.x = 0;
00099                             r.y = 0;
00100                             SDL_BlitSurface(tile, NULL, combined, &r);
00101                             r.x = maximum(0, (tile->w - overlay->w)/2);
00102                             r.y = maximum(0, (tile->h - overlay->h)/2);
00103                             blit_surface(overlay, NULL, combined, &r);
00104                             tile = combined;
00105                         }
00106 
00107                     }
00108 
00109                     surf = surface(scale_surface_blended(tile,scale,scale));
00110 
00111                     VALIDATE(surf != NULL, _("Error creating or aquiring an image."));
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 = surface(adjust_surface_colour(surf,-50,-50,-50));
00120                     fog_cache->insert(cache_map::value_type(terrain,surf));
00121                 }
00122 
00123                 VALIDATE(surf != NULL, _("Error creating or aquiring an image."));
00124 
00125                 // we need a balanced shift up and down of the hexes.
00126                 // if not, only the bottom half-hexes are clipped
00127                 // and it looks asymmetrical.
00128 
00129                 // also do 1-pixel shift because the scaling
00130                 // function seems to do it with its rounding
00131                 SDL_Rect maprect = {x * scale*3/4 - 1,
00132                     y*scale + scale/4 * (is_odd(x) ? 1 : -1) - 1,
00133                     0, 0};
00134                 SDL_BlitSurface(surf, NULL, minimap, &maprect);
00135             }
00136         }
00137     }
00138 
00139     double wratio = w*1.0 / minimap->w;
00140     double hratio = h*1.0 / minimap->h;
00141     double ratio = minimum<double>(wratio, hratio);
00142     
00143     minimap = scale_surface(minimap,
00144         static_cast<int>(minimap->w * ratio), static_cast<int>(minimap->h * ratio));
00145 
00146     DBG_DP << "done generating minimap\n";
00147 
00148     return minimap;
00149 }
00150 }

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs