pingus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pingus-CVS] r3148 - in trunk/pingus/src: . editor math


From: grumbel at BerliOS
Subject: [Pingus-CVS] r3148 - in trunk/pingus/src: . editor math
Date: Sat, 15 Sep 2007 02:59:41 +0200

Author: grumbel
Date: 2007-09-15 02:59:40 +0200 (Sat, 15 Sep 2007)
New Revision: 3148

Modified:
   trunk/pingus/src/blitter.cpp
   trunk/pingus/src/blitter.hpp
   trunk/pingus/src/blitter_impl.hpp
   trunk/pingus/src/editor/level_objs.cpp
   trunk/pingus/src/math/vector2i.cpp
   trunk/pingus/src/math/vector2i.hpp
   trunk/pingus/src/resource.cpp
   trunk/pingus/src/resource.hpp
   trunk/pingus/src/sprite.cpp
   trunk/pingus/src/sprite.hpp
   trunk/pingus/src/surface.cpp
   trunk/pingus/src/surface.hpp
Log:
- moved a bunch of stuff from Sprite to the Surface class

Modified: trunk/pingus/src/blitter.cpp
===================================================================
--- trunk/pingus/src/blitter.cpp        2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/blitter.cpp        2007-09-15 00:59:40 UTC (rev 3148)
@@ -238,4 +238,28 @@
                               );
 }
 
+SDL_Surface*
+Blitter::create_surface_from_format(SDL_Surface* surface, int w, int h)
+{
+  Uint32 flags = 0;
+  if (surface->flags & SDL_SWSURFACE)
+    flags |= SDL_SWSURFACE;
+
+  if (surface->flags & SDL_HWSURFACE)
+    flags |= SDL_HWSURFACE;
+
+  if (surface->flags & SDL_SRCCOLORKEY)
+    flags |= SDL_SRCCOLORKEY;
+
+  if (surface->flags & SDL_SRCALPHA)
+    flags |= SDL_SRCALPHA;
+
+  return SDL_CreateRGBSurface(flags, w, h,
+                              surface->format->BitsPerPixel, 
+                              surface->format->Rmask,
+                              surface->format->Gmask,
+                              surface->format->Bmask,
+                              surface->format->Amask);
+}
+
 /* EOF */

Modified: trunk/pingus/src/blitter.hpp
===================================================================
--- trunk/pingus/src/blitter.hpp        2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/blitter.hpp        2007-09-15 00:59:40 UTC (rev 3148)
@@ -35,6 +35,7 @@
 public:
   static SDL_Surface* create_surface_rgba(int w, int h);
   static SDL_Surface* create_surface_rgb(int w, int h);
+  static SDL_Surface* create_surface_from_format(SDL_Surface* surface, int w, 
int h);
 
   /** Flip a surface horizontal */
   static Surface flip_horizontal (Surface sur);

Modified: trunk/pingus/src/blitter_impl.hpp
===================================================================
--- trunk/pingus/src/blitter_impl.hpp   2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/blitter_impl.hpp   2007-09-15 00:59:40 UTC (rev 3148)
@@ -25,9 +25,8 @@
 #include "pingus.hpp"
 
 /** A collection of helper functions for the blitter class */
-namespace BlitterImpl
-{
-
+namespace BlitterImpl {
+
 /** Rotate a surface 90 degree */
 struct transform_rot90
 {
@@ -206,13 +205,13 @@
     }
   else
     {
-      std::cout << "Error: Blitter::modify: Unsupported PixelFormat: "
+      std::cout << "Error: Blitter::modify: Unsupported PixelFormat: 
BytesPerPixel: "
                 << int(source->format->BytesPerPixel) << std::endl;
       SDL_UnlockSurface(source);
-      return source_buffer;
+      return source_buffer.clone();
     }
 }
-
+
 } // namespace BlitterImpl
 
 #endif

Modified: trunk/pingus/src/editor/level_objs.cpp
===================================================================
--- trunk/pingus/src/editor/level_objs.cpp      2007-09-14 19:13:17 UTC (rev 
3147)
+++ trunk/pingus/src/editor/level_objs.cpp      2007-09-15 00:59:40 UTC (rev 
3148)
@@ -159,6 +159,7 @@
   if (attribs & HAS_SURFACE)
     {
       sprite = Resource::load_sprite(desc);
+      
 #if 0                          
       Surface pb;
 
@@ -219,6 +220,7 @@
   // Set modifier
   if (attribs & CAN_ROTATE)
     desc.modifier = modifier;
+
   refresh_sprite();  
 }
 

