Initial integration, lots of broken stuff
[supertux.git] / src / unison / src / video / Texture.cpp
diff --git a/src/unison/src/video/Texture.cpp b/src/unison/src/video/Texture.cpp
new file mode 100644 (file)
index 0000000..ac26976
--- /dev/null
@@ -0,0 +1,172 @@
+//          Copyright Timothy Goya 2007.
+// Distributed under the Boost Software License, Version 1.0.
+//    (See accompanying file LICENSE_1_0.txt or copy at
+//          http://www.boost.org/LICENSE_1_0.txt)
+
+#include <unison/video/Texture.hpp>
+#include <unison/video/backend/Texture.hpp>
+
+#include <assert.h>
+
+namespace Unison
+{
+   namespace Video
+   {
+      std::set<Texture *> Texture::textures = std::set<Texture*>();
+
+      Texture::Texture() :
+         id(INVALID_TEXTURE_ID)
+      {
+      }
+
+      Texture::Texture(const std::string &filename) :
+         id(Backend::Texture::get_texture_id(filename))
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         Backend::Texture::get_texture(id)->ref();
+         textures.insert(this);
+      }
+
+      Texture::Texture(const std::string &filename, const Color &colorkey) :
+         id(Backend::Texture::get_texture_id(filename, colorkey))
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         Backend::Texture::get_texture(id)->ref();
+         textures.insert(this);
+      }
+
+      Texture::Texture(const Surface &surface) :
+         id(Backend::Texture::get_texture_id(surface))
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         Backend::Texture::get_texture(id)->ref();
+         textures.insert(this);
+      }
+
+      Texture::Texture(const Texture &rhs) :
+         Blittable(),
+         id(rhs.id)
+      {
+         if(id != INVALID_TEXTURE_ID)
+         {
+            Backend::Texture::get_texture(id)->ref();
+         }
+         textures.insert(this);
+      }
+
+      Texture::~Texture()
+      {
+         textures.erase(this);
+         if(id != INVALID_TEXTURE_ID)
+         {
+            Backend::Texture::get_texture(id)->unref();
+         }
+      }
+
+      Texture &Texture::operator =(const Texture &rhs)
+      {
+         if(rhs.id != INVALID_TEXTURE_ID)
+         {
+            Backend::Texture::get_texture(rhs.id)->ref();
+         }
+         if(id != INVALID_TEXTURE_ID)
+         {
+            Backend::Texture::get_texture(id)->unref();
+         }
+         id = rhs.id;
+         return *this;
+      }
+
+      TextureID Texture::get_id() const
+      {
+         return id;
+      }
+
+      Area Texture::get_size() const
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         return Backend::Texture::get_texture(id)->get_size();
+      }
+
+      void Texture::blit(const Surface &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         cow();
+         Backend::Texture::get_texture(id)->blit(src, dst_pos, src_rect, options);
+      }
+
+      void Texture::blit(const Texture &src, const Point &dst_pos, const Rect &src_rect, const RenderOptions &options)
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         cow();
+         Backend::Texture::get_texture(id)->blit(src, dst_pos, src_rect, options);
+      }
+
+      void Texture::fill(const Color &color, const Rect &rect)
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         cow();
+         Backend::Texture::get_texture(id)->fill(color, rect);
+      }
+
+      void Texture::fill_blend(const Color &color, const Rect &rect)
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         cow();
+         Backend::Texture::get_texture(id)->fill_blend(color, rect);
+      }
+
+      std::vector<Surface> Texture::save_textures()
+      {
+         recover_texture_ids();
+         return Backend::Texture::save_textures();
+      }
+
+      namespace
+      {
+         void ref(Texture *texture)
+         {
+            assert(texture);
+            TextureID id = texture->get_id();
+            if(id != INVALID_TEXTURE_ID)
+            {
+               Backend::Texture::get_texture(id)->ref();
+            }
+         }
+      }
+
+      void Texture::load_textures(const std::vector<Surface> &surfaces)
+      {
+         Backend::Texture::load_textures(surfaces);
+         std::for_each(textures.begin(), textures.end(), ref);
+      }
+
+      void Texture::recover_texture_ids()
+      {
+         std::map<TextureID, TextureID> change_map = Backend::Texture::recover_texture_ids();
+         if(!change_map.empty())
+         {
+            for(std::set<Texture *>::iterator iter = textures.begin(), end = textures.end();iter != end;++iter)
+            {
+               if(change_map.find((*iter)->id) != change_map.end())
+               {
+                  (*iter)->id = change_map[(*iter)->id];
+               }
+            }
+         }
+      }
+
+      void Texture::cow()
+      {
+         assert(id != INVALID_TEXTURE_ID);
+         if(Backend::Texture::get_texture(id)->get_refcount() > 1)
+         {
+            TextureID old = id;
+            id = Backend::Texture::get_texture_id(Backend::Texture::get_texture(id)->get_surface());
+            assert(id != INVALID_TEXTURE_ID);
+            Backend::Texture::get_texture(id)->ref();
+            Backend::Texture::get_texture(old)->unref();
+         }
+      }
+   }
+}