1 // SuperTux
2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 #include "video/surface.hpp"
18
19 #include <sstream>
20
21 #include "util/reader_document.hpp"
22 #include "util/reader_mapping.hpp"
23 #include "util/string_util.hpp"
24 #include "video/texture.hpp"
25 #include "video/texture_manager.hpp"
26 #include "video/video_system.hpp"
27
28 SurfacePtr
from_reader(const ReaderMapping & mapping,const boost::optional<Rect> & rect,const std::string & filename)29 Surface::from_reader(const ReaderMapping& mapping, const boost::optional<Rect>& rect, const std::string& filename)
30 {
31 TexturePtr diffuse_texture;
32 boost::optional<ReaderMapping> diffuse_texture_mapping;
33 if (mapping.get("diffuse-texture", diffuse_texture_mapping))
34 {
35 diffuse_texture = TextureManager::current()->get(*diffuse_texture_mapping, rect);
36 }
37
38 TexturePtr displacement_texture;
39 boost::optional<ReaderMapping> displacement_texture_mapping;
40 if (mapping.get("displacement-texture", displacement_texture_mapping))
41 {
42 displacement_texture = TextureManager::current()->get(*displacement_texture_mapping, rect);
43 }
44
45 Flip flip = NO_FLIP;
46 std::vector<bool> flip_v;
47 if (mapping.get("flip", flip_v))
48 {
49 flip ^= flip_v[0] ? HORIZONTAL_FLIP : NO_FLIP;
50 flip ^= flip_v[1] ? VERTICAL_FLIP : NO_FLIP;
51 }
52
53 auto surface = new Surface(diffuse_texture, displacement_texture, flip, filename);
54 return SurfacePtr(surface);
55 }
56
57 SurfacePtr
from_file(const std::string & filename,const boost::optional<Rect> & rect)58 Surface::from_file(const std::string& filename, const boost::optional<Rect>& rect)
59 {
60 if (StringUtil::has_suffix(filename, ".surface"))
61 {
62 ReaderDocument doc = ReaderDocument::from_file(filename);
63 ReaderObject object = doc.get_root();
64 if (object.get_name() != "supertux-surface")
65 {
66 std::ostringstream msg;
67 msg << filename << ": error: not a 'supertux-surface' file";
68 throw std::runtime_error(msg.str());
69 }
70 else
71 {
72 return Surface::from_reader(object.get_mapping(), rect, filename);
73 }
74 }
75 else
76 {
77 if (rect)
78 {
79 TexturePtr texture = TextureManager::current()->get(filename, *rect);
80 return SurfacePtr(new Surface(texture, TexturePtr(), NO_FLIP, filename));
81 }
82 else
83 {
84 TexturePtr texture = TextureManager::current()->get(filename);
85 return SurfacePtr(new Surface(texture, TexturePtr(), NO_FLIP, filename));
86 }
87 }
88 }
89
Surface(const TexturePtr & diffuse_texture,const TexturePtr & displacement_texture,Flip flip,const std::string & filename)90 Surface::Surface(const TexturePtr& diffuse_texture,
91 const TexturePtr& displacement_texture,
92 Flip flip, const std::string& filename) :
93 m_diffuse_texture(diffuse_texture),
94 m_displacement_texture(displacement_texture),
95 m_region(0, 0, m_diffuse_texture->get_image_width(), m_diffuse_texture->get_image_height()),
96 m_flip(flip),
97 m_source_filename(filename)
98 {
99 }
100
Surface(const TexturePtr & diffuse_texture,const TexturePtr & displacement_texture,const Rect & region,Flip flip,const std::string & filename)101 Surface::Surface(const TexturePtr& diffuse_texture,
102 const TexturePtr& displacement_texture,
103 const Rect& region,
104 Flip flip, const std::string& filename) :
105 m_diffuse_texture(diffuse_texture),
106 m_displacement_texture(displacement_texture),
107 m_region(region),
108 m_flip(flip),
109 m_source_filename(filename)
110 {
111 }
112
113 SurfacePtr
from_texture(const TexturePtr & texture)114 Surface::from_texture(const TexturePtr& texture)
115 {
116 return SurfacePtr(new Surface(texture, TexturePtr(), NO_FLIP));
117 }
118
~Surface()119 Surface::~Surface()
120 {
121 }
122
123 SurfacePtr
clone(Flip flip) const124 Surface::clone(Flip flip) const
125 {
126 SurfacePtr surface(new Surface(m_diffuse_texture,
127 m_displacement_texture,
128 m_region,
129 m_flip ^ flip));
130 return surface;
131 }
132
133 SurfacePtr
region(const Rect & rect) const134 Surface::region(const Rect& rect) const
135 {
136 SurfacePtr surface(new Surface(m_diffuse_texture,
137 m_displacement_texture,
138 rect,
139 m_flip));
140 return surface;
141 }
142
143 TexturePtr
get_texture() const144 Surface::get_texture() const
145 {
146 return m_diffuse_texture;
147 }
148
149 TexturePtr
get_displacement_texture() const150 Surface::get_displacement_texture() const
151 {
152 return m_displacement_texture;
153 }
154
155 int
get_width() const156 Surface::get_width() const
157 {
158 return m_region.get_width();
159 }
160
161 int
get_height() const162 Surface::get_height() const
163 {
164 return m_region.get_height();
165 }
166
167 /* EOF */
168