Modified: trunk/pingus/src/math/vector2i.cpp
===================================================================
--- trunk/pingus/src/math/vector2i.cpp  2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/math/vector2i.cpp  2007-09-15 00:59:40 UTC (rev 3148)
@@ -66,4 +66,10 @@
   return *this;
 }
 
+bool
+Vector2i::operator== (const Vector2i& other)
+{
+  return (other.x == x && other.y == y);
+}
+
 /* EOF */

Modified: trunk/pingus/src/math/vector2i.hpp
===================================================================
--- trunk/pingus/src/math/vector2i.hpp  2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/math/vector2i.hpp  2007-09-15 00:59:40 UTC (rev 3148)
@@ -46,6 +46,8 @@
   Vector2i& operator+= (const Vector2i& add);
   Vector2i& operator-= (const Vector2i& sub);
   Vector2i& operator*= (int mul);
+
+  bool operator== (const Vector2i& other);
 };
 
 #endif

Modified: trunk/pingus/src/resource.cpp
===================================================================
--- trunk/pingus/src/resource.cpp       2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/resource.cpp       2007-09-15 00:59:40 UTC (rev 3148)
@@ -101,54 +101,15 @@
 }
 
 Sprite
-Resource::load_sprite(const ResDescriptor& desc)
+Resource::load_sprite(const ResDescriptor& res)
 {
-  if (desc.modifier == ResourceModifierNS::ROT0)
-    {
-      return load_sprite(desc.res_name);
-    }
+ SpriteDescription* desc = resmgr.get_sprite_description(res.res_name);
+  if (desc)
+    return Sprite(*desc, res.modifier);
   else
-    {
-      // FIXME: Add code to apply the modifier
-      return load_sprite(desc.res_name);
-    }
+    return Sprite();
 }
 
-Surface
-Resource::apply_modifier_to_surface(Surface prov, const ResDescriptor& desc)
-{
-  switch (desc.modifier)
-    {
-    case ResourceModifierNS::ROT0:
-      return prov;
-
-    case ResourceModifierNS::ROT90:
-      return Blitter::rotate_90(prov);
-
-    case ResourceModifierNS::ROT180:
-      return Blitter::rotate_180(prov);
-
-    case ResourceModifierNS::ROT270:
-      return Blitter::rotate_270(prov);
-
-    case ResourceModifierNS::ROT0FLIP:
-      return Blitter::flip_horizontal(prov);
-
-    case ResourceModifierNS::ROT90FLIP:
-      return Blitter::rotate_90_flip(prov);
-
-    case ResourceModifierNS::ROT180FLIP:
-      return Blitter::rotate_180_flip(prov);
-
-    case ResourceModifierNS::ROT270FLIP:
-      return Blitter::rotate_270_flip(prov);
-
-    default:
-      perr << "Resource: Unhandled modifier: " << desc.modifier << std::endl;
-      return prov;
-    }
-}
-
 Sprite
 Resource::load_sprite(const std::string& res_name)
 {
@@ -157,16 +118,6 @@
     return Sprite(*desc);
   else
     return Sprite();
-
-#if 0
-  try {
-    return CL_Sprite(res_name, &resmgr);
-  } catch (CL_Error& err) {
-    std::cout << "Resource::load_sprite: CL_Error: '" << res_name << "'" << 
std::endl;
-    std::cout << "CL_Error: " << err.message << std::endl;
-    return CL_Sprite("core/misc/404sprite", &resmgr);
-  }
-#endif
 }
 
 CollisionMask
@@ -186,9 +137,9 @@
 {
   SpriteDescription* desc = resmgr.get_sprite_description(desc_.res_name);
   if (desc)
-    return apply_modifier_to_surface(Surface(desc->filename), desc_);
+    return Surface(desc->filename).mod(desc_.modifier);
   else
-    return apply_modifier_to_surface(Surface(), desc_);
+    return Surface(desc->filename).mod(desc_.modifier);
 }
 
 Surface
@@ -197,64 +148,6 @@
   return load_surface(ResDescriptor(res_name));
 }
 
