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