Initial integration, lots of broken stuff
[supertux.git] / src / unison / src / video / Texture.cpp
1 //          Copyright Timothy Goya 2007.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <unison/video/Texture.hpp>
7 #include <unison/video/backend/Texture.hpp>
8
9 #include <assert.h>
10
11 namespace Unison
12 {
13    namespace Video
14    {
15       std::set<Texture *> Texture::textures = std::set<Texture*>();
16
17       Texture::Texture() :
18          id(INVALID_TEXTURE_ID)
19       {
20       }
21
22       Texture::Texture(const std::string &filename) :
23          id(Backend::Texture::get_texture_id(filename))
24       {
25          assert(id != INVALID_TEXTURE_ID);
26          Backend::Texture::get_texture(id)->ref();
27          textures.insert(this);
28       }
29
30       Texture::Texture(const std::string &filename, const Color &colorkey) :
31          id(Backend::Texture::get_texture_id(filename, colorkey))
32       {
33          assert(id != INVALID_TEXTURE_ID);
34          Backend::Texture::get_texture(id)->ref();
35          textures.insert(this);
36       }
37
38       Texture::Texture(const Surface &surface) :
39          id(Backend::Texture::get_texture_id(surface))
40       {
41          assert(id != INVALID_TEXTURE_ID);
42          Backend::Texture::get_texture(id)->ref();
43          textures.insert(this);
44       }
45
46       Texture::Texture(const Texture &rhs) :
47          Blittable(),
48          id(rhs.id)
49       {
50          if(id != INVALID_TEXTURE_ID)
51          {
52             Backend::Texture::get_texture(id)->ref();
53          }
54          textures.insert(this);
55       }
56
57       Texture::~Texture()
58       {
59          textures.erase(this);
60          if(id != INVALID_TEXTURE_ID)
61          {
62             Backend::Texture::get_texture(id)->unref();
63          }
64       }
65
66       Texture &Texture::operator =(const Texture &rhs)
67       {
68          if(rhs.id != INVALID_TEXTURE_ID)
69          {
70             Backend::Texture::get_texture(rhs.id)->ref();
71          }
72          if(id != INVALID_TEXTURE_ID)
73          {
74             Backend::Texture::get_texture(id)->unref();
75          }
76          id = rhs.id;
77          return *this;
78       }
79
80       TextureID Texture::get_id() const
81       {
82          return id;
83       }
84
85       Area Texture::get_size() const
86       {
87          assert(id != INVALID_TEXTURE_ID);
88          return Backend::Texture::get_texture(id)->get_size();
89       }
90
91       void Texture::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
92       {
93          assert(id != INVALID_TEXTURE_ID);
94          cow();
95          Backend::Texture::get_texture(id)->blit(src, dst_pos, src_rect, options);
96       }
97
98       void Texture::blit(const Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
99       {
100          assert(id != INVALID_TEXTURE_ID);
101          cow();
102          Backend::Texture::get_texture(id)->blit(src, dst_pos, src_rect, options);
103       }
104
105       void Texture::fill(const Color &color, const Rect &rect)
106       {
107          assert(id != INVALID_TEXTURE_ID);
108          cow();
109          Backend::Texture::get_texture(id)->fill(color, rect);
110       }
111
112       void Texture::fill_blend(const Color &color, const Rect &rect)
113       {
114          assert(id != INVALID_TEXTURE_ID);
115          cow();
116          Backend::Texture::get_texture(id)->fill_blend(color, rect);
117       }
118
119       std::vector<Surface> Texture::save_textures()
120       {
121          recover_texture_ids();
122          return Backend::Texture::save_textures();
123       }
124
125       namespace
126       {
127          void ref(Texture *texture)
128          {
129             assert(texture);
130             TextureID id = texture->get_id();
131             if(id != INVALID_TEXTURE_ID)
132             {
133                Backend::Texture::get_texture(id)->ref();
134             }
135          }
136       }
137
138       void Texture::load_textures(const std::vector<Surface> &surfaces)
139       {
140          Backend::Texture::load_textures(surfaces);
141          std::for_each(textures.begin(), textures.end(), ref);
142       }
143
144       void Texture::recover_texture_ids()
145       {
146          std::map<TextureID, TextureID> change_map = Backend::Texture::recover_texture_ids();
147          if(!change_map.empty())
148          {
149             for(std::set<Texture *>::iterator iter = textures.begin(), end = textures.end();iter != end;++iter)
150             {
151                if(change_map.find((*iter)->id) != change_map.end())
152                {
153                   (*iter)->id = change_map[(*iter)->id];
154                }
155             }
156          }
157       }
158
159       void Texture::cow()
160       {
161          assert(id != INVALID_TEXTURE_ID);
162          if(Backend::Texture::get_texture(id)->get_refcount() > 1)
163          {
164             TextureID old = id;
165             id = Backend::Texture::get_texture_id(Backend::Texture::get_texture(id)->get_surface());
166             assert(id != INVALID_TEXTURE_ID);
167             Backend::Texture::get_texture(id)->ref();
168             Backend::Texture::get_texture(old)->unref();
169          }
170       }
171    }
172 }