[Top][All Lists]
[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 §ion =
"");
-
- /** Returns a list of sections under the given section.
- Returns all sections if blank */
- static std::vector<std::string> get_sections(const std::string §ion =
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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pingus-CVS] r3148 - in trunk/pingus/src: . editor math,
grumbel at BerliOS <=