-#if 0
-CL_Surface
-Resource::load_surface(const ResDescriptor& res_desc)
-{
-  // try to load from cache
-  CL_Surface surf = load_from_cache(res_desc);
-
-  if (!surf) // not in cache
-    {
-      ResDescriptor desc = res_desc;
-      desc.modifier = ResourceModifierNS::ROT0;
-
-      // Try to an unmodified version from cache
-      surf = load_from_cache(desc);
-
-      if (surf) // found unmodified version in cache
-       {
-         pout(PINGUS_DEBUG_RESOURCES) << "Resource: Loading surface from cache 
1/2: " << res_desc << std::endl;
-         surf = apply_modifier (surf, res_desc);
-
-         surface_map[res_desc] = surf;
-       }
-      else // never loaded, need to load it from source
-       {
-         desc = res_desc;
-         desc.modifier = ResourceModifierNS::ROT0;
-
-         pout(PINGUS_DEBUG_RESOURCES) << "Resource: Loading surface from 
source: " << res_desc << std::endl;
-         surf = load_from_source (desc);
-         surface_map[desc] = surf; // add to cache
-
-         surf = apply_modifier (surf, res_desc);
-         surface_map[res_desc] = surf; // add modified version to cache
-       }
-    }
-  else
-    {
-      pout(PINGUS_DEBUG_RESOURCES) << "Resource: Loading surface from cache: " 
<< res_desc << std::endl;
-    }
-
-  return surf;
-}
-
-CL_Surface
-Resource::load_from_cache (const ResDescriptor& res_desc)
-{
-  std::map<ResDescriptor, CL_Surface>::iterator i = surface_map.find(res_desc);
-  if (i == surface_map.end())
-    {
-      return CL_Surface();
-    }
-  else
-    {
-      return i->second;
-    }
-}
-#endif 
-
 Font
 Resource::load_font(const std::string& res_name)
 {
@@ -278,38 +171,6 @@
 #endif
 }
 
-unsigned int
-Resource::get_mtime (const std::string& res_name)
-{
-  /*
-    try
-    {
-    CL_ResourceManager res_man = Resource::get(datafile);
-
-    CL_Resource& res = res_man->get_resource(res_name);
-
-    std::string filename = res.get_full_location();
-
-    #ifndef WIN32
-    struct stat stat_buf;
-    if (stat(filename.c_str(), &stat_buf) == 0)
-    return stat_buf.st_mtime;
-    else
-    return 0;
-    #else
-    // FIXME: Win32 mtime getter not implemented
-    return 0;
-    }
-    catch (CL_Error& err)
-    {
-    std::cout << "Resource::get_mtime: CL_Error: " << err.message << std::endl;
-    return 0;
-    }
-    #endif
-  */
-  return 0;
-}
-
 Sprite
 Resource::load_thumb_sprite(const std::string& name)
 {

Modified: trunk/pingus/src/resource.hpp
===================================================================
--- trunk/pingus/src/resource.hpp       2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/resource.hpp       2007-09-15 00:59:40 UTC (rev 3148)
@@ -38,42 +38,25 @@
 {
 public:
   static ResourceManager resmgr;
-#if 0
-  static std::map<ResDescriptor, CL_Surface> surface_map;
 
-  static CL_Surface load_from_source (const ResDescriptor& res_desc);
-  static CL_Surface load_from_cache (const ResDescriptor& res_desc);
-  static CL_Surface apply_modifier (const CL_Surface&, const ResDescriptor& 
res_desc);
-
-  /** Returns a list of resources for the given section.
-      Returns all if blank */
-  static std::vector<std::string> get_resources(const std::string &type,
-                                                const std::string &section = 
"");
-
-  /** Returns a list of sections under the given section.
-      Returns all sections if blank */
-  static std::vector<std::string> get_sections(const std::string &section = 
std::string());
-#endif
-  static Surface apply_modifier_to_surface(Surface, const ResDescriptor& 
res_desc);
-
 public:
   static void init();
   static void deinit();
 
-  /** */
-  static unsigned int get_mtime (const std::string& res_name);
-
   /** Loads a 48x48 size thumbnail of a sprite */
   static Sprite        load_thumb_sprite(const std::string&);
+
   static Sprite        load_sprite(const ResDescriptor&);
   static Sprite        load_sprite(const std::string& res_name);
+
   static CollisionMask load_collision_mask(const std::string& res_name);
   static CollisionMask load_collision_mask(const ResDescriptor&);
-  static Surface   load_surface(const std::string& res_name);
-  static Surface   load_surface(const ResDescriptor&);
 
+  static Surface       load_surface(const std::string& res_name);
+  static Surface       load_surface(const ResDescriptor&);
+
   /** Load a font with res_name from datafile */
-  static Font load_font(const std::string& res_name);
+  static Font          load_font(const std::string& res_name);
 
   /** Cleanup all currently unused surfaces */
   static void cleanup ();

Modified: trunk/pingus/src/sprite.cpp
===================================================================
--- trunk/pingus/src/sprite.cpp 2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/sprite.cpp 2007-09-15 00:59:40 UTC (rev 3148)
@@ -28,6 +28,7 @@
 #include "blitter.hpp"
 #include "surface.hpp"
 #include "pathname.hpp"
+#include "resource.hpp"
 #include "sprite_description.hpp"
 
 class SpriteImpl
@@ -35,8 +36,7 @@
 private:
   friend class Sprite;
 
-  SDL_Surface* surface;
-  bool         optimized;
+  Surface  surface;
 
   Vector2i offset;
 
@@ -59,27 +59,28 @@
   {
   }
 
-  SpriteImpl(const SpriteDescription& desc)
-    : surface(0),
-      optimized(false),
-      finished(false),
+  SpriteImpl(const SpriteDescription& desc, 
ResourceModifierNS::ResourceModifier mod = ResourceModifierNS::ROT0)
+    : finished(false),
       frame(0),
       tick_count(0)
   {
-    surface = IMG_Load(desc.filename.get_sys_path().c_str());
+    surface = Surface(desc.filename);
+    if (mod != ResourceModifierNS::ROT0)
+      surface = surface.mod(mod);
+
     if (!surface)
       {
-        std::cout << "Error: Couldn't load " << desc.filename << std::endl;
-        surface = IMG_Load(Pathname("images/core/misc/404.png", 
Pathname::DATA_PATH).str().c_str());
-        assert(surface);
+        std::cout << "Error: Surface: couldn't load '" << desc.filename << "'" 
<< std::endl;
+        surface = Surface(Pathname("images/core/misc/404.png", 
Pathname::DATA_PATH));
+        if (!surface) assert(!"Surface Couldn't find 404");
       }
 
     frame_pos = desc.frame_pos;
 
     array = desc.array;
 
-    frame_size.width  = (desc.frame_size.width  == -1) ? 
surface->w/array.width  : desc.frame_size.width;
-    frame_size.height = (desc.frame_size.height == -1) ? 
surface->h/array.height : desc.frame_size.height;
+    frame_size.width  = (desc.frame_size.width  == -1) ? 
surface.get_width()/array.width   : desc.frame_size.width;
+    frame_size.height = (desc.frame_size.height == -1) ? 
surface.get_height()/array.height : desc.frame_size.height;
 
     frame_delay  = desc.speed;
 
@@ -92,8 +93,7 @@
   }
 
   SpriteImpl(const Surface& surface)
-    : optimized(false),
-      offset(0,0),
+    : offset(0,0),
       frame_pos(0,0),
       frame_size(surface.get_width(), surface.get_height()),
       frame_delay(0),
@@ -104,43 +104,16 @@
       frame(0),
       tick_count(0)
   {
-    if (surface.get_surface())
-      {
-        if (surface.get_surface()->format->Amask == 0)
-          this->surface = SDL_DisplayFormat(surface.get_surface());
-        else
-          this->surface = SDL_DisplayFormatAlpha(surface.get_surface());
-
-        optimized = true;
-      }
-    else
-      {
-        this->surface = 0;
-        std::cout << "Sprite: Error trying to create a Sprite out of an empty 
Surface"  << std::endl;
-      }
+    optimize();
   }
 
   ~SpriteImpl()
   {
-    SDL_FreeSurface(surface);
   }
 
   void optimize()
   {
-    if (!optimized)
-      {
-        // FIXME: Could add a check to check if the surface is already 
optimized
-        SDL_Surface* old_surface = surface;
-
-        if (surface->format->Amask != 0 || (surface->flags & SDL_SRCCOLORKEY))
-          surface = SDL_DisplayFormatAlpha(old_surface);
-        else
-          surface = SDL_DisplayFormat(old_surface);
-  
-        SDL_FreeSurface(old_surface);
-
-        optimized = true;
-      }
+    surface.optimize();
   }
 
   void update(float delta)
@@ -185,7 +158,7 @@
     srcrect.x = frame_pos.x + (srcrect.w * (frame%array.width));
     srcrect.y = frame_pos.y + (srcrect.h * (frame/array.width));
 
-    SDL_BlitSurface(surface, &srcrect, dst, &dstrect);
+    SDL_BlitSurface(surface.get_surface(), &srcrect, dst, &dstrect);
   }
 
   void restart()
@@ -201,7 +174,7 @@
     finished = true;
   }
 };
