exploder_cutter.cpp

Go to the documentation of this file.
00001 /* $Id: exploder_cutter.cpp 23842 2008-02-16 08:47:16Z mordante $ */
00002 /*
00003    Copyright (C) 2004 - 2008 by Philippe Plantier <ayin@anathas.org>
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 "exploder_cutter.hpp"
00016 #include "filesystem.hpp"
00017 #include "sdl_utils.hpp"
00018 #include "serialization/parser.hpp"
00019 #include "serialization/preprocessor.hpp"
00020 #include "serialization/string_utils.hpp"
00021 #include "SDL_image.h"
00022 
00023 cutter::cutter() : verbose_(false)
00024 {
00025 
00026 }
00027 
00028 const config cutter::load_config(const std::string &filename)
00029 {
00030     const std::string conf_string = find_configuration(filename);
00031 
00032     config res;
00033 
00034     try {
00035         scoped_istream stream = preprocess_file(conf_string);
00036         read(res, *stream);
00037     } catch(config::error err) {
00038         throw exploder_failure("Unable to load the configuration for the file " + filename + ": "+ err.message);
00039     }
00040 
00041     return res;
00042 }
00043 
00044 
00045 void cutter::load_masks(const config& conf)
00046 {
00047     const config::child_list& masks = conf.get_children("mask");
00048 
00049     for(config::child_list::const_iterator itor = masks.begin();
00050                itor != masks.end(); ++itor) {
00051 
00052         const std::string name = (**itor)["name"];
00053         const std::string image = get_mask_dir() + "/" + (**itor)["image"];
00054 
00055         if(verbose_) {
00056             std::cerr << "Adding mask " << name << "\n";
00057         }
00058 
00059         if(image.empty())
00060             throw exploder_failure("Missing image for mask " + name);
00061 
00062         const exploder_point shift((**itor)["shift"]);
00063         const exploder_rect cut((**itor)["cut"]);
00064 
00065         if(masks_.find(name) != masks_.end() && masks_[name].filename != image) {
00066             throw exploder_failure("Mask " + name +
00067                     " correspond to two different files: " +
00068                     name + " and " +
00069                     masks_.find(name)->second.filename);
00070         }
00071 
00072         if(masks_.find(name) == masks_.end()) {
00073             mask& cur_mask = masks_[name];
00074 
00075             cur_mask.name = name;
00076             cur_mask.shift = shift;
00077             cur_mask.cut = cut;
00078             cur_mask.filename = image;
00079             surface tmp(IMG_Load(image.c_str()));
00080             if(tmp == NULL)
00081                 throw exploder_failure("Unable to load mask image " + image);
00082 
00083             cur_mask.image = surface(make_neutral_surface(tmp));
00084         }
00085 
00086         if(masks_[name].image == NULL)
00087             throw exploder_failure("Unable to load mask image " + image);
00088     }
00089 }
00090 
00091 
00092 cutter::surface_map cutter::cut_surface(surface surf, const config& conf)
00093 {
00094     surface_map res;
00095 
00096     const config::child_list& config_parts = conf.get_children("part");
00097     config::child_list::const_iterator itor;
00098 
00099     for(itor = config_parts.begin(); itor != config_parts.end(); ++itor) {
00100         add_sub_image(surf, res, *itor);
00101     }
00102 
00103     return res;
00104 }
00105 
00106 
00107 std::string cutter::find_configuration(const std::string &file)
00108 {
00109     //finds the file prefix.
00110     const std::string fname = file_name(file);
00111     const std::string::size_type dotpos = fname.rfind('.');
00112 
00113     std::string basename;
00114     if(dotpos == std::string::npos) {
00115         basename = fname;
00116     } else {
00117         basename = fname.substr(0, dotpos);
00118     }
00119 
00120     return get_exploder_dir() + "/" + basename + ".cfg";
00121 }
00122 
00123 
00124 void cutter::add_sub_image(const surface &surf, surface_map &map, const config* config)
00125 {
00126     const std::string name = (*config)["name"];
00127     if(name.empty())
00128         throw exploder_failure("Un-named sub-image");
00129 
00130     if(masks_.find(name) == masks_.end())
00131         throw exploder_failure("Unable to find mask corresponding to " + name);
00132 
00133     const cutter::mask& mask = masks_[name];
00134 
00135     std::vector<std::string> pos = utils::split((*config)["pos"]);
00136     if(pos.size() != 2)
00137         throw exploder_failure("Invalid position " + (*config)["pos"]);
00138 
00139     int x = atoi(pos[0].c_str());
00140     int y = atoi(pos[1].c_str());
00141 
00142     const SDL_Rect cut = {x - mask.shift.x, y - mask.shift.y, mask.image->w, mask.image->h};
00143 
00144     typedef std::pair<std::string, positioned_surface> sme;
00145 
00146     positioned_surface ps;
00147     ps.image = surface(::cut_surface(surf, cut));
00148     if(ps.image == NULL)
00149         throw exploder_failure("Unable to cut surface!");
00150     ps.name = name;
00151     ps.mask = mask;
00152     ps.pos.x = x - mask.shift.x;
00153     ps.pos.y = y - mask.shift.y;
00154     map.insert(sme(name, ps));
00155 
00156     if(verbose_) {
00157         std::cerr << "Extracting sub-image " << name << ", position (" << x << ", " << y << ")\n";
00158     }
00159 }
00160 
00161 void cutter::set_verbose(bool value)
00162 {
00163     verbose_ = value;
00164 }
00165 

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