The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
exploder_cutter.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004 - 2016 by Philippe Plantier <[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 #include "exploder_cutter.hpp"
16 #include "filesystem.hpp"
17 #include "sdl/rect.hpp"
18 #include "serialization/parser.hpp"
21 #include <SDL_image.h>
22 
23 #include <iostream>
24 
26  : masks_()
27  , verbose_(false)
28 {
29 }
30 
31 const config cutter::load_config(const std::string &filename)
32 {
33  const std::string conf_string = find_configuration(filename);
34 
35  config res;
36 
37  try {
39  read(res, *stream);
40  } catch(config::error& err) {
41  throw exploder_failure("Unable to load the configuration for the file " + filename + ": "+ err.message);
42  }
43 
44  return res;
45 }
46 
47 
48 void cutter::load_masks(const config& conf)
49 {
50  for(const config &m : conf.child_range("mask"))
51  {
52  const std::string name = m["name"];
53  const std::string image = get_mask_dir() + "/" + std::string(m["image"]);
54 
55  if(verbose_) {
56  std::cerr << "Adding mask " << name << "\n";
57  }
58 
59  if(image.empty())
60  throw exploder_failure("Missing image for mask " + name);
61 
62  const exploder_point shift(m["shift"]);
63  const exploder_rect cut(m["cut"]);
64 
65  if(masks_.find(name) != masks_.end() && masks_[name].filename != image) {
66  throw exploder_failure("Mask " + name +
67  " correspond to two different files: " +
68  name + " and " +
69  masks_.find(name)->second.filename);
70  }
71 
72  if(masks_.find(name) == masks_.end()) {
73  mask& cur_mask = masks_[name];
74 
75  cur_mask.name = name;
76  cur_mask.shift = shift;
77  cur_mask.cut = cut;
78  cur_mask.filename = image;
79  surface tmp(IMG_Load(image.c_str()));
80  if(tmp == nullptr)
81  throw exploder_failure("Unable to load mask image " + image);
82 
83  cur_mask.image = make_neutral_surface(tmp);
84  }
85 
86  if(masks_[name].image == nullptr)
87  throw exploder_failure("Unable to load mask image " + image);
88  }
89 }
90 
91 
93 {
95 
96  for(const config &part : conf.child_range("part")) {
97  add_sub_image(surf, res, &part);
98  }
99 
100  return res;
101 }
102 
103 
105 {
106  //finds the file prefix.
107  const std::string fname = filesystem::base_name(file);
108  const std::string::size_type dotpos = fname.rfind('.');
109 
110  std::string basename;
111  if(dotpos == std::string::npos) {
112  basename = fname;
113  } else {
114  basename = fname.substr(0, dotpos);
115  }
116 
117  return get_exploder_dir() + "/" + basename + ".cfg";
118 }
119 
120 
122 {
123  const std::string name = (*config)["name"];
124  if(name.empty())
125  throw exploder_failure("Un-named sub-image");
126 
127  if(masks_.find(name) == masks_.end())
128  throw exploder_failure("Unable to find mask corresponding to " + name);
129 
130  const cutter::mask& mask = masks_[name];
131 
132  std::vector<std::string> pos = utils::split((*config)["pos"]);
133  if(pos.size() != 2)
134  throw exploder_failure("Invalid position " + (*config)["pos"].str());
135 
136  int x = atoi(pos[0].c_str());
137  int y = atoi(pos[1].c_str());
138 
139  const SDL_Rect cut = sdl::create_rect(x - mask.shift.x
140  , y - mask.shift.y
141  , mask.image->w
142  , mask.image->h);
143 
144  typedef std::pair<std::string, positioned_surface> sme;
145 
147  ps.image = ::cut_surface(surf, cut);
148  if(ps.image == nullptr)
149  throw exploder_failure("Unable to cut surface!");
150  ps.name = name;
151  ps.mask = mask;
152  ps.pos.x = x - mask.shift.x;
153  ps.pos.y = y - mask.shift.y;
154  map.insert(sme(name, ps));
155 
156  if(verbose_) {
157  std::cerr << "Extracting sub-image " << name << ", position (" << x << ", " << y << ")\n";
158  }
159 }
160 
162 {
163  verbose_ = value;
164 }
165 
void set_verbose(bool value)
child_itors child_range(const std::string &key)
Definition: config.cpp:613
int pos
Definition: formula.cpp:800
surface_map cut_surface(surface surf, const config &conf)
std::string name
void add_sub_image(const surface &surf, surface_map &map, const config *config)
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glew.h:3783
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
std::multimap< std::string, positioned_surface > surface_map
std::string find_configuration(const std::string &file)
const config load_config(const std::string &filename)
exploder_rect cut
GLuint GLuint stream
Definition: glew.h:5239
std::string get_exploder_dir()
GLsizei const GLfloat * value
Definition: glew.h:1817
std::string base_name(const std::string &file)
Returns the base filename of a file, with directory name stripped.
surf
Definition: filter.cpp:143
GLuint res
Definition: glew.h:9258
logger & err()
Definition: log.cpp:79
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
Declarations for File-IO.
void read(config &cfg, std::istream &in, abstract_validator *validator)
Definition: parser.cpp:400
GLuint const GLchar * name
Definition: glew.h:1782
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
std::istream * preprocess_file(std::string const &fname, preproc_map *defines)
mask_map masks_
Contains the SDL_Rect helper code.
const GLdouble * m
Definition: glew.h:6968
surface make_neutral_surface(const surface &surf)
Definition: utils.cpp:135
this module manages the cache of images.
Definition: image.cpp:75
std::string message
Definition: exceptions.hpp:29
std::string filename
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 mask(n)
Definition: lbitlib.cpp:28
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
exploder_point shift
std::string get_mask_dir()
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void load_masks(const config &conf)