-
+
 Sprite::Sprite()
 {
   
@@ -220,8 +193,8 @@
   
 }
 
-Sprite::Sprite(const SpriteDescription& desc)
-  : impl(new SpriteImpl(desc))
+Sprite::Sprite(const SpriteDescription& desc, 
ResourceModifierNS::ResourceModifier mod)
+  : impl(new SpriteImpl(desc, mod))
 {
 }
 
@@ -334,7 +307,7 @@
 Sprite::get_surface() const
 {
   if (impl.get())
-    return impl->surface;
+    return impl->surface.get_surface();
   else
     return NULL;
 }
@@ -342,52 +315,27 @@
 void
 Sprite::scale(int w, int h)
 {
+  // FIXME: This doesn't work for animated graphics, in which case it will 
only handle the first frame
   if (impl->frame_size.width != w || impl->frame_size.height != h)
     {
       boost::shared_ptr<SpriteImpl> new_impl(new SpriteImpl());
 
-      if ((impl->frame_size.width  * impl->array.width)  == impl->surface->w 
&& 
-          (impl->frame_size.height * impl->array.height) == impl->surface->h)
-        {
-          new_impl->surface = Blitter::scale_surface(impl->surface, 
-                                                     w * impl->array.width,
-                                                     h * impl->array.height);
+      
+      if ((impl->frame_size.width  * impl->array.width)  == 
impl->surface.get_width() && 
+          (impl->frame_size.height * impl->array.height) == 
impl->surface.get_height())
+        { // single frame Sprite
+          new_impl->surface = impl->surface.scale(w, h);
         }
       else
-        {
-          // Create a temporary surface that contains the subsection
-          // that is actually used for this Sprite
-          SDL_Surface* subsurface = 
SDL_CreateRGBSurfaceFrom((uint8_t*)(impl->surface->pixels)
-                                                             + 
(impl->frame_pos.y * impl->surface->pitch) 
-                                                             + 
(impl->frame_pos.x * impl->surface->format->BytesPerPixel),
-                                                             impl->array.width 
 * impl->frame_size.width,
-                                                             
impl->array.height * impl->frame_size.height,
-                                                             
impl->surface->format->BitsPerPixel, 
-                                                             
impl->surface->pitch,
-                                                             
impl->surface->format->Rmask,
-                                                             
impl->surface->format->Gmask,
-                                                             
impl->surface->format->Bmask,
-                                                             
impl->surface->format->Amask);
-      
-          if (impl->surface->format->palette)
-            SDL_SetPalette(subsurface, SDL_LOGPAL, 
impl->surface->format->palette->colors, 
-                           0, impl->surface->format->palette->ncolors);
-
-          if (impl->surface->flags & SDL_SRCCOLORKEY)
-            SDL_SetColorKey(subsurface, SDL_SRCCOLORKEY, 
impl->surface->format->colorkey);
-
-          new_impl->surface = Blitter::scale_surface(subsurface, 
-                                                     w * impl->array.width,
-                                                     h * impl->array.height);
-
-          SDL_FreeSurface(subsurface);
+        { // multi frame sprite
+          new_impl->surface = impl->surface.subsection(Rect(impl->frame_pos, 
impl->frame_size)).scale(w, h);
         }
 
-      float scale_x = float(w) / float(impl->frame_size.width); // ok
-      float scale_y = float(h) / float(impl->frame_size.height); // ok
-            
+      float scale_x = float(w) / float(impl->frame_size.width);
+      float scale_y = float(h) / float(impl->frame_size.height);
+      
       new_impl->offset          = Vector2i(int(impl->offset.x * scale_x),
-                                           int(impl->offset.y * scale_y)); //ok
+                                           int(impl->offset.y * scale_y)); 
       new_impl->frame_pos       = Vector2i(0, 0);
       new_impl->frame_size      = Size(w, h);
       new_impl->frame_delay     = impl->frame_delay;
@@ -408,18 +356,7 @@
   if (color.a != 0) 
     {
       make_single_user();
-
-      // FIXME: Couldn't get this to work with a RGBA surface for some
-      // reason, something to do with tmp format and impl->surface
-      // matching up maybe, anyway with RGB it works and it saves a
-      // little bit of space to
-      SDL_Surface* tmp = Blitter::create_surface_rgb(impl->surface->w, 
impl->surface->h);
-      SDL_FillRect(tmp, NULL, SDL_MapRGBA(tmp->format, color.r, color.g, 
color.b, 255));
-      SDL_SetAlpha(tmp, SDL_SRCALPHA, color.a);
-          
-      SDL_BlitSurface(tmp, NULL, impl->surface, NULL);
-
-      SDL_FreeSurface(tmp);
+      impl->surface.fill(color);
     }
 }
 
@@ -428,13 +365,7 @@
 {
   boost::shared_ptr<SpriteImpl> new_impl(new SpriteImpl());
   
-  if (impl->surface->format->Amask == 0)
-    new_impl->surface         = Blitter::create_surface_rgb(impl->surface->w, 
impl->surface->h);
-  else
-    new_impl->surface         = Blitter::create_surface_rgba(impl->surface->w, 
impl->surface->h);
-
-  SDL_BlitSurface(impl->surface, NULL, new_impl->surface, NULL);
-
+  new_impl->surface         = impl->surface.clone();
   new_impl->offset          = impl->offset;
   new_impl->frame_pos       = impl->frame_pos;
   new_impl->frame_size      = impl->frame_size;
@@ -457,6 +388,27 @@
 }
 
 void
+Sprite::apply_mod(ResourceModifierNS::ResourceModifier mod)
+{
+  // FIXME: This isn't all that useful, since Sprites are optimized
+  // per default and thus not modifiable, since the Modifier can only
+  // handle indexed images.
+  if (impl->frame_pos  == Vector2i(0, 0) &&
+      impl->frame_size == Size(impl->surface.get_width(), 
impl->surface.get_height()) &&
+      impl->array      == Size(1, 1))
+    {
+      make_single_user();
+      impl->surface = impl->surface.mod(mod);
+      impl->frame_size.width  = impl->surface.get_width();
+      impl->frame_size.height = impl->surface.get_height();
+    }
+  else
+    {
+      std::cout << "Error: Sprite: apply_mod() only works with single frame 
Sprites" << std::endl;
+    }
+}
+
+void
 Sprite::optimize()
 {
   impl->optimize();

Modified: trunk/pingus/src/sprite.hpp
===================================================================
--- trunk/pingus/src/sprite.hpp 2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/sprite.hpp 2007-09-15 00:59:40 UTC (rev 3148)
@@ -23,6 +23,7 @@
 #include <string>
 #include <boost/shared_ptr.hpp>
 #include "math/origin.hpp"
+#include "resource_modifier.hpp"
 #include "SDL.h"
 
 class Color;
@@ -37,7 +38,7 @@
 public:
   Sprite();
   Sprite(const Pathname& name);
-  Sprite(const SpriteDescription& desc);
+  Sprite(const SpriteDescription& desc, ResourceModifierNS::ResourceModifier 
mod = ResourceModifierNS::ROT0);
   Sprite(const Surface& surface);
   ~Sprite();
 
@@ -77,6 +78,8 @@
       without affecting other references to it */
   void make_single_user();
 
+  void apply_mod(ResourceModifierNS::ResourceModifier mod);
+
 private:
   boost::shared_ptr<SpriteImpl> impl;
 };

Modified: trunk/pingus/src/surface.cpp
===================================================================
--- trunk/pingus/src/surface.cpp        2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/surface.cpp        2007-09-15 00:59:40 UTC (rev 3148)
@@ -20,31 +20,48 @@
 #include "SDL_image.h"
 #include <sstream>
 #include <iostream>
+#include "math/rect.hpp"
+#include "debug.hpp"
+#include "blitter.hpp"
 #include "surface.hpp"
 
 class SurfaceImpl
 {
 public:
-  SurfaceImpl(SDL_Surface* surface = NULL) : surface(surface) {}
-  ~SurfaceImpl() {
-    SDL_FreeSurface(surface);
+  SDL_Surface* surface;
+  bool  delete_surface;
+  bool       optimized;
+
+  SurfaceImpl(SDL_Surface* surface = NULL, bool delete_surface_ = true) 
+    : surface(surface),
+      delete_surface(delete_surface_),
+      optimized(false)
+  {}
+  
+  ~SurfaceImpl() 
+  {
+    if (delete_surface)
+      SDL_FreeSurface(surface);
   }
-  SDL_Surface* surface;
 };
 
 Surface::Surface()
 {
 }
 
+Surface::Surface(boost::shared_ptr<SurfaceImpl> impl_)
+  : impl(impl_)
+{
+}
+
 Surface::Surface(const Pathname& pathname)
-  : impl(new SurfaceImpl())
 {
-  impl->surface = IMG_Load(pathname.get_sys_path().c_str());
-  if (!impl->surface)
-    std::cout << "XXXXXX Failed to load: " << pathname.str() << std::endl;
-  ///else
-  //std::cout << "Loaded surface: " << name << ": " << surface->w << "x" << 
surface->h << std::endl;
-
+  SDL_Surface* surface = IMG_Load(pathname.get_sys_path().c_str());
+  if (surface)
+    {
+      impl = boost::shared_ptr<SurfaceImpl>(new SurfaceImpl());
+      impl->surface = surface;
+    }
 }
 
 Surface::Surface(int width, int height, SDL_Palette* palette, int colorkey)
@@ -76,8 +93,8 @@
   //SDL_FillRect(surface, NULL, SDL_MapRGBA(surface->format, 0, 0, 0, 0));
 }
 
-Surface::Surface(SDL_Surface* surface)
-  : impl(new SurfaceImpl(surface))
+Surface::Surface(SDL_Surface* surface, bool delete_surface)
+  : impl(new SurfaceImpl(surface, delete_surface))
 {
 }
 
@@ -125,6 +142,15 @@
   return static_cast<uint8_t*>(get_surface()->pixels);
 }
 
+Size
+Surface::get_size()  const
+{
+  if (get_surface())
+    return Size(impl->surface->w, impl->surface->h);
+  else
+    return Size();
+}
+
 int
 Surface::get_width()  const
 {
@@ -191,4 +217,120 @@
   return color;
 }
 
+Surface
+Surface::mod(ResourceModifierNS::ResourceModifier modifier)
+{
+  switch(modifier)
+    {
+      case ResourceModifierNS::ROT0:
+        return this->clone();
+
+      case ResourceModifierNS::ROT90:
+        return Blitter::rotate_90(*this);
+
+      case ResourceModifierNS::ROT180:
+        return Blitter::rotate_180(*this);
+
+      case ResourceModifierNS::ROT270:
+        return Blitter::rotate_270(*this);
+
+      case ResourceModifierNS::ROT0FLIP:
+        return Blitter::flip_horizontal(*this);
+
+      case ResourceModifierNS::ROT90FLIP:
+        return Blitter::rotate_90_flip(*this);
+
+      case ResourceModifierNS::ROT180FLIP:
+        return Blitter::rotate_180_flip(*this);
+
+      case ResourceModifierNS::ROT270FLIP:
+        return Blitter::rotate_270_flip(*this);
+
+      default:
+        perr << "Surface: unhandled modifier: " << modifier << std::endl;
+        return *this;
+    }
+}
+
+void
+Surface::optimize()
+{
+  if (!impl->optimized)
+    {
+      // FIXME: Could add a check to check if the surface is already optimized
+      SDL_Surface* old_surface = impl->surface;
+
+      if (impl->surface->format->Amask != 0 || (impl->surface->flags & 
SDL_SRCCOLORKEY))
+        impl->surface = SDL_DisplayFormatAlpha(old_surface);
+      else
+        impl->surface = SDL_DisplayFormat(old_surface);
+  
+      SDL_FreeSurface(old_surface);
+
+      impl->optimized = true;
+    }
+}
+
+Surface
+Surface::scale(int w, int h)
+{
+  return Surface(boost::shared_ptr<SurfaceImpl>
+                 (new SurfaceImpl(Blitter::scale_surface(impl->surface, w, h), 
true)));
+}
+
+Surface
+Surface::clone() const
+{
+  SDL_Surface* new_surface = 
Blitter::create_surface_from_format(impl->surface, 
+                                                                 
impl->surface->w, impl->surface->h);
+  SDL_BlitSurface(impl->surface, NULL, new_surface, NULL);
+ 
+ return Surface(boost::shared_ptr<SurfaceImpl>(new SurfaceImpl(new_surface, 
true)));
+}
+
+Surface
+Surface::subsection(const Rect& rect) const
+{
+  SDL_Surface* new_surface;
+  new_surface = Blitter::create_surface_from_format(impl->surface,
+                                                    rect.get_width(), 
rect.get_height());
+  SDL_Rect dst_rect;
+  dst_rect.x = rect.left;
+  dst_rect.y = rect.top;
+
+  if (impl->surface->format->palette)
+    SDL_SetPalette(new_surface, SDL_LOGPAL, 
impl->surface->format->palette->colors, 
+                   0, impl->surface->format->palette->ncolors);
+
+  SDL_BlitSurface(impl->surface, NULL, new_surface, &dst_rect);
+
+  /* FIXME: Need to copy palette and color key?!
+    if (impl->surface->format->palette)
+    SDL_SetPalette(subsurface, SDL_LOGPAL, 
impl->surface->format->palette->colors, 
+    0, impl->surface->format->palette->ncolors);
+
+    if (impl->surface->flags & SDL_SRCCOLORKEY)
+    SDL_SetColorKey(subsurface, SDL_SRCCOLORKEY, 
impl->surface->format->colorkey);
+  */
+
+  return Surface(boost::shared_ptr<SurfaceImpl>(new SurfaceImpl(new_surface, 
true)));
+}
+
+void
+Surface::fill(const Color& color)
+{
+  // FIXME: Couldn't get this to work with a RGBA surface for some
+  // reason, something to do with tmp format and impl->surface
+  // matching up maybe, anyway with RGB it works and it saves a
+  // little bit of space to
+  // FIXME: sould/should use a proper RGBA rect_fill function, this is just a 
work around
+  SDL_Surface* tmp = Blitter::create_surface_rgb(impl->surface->w, 
impl->surface->h);
+  SDL_FillRect(tmp, NULL, SDL_MapRGBA(tmp->format, color.r, color.g, color.b, 
255));
+  SDL_SetAlpha(tmp, SDL_SRCALPHA, color.a);
+          
+  SDL_BlitSurface(tmp, NULL, impl->surface, NULL);
+
+  SDL_FreeSurface(tmp);
+}
+
 /* EOF */

Modified: trunk/pingus/src/surface.hpp
===================================================================
--- trunk/pingus/src/surface.hpp        2007-09-14 19:13:17 UTC (rev 3147)
+++ trunk/pingus/src/surface.hpp        2007-09-15 00:59:40 UTC (rev 3148)
@@ -23,9 +23,12 @@
 #include "SDL.h"
 #include <string>
 #include <boost/shared_ptr.hpp>
+#include "math/size.hpp"
+#include "resource_modifier.hpp"
 #include "pathname.hpp"
 #include "math/color.hpp"
 
+class Rect;
 class Pathname;
 class SurfaceImpl;
 
@@ -34,28 +37,44 @@
 {
 public:
   Surface();
+
+  Surface(boost::shared_ptr<SurfaceImpl> impl);
+
   Surface(const Pathname& name);
+
   /** Create an empty RGBA Surface */
   Surface(int width, int height);
 
   /** Create an empty Indexed Surface (8bit) */
   Surface(int width, int height, SDL_Palette* palette, int colorkey = -1);
+
   /** Create a Surface from a SDL_Surface */
-  Surface(SDL_Surface* surface);
+  Surface(SDL_Surface* surface, bool delete_surface = true);
+
   ~Surface();
 
   uint8_t* get_data() const;
   void lock();
   void unlock();
 
+  Size get_size()  const;
   int get_width()  const;
   int get_height() const;
   int get_pitch()  const;
 
+
   void blit(const Surface& source, int x, int y);
 
   Color get_pixel(int x, int y) const;
 
+  void fill(const Color& color);
+  void optimize();
+
+  Surface scale(int w, int h);
+  Surface mod(ResourceModifierNS::ResourceModifier mod);
+  Surface clone() const;
+  Surface subsection(const Rect& rect) const;
+
   SDL_Surface* get_surface() const;
 
   operator bool() const;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]