tools/exploder_cutter.cpp

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

Generated by doxygen 1.7.1 on Thu May 24 2012 01:02:54 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs