diff --git a/ee.linux.cbp b/ee.linux.cbp
index 706f500b7..a865d5a8b 100644
--- a/ee.linux.cbp
+++ b/ee.linux.cbp
@@ -120,13 +120,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/audio/caudiodevice.hpp b/src/audio/caudiodevice.hpp
index 3ad5f0d1e..849a1fc28 100755
--- a/src/audio/caudiodevice.hpp
+++ b/src/audio/caudiodevice.hpp
@@ -5,7 +5,7 @@
namespace EE { namespace Audio {
-class cAudioDevice {
+class EE_API cAudioDevice {
public :
static cAudioDevice * instance();
diff --git a/src/audio/csoundfile.hpp b/src/audio/csoundfile.hpp
index 8b99a2aad..1ab4e0141 100755
--- a/src/audio/csoundfile.hpp
+++ b/src/audio/csoundfile.hpp
@@ -5,7 +5,7 @@
namespace EE { namespace Audio {
-class cSoundFile {
+class EE_API cSoundFile {
public:
static cSoundFile* CreateRead(const std::string& Filename);
static cSoundFile* CreateRead(const char* Data, std::size_t SizeInBytes);
diff --git a/src/audio/csoundfiledefault.hpp b/src/audio/csoundfiledefault.hpp
index c62ed3608..6af270bc2 100755
--- a/src/audio/csoundfiledefault.hpp
+++ b/src/audio/csoundfiledefault.hpp
@@ -9,7 +9,7 @@
namespace EE { namespace Audio {
-class cSoundFileDefault : public cSoundFile {
+class EE_API cSoundFileDefault : public cSoundFile {
public :
cSoundFileDefault();
~cSoundFileDefault();
diff --git a/src/audio/csoundfileogg.hpp b/src/audio/csoundfileogg.hpp
index b01fca769..5a5bc26a2 100755
--- a/src/audio/csoundfileogg.hpp
+++ b/src/audio/csoundfileogg.hpp
@@ -7,7 +7,7 @@
namespace EE { namespace Audio {
-class cSoundFileOgg : public cSoundFile {
+class EE_API cSoundFileOgg : public cSoundFile {
public:
cSoundFileOgg();
~cSoundFileOgg();
diff --git a/src/base.hpp b/src/base.hpp
index 23d53e194..21b410d7c 100644
--- a/src/base.hpp
+++ b/src/base.hpp
@@ -88,8 +88,6 @@
#endif
namespace EE {
- #define EE_CLOCKS_PER_SEC 1000000l
-
#define eeARRAY_SIZE(__array) ( sizeof(__array) / sizeof(__array[0]) )
#define eeSAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define eeSAFE_FREE(p) { if(p) { free ( (void*)p );(p)=NULL; } }
diff --git a/src/ee.h b/src/ee.h
index 58ab61e89..c7ae5d8dc 100755
--- a/src/ee.h
+++ b/src/ee.h
@@ -91,9 +91,11 @@
// Graphics
#include "graphics/renders.hpp"
+ #include "graphics/cimage.hpp"
#include "graphics/ctexture.hpp"
#include "graphics/ctextureloader.hpp"
#include "graphics/ctexturefactory.hpp"
+ #include "graphics/ctexturepacker.hpp"
#include "graphics/cshape.hpp"
#include "graphics/cshapegroup.hpp"
#include "graphics/cglobalshapegroup.hpp"
@@ -117,6 +119,7 @@
#include "graphics/cshader.hpp"
#include "graphics/cshaderprogram.hpp"
#include "graphics/cshaderprogrammanager.hpp"
+ #include "graphics/ctexturegrouploader.hpp"
using namespace EE::Graphics;
// Gaming
diff --git a/src/graphics/cbatchrenderer.hpp b/src/graphics/cbatchrenderer.hpp
index eeb7950bb..97e57d8e9 100755
--- a/src/graphics/cbatchrenderer.hpp
+++ b/src/graphics/cbatchrenderer.hpp
@@ -18,7 +18,7 @@ typedef struct {
} eeVertex;
/** @brief A batch rendering class. */
-class cBatchRenderer {
+class EE_API cBatchRenderer {
public:
cBatchRenderer();
~cBatchRenderer();
diff --git a/src/graphics/cfontmanager.hpp b/src/graphics/cfontmanager.hpp
index 0974cbc64..c39edef6c 100644
--- a/src/graphics/cfontmanager.hpp
+++ b/src/graphics/cfontmanager.hpp
@@ -6,7 +6,7 @@
namespace EE { namespace Graphics {
-class cFontManager : public tResourceManager, public cSingleton {
+class EE_API cFontManager : public tResourceManager, public cSingleton {
friend class cSingleton;
public:
cFontManager();
diff --git a/src/graphics/cglobalbatchrenderer.hpp b/src/graphics/cglobalbatchrenderer.hpp
index 7e9a13a45..a19237988 100755
--- a/src/graphics/cglobalbatchrenderer.hpp
+++ b/src/graphics/cglobalbatchrenderer.hpp
@@ -7,7 +7,7 @@
namespace EE { namespace Graphics {
/** @brief The global Batch Renderer class. This class will be used by the engine for the rendering. */
-class cGlobalBatchRenderer : public cSingleton, public cBatchRenderer {
+class EE_API cGlobalBatchRenderer : public cSingleton, public cBatchRenderer {
friend class cSingleton;
public:
cGlobalBatchRenderer();
diff --git a/src/graphics/cimage.cpp b/src/graphics/cimage.cpp
index 5194cfd46..e06c7abc8 100644
--- a/src/graphics/cimage.cpp
+++ b/src/graphics/cimage.cpp
@@ -1,4 +1,5 @@
#include "cimage.hpp"
+#include "../helper/SOIL/image_helper.h"
namespace EE { namespace Graphics {
@@ -7,7 +8,8 @@ cImage::cImage() :
mWidth(0),
mHeight(0),
mChannels(0),
- mSize(0)
+ mSize(0),
+ mAvoidFree(false)
{
}
@@ -16,7 +18,8 @@ cImage::cImage( const Uint8* data, const eeUint& Width, const eeUint& Height, co
mWidth(Width),
mHeight(Height),
mChannels(Channels),
- mSize(0)
+ mSize(0),
+ mAvoidFree(false)
{
SetPixels( data );
}
@@ -26,13 +29,35 @@ cImage::cImage( const Uint32& Width, const Uint32& Height, const Uint32& Channel
mWidth(Width),
mHeight(Height),
mChannels(Channels),
- mSize(0)
+ mSize(0),
+ mAvoidFree(false)
{
Create( Width, Height, Channels );
}
+cImage::cImage( Uint8* data, const eeUint& Width, const eeUint& Height, const eeUint& Channels ) :
+ mPixels( data ),
+ mWidth(Width),
+ mHeight(Height),
+ mChannels(Channels),
+ mSize(Width*Height*Channels),
+ mAvoidFree(false)
+{
+}
+
cImage::~cImage() {
- ClearCache();
+ if ( !mAvoidFree )
+ ClearCache();
+}
+
+void cImage::SetPixels( const Uint8* data ) {
+ if ( data != NULL ) {
+ eeUint size = (eeUint)mWidth * (eeUint)mHeight * mChannels;
+
+ Allocate( size );
+
+ memcpy( reinterpret_cast( &mPixels[0] ), reinterpret_cast ( data ), size );
+ }
}
const Uint8* cImage::GetPixelsPtr() {
@@ -77,16 +102,6 @@ void cImage::Create( const Uint32& Width, const Uint32& Height, const Uint32& Ch
Allocate( mWidth * mHeight * mChannels );
}
-void cImage::SetPixels( const Uint8* data ) {
- if ( data != NULL ) {
- eeUint size = (eeUint)mWidth * (eeUint)mHeight * mChannels;
-
- Allocate( size );
-
- memcpy( reinterpret_cast( &mPixels[0] ), reinterpret_cast ( data ), size );
- }
-}
-
Uint8* cImage::GetPixels() const {
return mPixels;
}
@@ -140,4 +155,129 @@ bool cImage::SaveToFile( const std::string& filepath, const EE_SAVETYPE& Format
return Res;
}
+void cImage::ReplaceColor( const eeColorA& ColorKey, const eeColorA& NewColor ) {
+ eeUint Pos = 0;
+
+ if ( NULL == mPixels )
+ return;
+
+ for ( eeUint i = 0; i < mWidth * mHeight; i++ ) {
+ Pos = i * mChannels;
+
+ if ( 4 == mChannels ) {
+ if ( mPixels[ Pos ] == ColorKey.R() && mPixels[ Pos + 1 ] == ColorKey.G() && mPixels[ Pos + 2 ] == ColorKey.B() && mPixels[ Pos + 3 ] == ColorKey.A() ) {
+ mPixels[ Pos ] = NewColor.R();
+ mPixels[ Pos + 1 ] = NewColor.G();
+ mPixels[ Pos + 2 ] = NewColor.B();
+ mPixels[ Pos + 3 ] = NewColor.A();
+ }
+ } else if ( 3 == mChannels ) {
+ if ( mPixels[ Pos ] == ColorKey.R() && mPixels[ Pos + 1 ] == ColorKey.G() && mPixels[ Pos + 2 ] == ColorKey.B() ) {
+ mPixels[ Pos ] = NewColor.R();
+ mPixels[ Pos + 1 ] = NewColor.G();
+ mPixels[ Pos + 2 ] = NewColor.B();
+ }
+ } else if ( 2 == mChannels ) {
+ if ( mPixels[ Pos ] == ColorKey.R() && mPixels[ Pos + 1 ] == ColorKey.G() ) {
+ mPixels[ Pos ] = NewColor.R();
+ mPixels[ Pos + 1 ] = NewColor.G();
+ }
+ } else if ( 1 == mChannels ) {
+ if ( mPixels[ Pos ] == ColorKey.R() ) {
+ mPixels[ Pos ] = NewColor.R();
+ }
+ }
+ }
+}
+
+void cImage::CreateMaskFromColor( const eeColorA& ColorKey, Uint8 Alpha ) {
+ ReplaceColor( ColorKey, eeColorA( ColorKey.R(), ColorKey.G(), ColorKey.B(), Alpha ) );
+}
+
+void cImage::CreateMaskFromColor( const eeColor& ColorKey, Uint8 Alpha ) {
+ CreateMaskFromColor( eeColorA( ColorKey.R(), ColorKey.G(), ColorKey.B(), 255 ), Alpha );
+}
+
+void cImage::FillWithColor( const eeColorA& Color ) {
+ if ( NULL == mPixels )
+ return;
+
+ eeUint z;
+
+ for ( eeUint i = 0; i < mWidth * mHeight; i += mChannels ) {
+ for ( z = 0; z < mChannels; z++ ) {
+ if ( 0 == z )
+ mPixels[ i + z ] = Color.R();
+ else if ( 1 == z )
+ mPixels[ i + z ] = Color.G();
+ else if ( 2 == z )
+ mPixels[ i + z ] = Color.B();
+ else if ( 3 == z )
+ mPixels[ i + z ] = Color.A();
+ }
+ }
+}
+
+void cImage::CopyImage( cImage * Img, const eeUint& x, const eeUint& y ) {
+ if ( NULL != mPixels && NULL != Img->GetPixels() && mWidth >= x + Img->Width() && mHeight >= y + Img->Height() ) {
+ eeUint dWidth = Img->Width();
+ eeUint dHeight = Img->Height();
+
+ for ( eeUint ty = 0; ty < dHeight; ty++ ) {
+ for ( eeUint tx = 0; tx < dWidth; tx++ ) {
+ SetPixel( x + tx, y + ty, Img->GetPixel( tx, ty ) );
+ }
+ }
+ }
+}
+
+void cImage::Resize( const eeUint& new_width, const eeUint& new_height ) {
+ if ( NULL != mPixels && mWidth != new_width && mHeight != new_height ) {
+ unsigned char * resampled = new unsigned char[ mChannels * new_width * new_height ];
+
+ int res = up_scale_image( reinterpret_cast ( mPixels ), mWidth, mHeight, mChannels, resampled, new_width, new_height );
+
+ if ( res ) {
+ ClearCache();
+
+ mPixels = resampled;
+ mWidth = new_width;
+ mHeight = new_height;
+ } else
+ eeSAFE_DELETE_ARRAY( resampled );
+ }
+}
+
+void cImage::Scale( const eeFloat& scale ) {
+ if ( 1.f == scale )
+ return;
+
+ Int32 new_width = (Int32)( (eeFloat)mWidth * scale );
+ Int32 new_height = (Int32)( (eeFloat)mHeight * scale );
+
+ Resize( new_width, new_height );
+}
+
+cImage * cImage::Thumbnail( const eeUint& max_width, const eeUint& max_height ) {
+ if ( NULL != mPixels && mWidth > max_width && mHeight > max_height ) {
+ eeFloat iScaleX = ( (eeFloat)max_width / (eeFloat)mWidth );
+ eeFloat iScaleY = ( (eeFloat)max_height / (eeFloat)mHeight );
+ eeFloat iScale = ( iScaleY < iScaleX ) ? iScaleY : iScaleX;
+ Int32 new_width = (Int32)( (eeFloat)mWidth * iScale );
+ Int32 new_height = (Int32)( (eeFloat)mHeight * iScale );
+
+ unsigned char * resampled = new unsigned char[ mChannels * new_width * new_height ];
+
+ int res = up_scale_image( reinterpret_cast ( mPixels ), mWidth, mHeight, mChannels, resampled, new_width, new_height );
+
+ if ( res ) {
+ return new cImage( (Uint8*)resampled, new_width, new_height, mChannels );
+ } else {
+ eeSAFE_DELETE_ARRAY( resampled );
+ }
+ }
+
+ return NULL;
+}
+
}}
diff --git a/src/graphics/cimage.hpp b/src/graphics/cimage.hpp
index 24b449908..899b5d319 100644
--- a/src/graphics/cimage.hpp
+++ b/src/graphics/cimage.hpp
@@ -5,10 +5,13 @@
namespace EE { namespace Graphics {
-class cImage {
+class EE_API cImage {
public:
cImage();
+ /** Use an existing image */
+ cImage( Uint8* data, const eeUint& Width, const eeUint& Height, const eeUint& Channels );
+
/** Copy a image data to create the image */
cImage( const Uint8* data, const eeUint& Width, const eeUint& Height, const eeUint& Channels );
@@ -61,12 +64,40 @@ class cImage {
/** Save the Image to a new File in a specific format */
virtual bool SaveToFile( const std::string& filepath, const EE_SAVETYPE& Format );
+
+ /** Create an Alpha mask from a Color */
+ virtual void CreateMaskFromColor( const eeColorA& ColorKey, Uint8 Alpha );
+
+ /** Create an Alpha mask from a Color */
+ void CreateMaskFromColor( const eeColor& ColorKey, Uint8 Alpha );
+
+ /** Replace a color on the image */
+ virtual void ReplaceColor( const eeColorA& ColorKey, const eeColorA& NewColor );
+
+ /** Fill the image with a color */
+ virtual void FillWithColor( const eeColorA& Color );
+
+ /** Copy the image to this image data, starting from the position x,y */
+ virtual void CopyImage( cImage * Img, const eeUint& x, const eeUint& y );
+
+ /** Scale the image */
+ virtual void Scale( const eeFloat& scale );
+
+ /** Resize the image */
+ virtual void Resize( const eeUint& new_width, const eeUint& new_height );
+
+ /** Create a thumnail of the image */
+ cImage * Thumbnail( const eeUint& max_width, const eeUint& max_height );
+
+ /** Set as true if you dont want to free the image data ( false as default ). */
+ void AvoidFreeImage( const bool& AvoidFree ) { mAvoidFree = AvoidFree; }
protected:
Uint8 * mPixels;
eeUint mWidth;
eeUint mHeight;
eeUint mChannels;
Uint32 mSize;
+ bool mAvoidFree;
void Allocate( const Uint32& size );
};
diff --git a/src/graphics/cshape.hpp b/src/graphics/cshape.hpp
index ec013d006..357496279 100644
--- a/src/graphics/cshape.hpp
+++ b/src/graphics/cshape.hpp
@@ -53,7 +53,7 @@ class EE_API cShape {
void Draw( const eeFloat& X, const eeFloat& Y, const eeRGBA& Color = eeRGBA(), const eeFloat& Angle = 0.f, const eeFloat& Scale = 1.f, const EE_RENDERALPHAS& Blend = ALPHA_NORMAL, const EE_RENDERTYPE& Effect = RN_NORMAL, const bool& ScaleRendered = true );
- void Draw( const eeFloat& X, const eeFloat& Y, const eeFloat& Angle = 0.f, const eeFloat& Scale = 1.f, const eeRGBA& Color0 = eeRGBA(), const eeRGBA& Color1 = eeRGBA(), const eeRGBA& Color2 = eeRGBA(), const eeRGBA& Color3 = eeRGBA(), const EE_RENDERALPHAS& Blend = ALPHA_NORMAL, const EE_RENDERTYPE& Effect = RN_NORMAL, const bool& ScaleRendered = true );
+ void Draw( const eeFloat& X, const eeFloat& Y, const eeFloat& Angle, const eeFloat& Scale, const eeRGBA& Color0 = eeRGBA(), const eeRGBA& Color1 = eeRGBA(), const eeRGBA& Color2 = eeRGBA(), const eeRGBA& Color3 = eeRGBA(), const EE_RENDERALPHAS& Blend = ALPHA_NORMAL, const EE_RENDERTYPE& Effect = RN_NORMAL, const bool& ScaleRendered = true );
cTexture * GetTexture();
diff --git a/src/graphics/ctextcache.hpp b/src/graphics/ctextcache.hpp
index 553a1be6f..3e7a969b4 100644
--- a/src/graphics/ctextcache.hpp
+++ b/src/graphics/ctextcache.hpp
@@ -9,7 +9,7 @@ namespace EE { namespace Graphics {
class cFont;
/** @brief Cached text for a fast font rendering. */
-class cTextCache {
+class EE_API cTextCache {
public:
cTextCache( cFont * font, const std::wstring& text = L"", eeColorA FontColor = eeColorA(0xFFFFFFFF), eeColorA ShadowColor = eeColorA(0xFF000000) );
diff --git a/src/graphics/ctexture.cpp b/src/graphics/ctexture.cpp
index 0f2e812e8..0a16e5896 100755
--- a/src/graphics/ctexture.cpp
+++ b/src/graphics/ctexture.cpp
@@ -251,31 +251,44 @@ void cTexture::SetTextureFilter(const EE_TEX_FILTER& filter) {
}
}
-void cTexture::ReplaceColor(eeColorA ColorKey, eeColorA NewColor) {
+void cTexture::ReplaceColor( const eeColorA& ColorKey, const eeColorA& NewColor ) {
+ Lock();
+
+ cImage::ReplaceColor( ColorKey, NewColor );
+
+ Unlock( false, true );
+}
+
+void cTexture::CreateMaskFromColor( const eeColorA& ColorKey, Uint8 Alpha ) {
Lock( true );
- eeUint Pos = 0;
+ cImage::ReplaceColor( ColorKey, eeColorA( ColorKey.R(), ColorKey.G(), ColorKey.B(), Alpha ) );
- for ( eeUint i = 0; i < mWidth * mHeight; i++ ) {
- Pos = i * mChannels;
-
- if ( mPixels[ Pos ] == ColorKey.R() && mPixels[ Pos + 1 ] == ColorKey.G() && mPixels[ Pos + 2 ] == ColorKey.B() && mPixels[ Pos + 3 ] == ColorKey.A() ) {
- mPixels[ Pos ] = NewColor.R();
- mPixels[ Pos + 1 ] = NewColor.G();
- mPixels[ Pos + 2 ] = NewColor.B();
- mPixels[ Pos + 3 ] = NewColor.A();
- }
- }
-
- Unlock(false, true);
+ Unlock( false, true );
}
-void cTexture::CreateMaskFromColor(eeColorA ColorKey, Uint8 Alpha) {
- ReplaceColor( ColorKey, eeColorA( ColorKey.R(), ColorKey.G(), ColorKey.B(), Alpha ) );
+void cTexture::FillWithColor( const eeColorA& Color ) {
+ Lock();
+
+ cImage::FillWithColor( Color );
+
+ Unlock( false, true );
}
-void cTexture::CreateMaskFromColor(eeColor ColorKey, Uint8 Alpha) {
- CreateMaskFromColor( eeColorA( ColorKey.R(), ColorKey.G(), ColorKey.B(), 255 ), Alpha );
+void cTexture::Resize( const eeUint& new_width, const eeUint& new_height ) {
+ Lock();
+
+ cImage::Resize( new_width, new_height );
+
+ Unlock( false, true );
+}
+
+void cTexture::CopyImage( cImage * Img, const eeUint& x, const eeUint& y ) {
+ Lock();
+
+ cImage::CopyImage( Img, x, y );
+
+ Unlock( false, true );
}
bool cTexture::LocalCopy() {
diff --git a/src/graphics/ctexture.hpp b/src/graphics/ctexture.hpp
index 1b708a932..a43933c10 100755
--- a/src/graphics/ctexture.hpp
+++ b/src/graphics/ctexture.hpp
@@ -94,14 +94,20 @@ class EE_API cTexture : public cImage {
/** Save the Texture to a new File */
bool SaveToFile( const std::string& filepath, const EE_SAVETYPE& Format );
- /** Create an Alpha mask from a Color */
- void CreateMaskFromColor(eeColorA ColorKey, Uint8 Alpha);
-
- /** Create an Alpha mask from a Color */
- void CreateMaskFromColor(eeColor ColorKey, Uint8 Alpha);
-
/** Replace a color on the texture */
- void ReplaceColor(eeColorA ColorKey, eeColorA NewColor);
+ void ReplaceColor( const eeColorA& ColorKey, const eeColorA& NewColor);
+
+ /** Create an Alpha mask from a Color */
+ void CreateMaskFromColor( const eeColorA& ColorKey, Uint8 Alpha );
+
+ /** Fill a texture with a color */
+ void FillWithColor( const eeColorA& Color );
+
+ /** Resize the texture */
+ void Resize( const eeUint& new_width, const eeUint& new_height );
+
+ /** Copy an image inside the texture */
+ void CopyImage( cImage * Img, const eeUint& x, const eeUint& y );
/** @return If the Texture has a copy on the local memory */
bool LocalCopy();
diff --git a/src/graphics/ctexturegrouploader.cpp b/src/graphics/ctexturegrouploader.cpp
new file mode 100644
index 000000000..787612fdd
--- /dev/null
+++ b/src/graphics/ctexturegrouploader.cpp
@@ -0,0 +1,129 @@
+#include "ctexturegrouploader.hpp"
+#include "cshapegroup.hpp"
+#include "cshapegroupmanager.hpp"
+
+namespace EE { namespace Graphics {
+
+cTextureGroupLoader::cTextureGroupLoader() :
+ mThreaded(false),
+ mLoaded(false),
+ mAppPath( AppPath() )
+{
+}
+
+cTextureGroupLoader::cTextureGroupLoader( const std::string& TextureGroupPath, const bool& Threaded ) :
+ mTextureGroupPath( TextureGroupPath ),
+ mThreaded( Threaded ),
+ mLoaded(false),
+ mAppPath( AppPath() )
+{
+ Load();
+}
+
+cTextureGroupLoader::~cTextureGroupLoader()
+{
+}
+
+void cTextureGroupLoader::Update() {
+ mRL.Update();
+
+ if ( mRL.IsLoaded() && !mLoaded )
+ CreateShapes();
+}
+
+void cTextureGroupLoader::Load( const std::string& TextureGroupPath ) {
+ mRL.Threaded( mThreaded );
+
+ if ( TextureGroupPath.size() )
+ mTextureGroupPath = TextureGroupPath;
+
+ sTextureGroupHdr TexGrHdr;
+
+ std::fstream fs ( mTextureGroupPath.c_str() , std::ios::in | std::ios::binary );
+
+ if ( fs.is_open() ) {
+ fs.read( reinterpret_cast (&TexGrHdr), sizeof(sTextureGroupHdr) );
+
+ if ( TexGrHdr.Magic == ( ( 'E' << 0 ) | ( 'E' << 8 ) | ( 'T' << 16 ) | ( 'G' << 24 ) ) ) {
+ for ( Uint32 i = 0; i < TexGrHdr.TextureCount; i++ ) {
+ sTextureHdr tTextureHdr;
+ sTempTexGroup tTexGroup;
+
+ fs.read( reinterpret_cast (&tTextureHdr), sizeof(sTextureHdr) );
+
+ tTexGroup.Texture = tTextureHdr;
+ tTexGroup.Shapes.resize( tTextureHdr.ShapeCount );
+
+ std::string name( &tTextureHdr.Name[0] );
+ std::string path( FileRemoveFileName( mTextureGroupPath ) + name );
+
+ mRL.Add( new cTextureLoader( path ) );
+
+ fs.read( reinterpret_cast (&tTexGroup.Shapes[0]), sizeof(sShapeHdr) * tTextureHdr.ShapeCount );
+
+ mTempGroups.push_back( tTexGroup );
+ }
+ }
+
+ mRL.Load();
+
+ if ( !mThreaded )
+ CreateShapes();
+ }
+}
+
+void cTextureGroupLoader::CreateShapes() {
+ cShapeGroup * tSG = NULL;
+
+ for ( Uint32 z = 0; z < mTempGroups.size(); z++ ) {
+ sTempTexGroup * tTexGroup = &mTempGroups[z];
+ sTextureHdr * tTexHdr = &tTexGroup->Texture;
+
+ std::string name( &tTexHdr->Name[0] );
+ std::string path( FileRemoveFileName( mTextureGroupPath ) + name );
+
+ Int32 pos = StrStartsWith( mAppPath, path );
+
+ if ( -1 != pos && (Uint32)(pos + 1) < path.size() )
+ path = path.substr( pos + 1 );
+
+ cTexture * tTex = cTextureFactory::instance()->GetByName( path );
+
+ // Create the Shape Group with the name of the real texture, not the Childs ( example load 1.png and not 1_ch1.png )
+ if ( 0 == z ) {
+ tSG = new cShapeGroup( name );
+ cShapeGroupManager::instance()->Add( tSG );
+ }
+
+ if ( NULL != tTex ) {
+ for ( Int32 i = 0; i < tTexHdr->ShapeCount; i++ ) {
+ sShapeHdr * tSh = &tTexGroup->Shapes[i];
+
+ std::string ShapeName( &tSh->Name[0] );
+ eeRecti tRect( tSh->X, tSh->Y, tSh->X + tSh->Width, tSh->Y + tSh->Height );
+
+ tSG->Add( new cShape( tTex->TexId(), tRect, tSh->DestWidth, tSh->DestHeight, tSh->OffsetX, tSh->OffsetY, ShapeName ) );
+ }
+ } else {
+ /** @TODO: Error Report */
+ return;
+ }
+ }
+
+ mLoaded = true;
+}
+
+bool cTextureGroupLoader::Threaded() const {
+ return mThreaded;
+}
+
+void cTextureGroupLoader::Threaded( const bool& threaded ) {
+ mThreaded = threaded;
+}
+
+const bool& cTextureGroupLoader::IsLoaded() const {
+ return mLoaded;
+}
+
+}}
+
diff --git a/src/graphics/ctexturegrouploader.hpp b/src/graphics/ctexturegrouploader.hpp
new file mode 100644
index 000000000..2359b1b06
--- /dev/null
+++ b/src/graphics/ctexturegrouploader.hpp
@@ -0,0 +1,50 @@
+#ifndef EE_GRAPHICSCTEXTUREGROUPLOADER_HPP
+#define EE_GRAPHICSCTEXTUREGROUPLOADER_HPP
+
+#include "base.hpp"
+#include "packerhelper.hpp"
+#include "ctextureloader.hpp"
+#include "ctexturefactory.hpp"
+#include "../system/cresourceloader.hpp"
+
+namespace EE { namespace Graphics {
+
+using namespace Private;
+
+class EE_API cTextureGroupLoader {
+ public:
+ cTextureGroupLoader();
+
+ cTextureGroupLoader( const std::string& TextureGroupPath, const bool& Threaded = false );
+
+ ~cTextureGroupLoader();
+
+ void Update();
+
+ void Load( const std::string& TextureGroupPath = "" );
+
+ bool Threaded() const;
+
+ void Threaded( const bool& threaded );
+
+ const bool& IsLoaded() const;
+ protected:
+ cResourceLoader mRL;
+ std::string mTextureGroupPath;
+ bool mThreaded;
+ bool mLoaded;
+ std::string mAppPath;
+
+ typedef struct sTempTexGroupS {
+ sTextureHdr Texture;
+ std::vector Shapes;
+ } sTempTexGroup;
+
+ std::vector mTempGroups;
+
+ void CreateShapes();
+};
+
+}}
+
+#endif
diff --git a/src/graphics/ctextureloader.cpp b/src/graphics/ctextureloader.cpp
index 2c7175d23..5ad63dce9 100644
--- a/src/graphics/ctextureloader.cpp
+++ b/src/graphics/ctextureloader.cpp
@@ -1,5 +1,6 @@
#include "ctextureloader.hpp"
#include "ctexturefactory.hpp"
+#define STBI_TYPE_SPECIFIC_FUNCTIONS
#include "../helper/SOIL/stb_image.h"
#include "../helper/SOIL/SOIL.h"
diff --git a/src/graphics/ctexturepacker.cpp b/src/graphics/ctexturepacker.cpp
new file mode 100644
index 000000000..7561dda5f
--- /dev/null
+++ b/src/graphics/ctexturepacker.cpp
@@ -0,0 +1,670 @@
+#include "ctexturepacker.hpp"
+#include "cimage.hpp"
+#include "../helper/SOIL/SOIL.h"
+
+namespace EE { namespace Graphics {
+
+cTexturePacker::cTexturePacker() :
+ mLongestEdge(0),
+ mTotalArea(0),
+ mFreeList(NULL),
+ mWidth(0),
+ mHeight(0),
+ mPacked(false),
+ mAllowFlipping(false),
+ mChild(NULL),
+ mStrategy(PackBig),
+ mCount(0),
+ mParent(NULL),
+ mPlacedCount(0)
+{
+}
+
+cTexturePacker::~cTexturePacker()
+{
+ Close();
+}
+
+void cTexturePacker::Close() {
+ mLongestEdge = 0;
+ mTotalArea = 0;
+ mTextures.clear();
+
+ if ( NULL != mFreeList ) {
+ cTexturePackerNode * next = mFreeList;
+ cTexturePackerNode * kill = NULL;
+
+ while ( NULL != next ) {
+ kill = next;
+
+ next = next->GetNext();
+
+ eeSAFE_DELETE( kill );
+ }
+ }
+
+ eeSAFE_DELETE( mChild );
+}
+
+void cTexturePacker::NewFree( Int32 x, Int32 y, Int32 width, Int32 height ) {
+ cTexturePackerNode * node = new cTexturePackerNode( x, y, width, height );
+ node->SetNext( mFreeList );
+ mFreeList = node;
+}
+
+bool cTexturePacker::MergeNodes() {
+ cTexturePackerNode *f = mFreeList;
+
+ while ( f ) {
+ cTexturePackerNode * prev = 0;
+ cTexturePackerNode * c = mFreeList;
+
+ while ( c ) {
+ if ( f != c ) {
+ if ( f->Merge( *c ) ) {
+ assert( prev );
+
+ prev->SetNext( c->GetNext() );
+
+ eeSAFE_DELETE( c );
+
+ return true;
+ }
+ }
+
+ prev = c;
+ c = c->GetNext();
+ }
+
+ f = f->GetNext();
+ }
+
+ return false;
+}
+
+void cTexturePacker::Validate() {
+#ifdef EE_DEBUG
+ cTexturePackerNode * f = mFreeList;
+ while ( f ) {
+ cTexturePackerNode * c = mFreeList;
+
+ while ( c ) {
+ if ( f != c )
+ f->Validate(c);
+
+ c = c->GetNext();
+ }
+
+ f = f->GetNext();
+ }
+#endif
+}
+
+cTexturePackerTex * cTexturePacker::GetLonguestEdge() {
+ cTexturePackerTex * t = NULL;
+ std::list::iterator it;
+
+ for ( it = mTextures.begin(); it != mTextures.end(); it++ ) {
+ if ( !(*it).Placed() ) {
+ t = &(*it);
+ break;
+ }
+ }
+
+ return t;
+}
+
+cTexturePackerTex * cTexturePacker::GetShortestEdge() {
+ cTexturePackerTex * t = NULL;
+ std::list::reverse_iterator it;
+
+ for ( it = mTextures.rbegin(); it != mTextures.rend(); it++ ) {
+ if ( !(*it).Placed() ) {
+ t = &(*it);
+ break;
+ }
+ }
+
+ return t;
+}
+
+void cTexturePacker::AddBorderToTextures( const Int32& BorderSize ) {
+ cTexturePackerTex * t;
+
+ if ( 0 != BorderSize ) {
+ std::list::iterator it;
+
+ for ( it = mTextures.begin(); it != mTextures.end(); it++ ) {
+ t = &(*it);
+
+ t->Width ( t->Width() + BorderSize );
+ t->Height ( t->Height() + BorderSize );
+ }
+
+ mLongestEdge += BorderSize;
+ }
+}
+
+cTexturePackerNode * cTexturePacker::GetBestFit( cTexturePackerTex * t, cTexturePackerNode ** prevBestFit, Int32 * EdgeCount ) {
+ Int32 leastY = 0x7FFFFFFF;
+ Int32 leastX = 0x7FFFFFFF;
+ cTexturePackerNode * previousBestFit = NULL;
+ cTexturePackerNode * bestFit = NULL;
+ cTexturePackerNode * previous = NULL;
+ cTexturePackerNode * search = mFreeList;
+ Int32 edgeCount = 0;
+
+ // Walk the singly linked list of free nodes
+ // see if it will fit into any currently free space
+ while ( search ) {
+ Int32 ec;
+
+ // see if the texture will fit into this slot, and if so how many edges does it share.
+ if ( search->Fits( t->Width(), t->Height(), ec, mAllowFlipping ) ) {
+
+ if ( ec == 2 ) {
+ previousBestFit = previous; // record the pointer previous to this one (used to patch the linked list)
+ bestFit = search; // record the best fit.
+ edgeCount = ec;
+
+ break;
+ }
+
+ if ( search->Y() < leastY ) {
+ leastY = search->Y();
+ leastX = search->X();
+ previousBestFit = previous;
+ bestFit = search;
+ edgeCount = ec;
+ } else if ( search->Y() == leastY && search->X() < leastX ) {
+ leastX = search->X();
+ previousBestFit = previous;
+ bestFit = search;
+ edgeCount = ec;
+ }
+ }
+
+ previous = search;
+ search = search->GetNext();
+ }
+
+ *EdgeCount = edgeCount;
+ *prevBestFit = previousBestFit;
+
+ return bestFit;
+}
+
+void cTexturePacker::InsertTexture( cTexturePackerTex * t, cTexturePackerNode * bestFit, Int32 edgeCount, cTexturePackerNode * previousBestFit ) {
+ if ( NULL != bestFit ) {
+ Validate();
+
+ switch ( edgeCount ) {
+ case 0:
+ {
+ bool flipped = false;
+ int w = t->Width();
+ int h = t->Height();
+
+ if ( mAllowFlipping ) {
+ if ( t->LongestEdge() <= bestFit->Width() ) {
+ if ( h > w ) {
+ w = t->Height();
+ h = t->Width();
+ flipped = true;
+ }
+ } else {
+ assert( t->LongestEdge() <= bestFit->Height() );
+
+ if ( h < w ) {
+ w = t->Height();
+ h = t->Width();
+ flipped = true;
+ }
+ }
+ }
+
+ t->Place( bestFit->X(), bestFit->Y(), flipped ); // place it.
+
+ NewFree( bestFit->X(), bestFit->Y() + h, bestFit->Width(), bestFit->Height() - h );
+
+ bestFit->X ( bestFit->X() + w );
+ bestFit->Width ( bestFit->Width() - w );
+ bestFit->Height ( h );
+
+ Validate();
+ }
+ break;
+ case 1:
+ {
+ if ( t->Width() == bestFit->Width() ) {
+ t->Place( bestFit->X(), bestFit->Y(), false );
+
+ bestFit->Y ( bestFit->Y() + t->Height() );
+ bestFit->Height ( bestFit->Height() - t->Height() );
+
+ Validate();
+ } else if ( t->Height() == bestFit->Height() ) {
+ t->Place( bestFit->X(), bestFit->Y(), false );
+
+ bestFit->X ( bestFit->X() + t->Width() );
+ bestFit->Width ( bestFit->Width() - t->Width() );
+
+ Validate();
+ } else if ( mAllowFlipping && t->Width() == bestFit->Height() ) {
+ t->Place( bestFit->X(), bestFit->Y(), true );
+
+ bestFit->X ( bestFit->X() + t->Height() );
+ bestFit->Width ( bestFit->Width() - t->Height() );
+
+ Validate();
+ } else if ( mAllowFlipping && t->Height() == bestFit->Width() ) {
+ t->Place( bestFit->X(), bestFit->Y(), true );
+
+ bestFit->Y ( bestFit->Y() + t->Width() );
+ bestFit->Height ( bestFit->Height() - t->Width() );
+
+ Validate();
+ }
+ }
+ break;
+ case 2:
+ {
+ bool flipped = t->Width() != bestFit->Width() || t->Height() != bestFit->Height();
+
+ t->Place( bestFit->X(), bestFit->Y(), flipped );
+
+ if ( previousBestFit )
+ previousBestFit->SetNext( bestFit->GetNext() );
+ else
+ mFreeList = bestFit->GetNext();
+
+ eeSAFE_DELETE( bestFit );
+
+ Validate();
+ }
+ break;
+ }
+
+ while ( MergeNodes() ); // keep merging nodes as much as we can...
+ }
+}
+
+void cTexturePacker::CreateChild( const Uint32& MaxWidth, const Uint32& MaxHeight, const bool& ForcePowOfTwo, const Uint32& PixelBorder, const bool& AllowFlipping ) {
+ mChild = new cTexturePacker();
+
+ std::list::iterator it;
+ cTexturePackerTex * t = NULL;
+
+ for ( it = mTextures.begin(); it != mTextures.end(); it++ ) {
+ t = &(*it);
+
+ if ( !t->Placed() ) {
+ mChild->AddTexture( t->Name() );
+ mChild->mParent = this;
+
+ t->Disabled( true );
+
+ mCount--;
+ }
+ }
+
+ mChild->PackTextures( MaxWidth, MaxHeight, ForcePowOfTwo, PixelBorder, AllowFlipping );
+}
+
+bool cTexturePacker::AddTexturesPath( std::string TexturesPath ) {
+ if ( IsDirectory( TexturesPath ) ) {
+
+ if ( TexturesPath[ TexturesPath.size() - 1 ] != '/' && TexturesPath[ TexturesPath.size() - 1 ] != '\\' )
+ TexturesPath += "/";
+
+ std::vector files = FilesGetInPath( TexturesPath );
+ std::sort( files.begin(), files.end() );
+
+ for ( Uint32 i = 0; i < files.size(); i++ ) {
+ std::string path( TexturesPath + files[i] );
+ if ( !IsDirectory( path ) )
+ AddTexture( path );
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool cTexturePacker::AddTexture( const std::string& TexturePath ) {
+ if ( FileExists( TexturePath ) ) {
+ cTexturePackerTex TPack( TexturePath );
+
+ if ( TPack.LoadedInfo() ) {
+ if ( TPack.Width() > mLongestEdge )
+ mLongestEdge = TPack.Width();
+
+ if ( TPack.Height() > mLongestEdge )
+ mLongestEdge = TPack.Height();
+
+ mTotalArea += TPack.Area();
+
+ // Insert ordered
+ std::list::iterator it;
+
+ bool Added = false;
+
+ for ( it = mTextures.begin(); it != mTextures.end(); it++ ) {
+ if ( (*it).Area() < TPack.Area() ) {
+ mTextures.insert( it, TPack );
+ Added = true;
+ break;
+ }
+ }
+
+ if ( !Added ) {
+ mTextures.push_back( TPack );
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+Int32 cTexturePacker::PackTextures( const Uint32& MaxWidth, const Uint32& MaxHeight, const bool& ForcePowOfTwo, const Uint32& PixelBorder, const bool& AllowFlipping ) { // pack the textures, the return code is the amount of wasted/unused area.
+ mAllowFlipping = AllowFlipping;
+ Int32 Width = MaxWidth;
+ Int32 Height = MaxHeight;
+ cTexturePackerTex * t = NULL;
+
+ AddBorderToTextures( (Int32)PixelBorder );
+
+ if ( ForcePowOfTwo && !IsPow2( Width ) )
+ Width = NextPowOfTwo( Width );
+
+ if ( ForcePowOfTwo && !IsPow2( Height ) )
+ Height = NextPowOfTwo( Height );
+
+ NewFree( 0, 0, Width, Height );
+
+ mCount = mTextures.size();
+
+ // We must place each texture
+ std::list::iterator it;
+ for ( it = mTextures.begin(); it != mTextures.end(); it++ ) {
+ // For the texture with the longest edge we place it according to this criteria.
+ // (1) If it is a perfect match, we always accept it as it causes the least amount of fragmentation.
+ // (2) A match of one edge with the minimum area left over after the split.
+ // (3) No edges match, so look for the node which leaves the least amount of area left over after the split.
+
+ if ( PackBig == mStrategy )
+ t = GetLonguestEdge();
+ else if ( PackTiny == mStrategy )
+ t = GetShortestEdge();
+
+ cTexturePackerNode * previousBestFit = NULL;
+ Int32 edgeCount = 0;
+ cTexturePackerNode * bestFit = GetBestFit( t, &previousBestFit, &edgeCount );
+
+ if ( NULL == bestFit ) {
+ if ( PackBig == mStrategy ) {
+ mStrategy = PackTiny;
+ #ifdef EE_DEBUG
+ printf( "Chaging Strategy to Tiny. %s faults.\n", t->Name().c_str() );
+ #endif
+ } else if ( PackTiny == mStrategy ) {
+ mStrategy = PackFail;
+ #ifdef EE_DEBUG
+ printf( "Strategy fail, must create a new image. %s faults.\n", t->Name().c_str() );
+ #endif
+ }
+ } else {
+ InsertTexture( t, bestFit, edgeCount, previousBestFit );
+ mCount--;
+ }
+
+ if ( PackFail == mStrategy ) {
+ #ifdef EE_DEBUG
+ printf( "Creating a new image as a child.\n" );
+ #endif
+ CreateChild( MaxWidth, MaxHeight, ForcePowOfTwo, PixelBorder, AllowFlipping );
+ break;
+ }
+ }
+
+ if ( mCount > 0 ) {
+ #ifdef EE_DEBUG
+ printf( "Creating a new image as a child. Some textures couldn't get it: %d\n", mCount );
+ #endif
+ CreateChild( MaxWidth, MaxHeight, ForcePowOfTwo, PixelBorder, AllowFlipping );
+ }
+
+ AddBorderToTextures( -( (Int32)PixelBorder ) );
+
+ if ( ForcePowOfTwo )
+ Height = NextPowOfTwo( Height );
+
+ mWidth = Width;
+ mHeight = Height;
+ mPacked = true;
+
+ for ( it = mTextures.begin(); it != mTextures.end(); it++ ) {
+ if ( !(*it).Placed() )
+ mTotalArea -= (*it).Area();
+ }
+
+ #ifdef EE_DEBUG
+ printf( "Total Area Used: %d. This represents the %4.2f percent \n", mTotalArea, ( (eeDouble)mTotalArea / (eeDouble)( mWidth * mHeight ) ) * 100.0 );
+ #endif
+
+ return ( Width * Height ) - mTotalArea;
+}
+
+void cTexturePacker::Save( const std::string& Filepath, const EE_SAVETYPE& Format ) {
+ mFilepath = Filepath;
+
+ cImage Img( (Uint32)mWidth, (Uint32)mHeight, (Uint32)4 );
+
+ Img.FillWithColor( eeColorA(0,0,0,0) );
+
+ cTexturePackerTex * t = NULL;
+ int w, h, c;
+ std::list::iterator it;
+
+ for ( it = mTextures.begin(); it != mTextures.end(); it++ ) {
+ t = &(*it);
+
+ if ( t->Placed() ) {
+ Uint8 * data = SOIL_load_image( t->Name().c_str(), &w, &h, &c, 0 );
+
+ if ( NULL != data && t->Width() == w && t->Height() == h ) {
+ cImage * ImgCopy = new cImage( data, w, h, c );
+
+ Img.CopyImage( ImgCopy, t->X(), t->Y() );
+
+ ImgCopy->AvoidFreeImage( true );
+
+ eeSAFE_DELETE( ImgCopy );
+
+ SOIL_free_image_data( data );
+
+ mPlacedCount++;
+ }
+ }
+ }
+
+ Img.SaveToFile( Filepath, Format );
+
+ ChildSave( Format );
+
+ SaveShapes();
+}
+
+Int32 cTexturePacker::GetChildCount() {
+ cTexturePacker * Child = mChild;
+ Int32 ChildCount = 0;
+
+ while ( NULL != Child ) {
+ ChildCount++;
+ Child = Child->GetChild();
+ }
+
+ return ChildCount;
+}
+
+void cTexturePacker::SaveShapes() {
+ if ( NULL != mParent )
+ return;
+
+ sTextureGroupHdr TexGrHdr;
+
+ TexGrHdr.Magic = ( ( 'E' << 0 ) | ( 'E' << 8 ) | ( 'T' << 16 ) | ( 'G' << 24 ) );
+ TexGrHdr.TextureCount = 1 + GetChildCount();
+
+ sTextureHdr TexHdr[ TexGrHdr.TextureCount ];
+
+ TexHdr[ 0 ] = CreateTextureHdr( this );
+
+ Int32 HdrPos = 1;
+ cTexturePacker * Child = mChild;
+
+ while ( NULL != Child ) {
+ TexHdr[ HdrPos ] = CreateTextureHdr( Child );
+ Child = Child->GetChild();
+ HdrPos++;
+ }
+
+ std::vector tShapesHdr;
+
+ std::string path = FileRemoveExtension( mFilepath ) + ".etg";
+ std::fstream fs ( path.c_str() , std::ios::out | std::ios::binary );
+
+ if ( fs.is_open() ) {
+ fs.write( reinterpret_cast (&TexGrHdr), sizeof(sTextureGroupHdr) );
+
+ fs.write( reinterpret_cast (&TexHdr[ 0 ]), sizeof(sTextureHdr) );
+
+ CreateShapesHdr( this, tShapesHdr, &fs );
+
+ if ( tShapesHdr.size() )
+ fs.write( reinterpret_cast (&tShapesHdr[ 0 ]), sizeof(sShapeHdr) * tShapesHdr.size() );
+
+ Int32 HdrPos = 1;
+ cTexturePacker * Child = mChild;
+
+ while ( NULL != Child ) {
+ fs.write( reinterpret_cast (&TexHdr[ HdrPos ]), sizeof(sTextureHdr) );
+
+ CreateShapesHdr( Child, tShapesHdr, &fs );
+
+ if ( tShapesHdr.size() )
+ fs.write( reinterpret_cast (&tShapesHdr[ 0 ]), sizeof(sShapeHdr) * tShapesHdr.size() );
+
+ Child = Child->GetChild();
+
+ HdrPos++;
+ }
+
+ fs.close();
+ }
+}
+
+void cTexturePacker::CreateShapesHdr( cTexturePacker * Packer, std::vector& Shapes, std::fstream * fs ) {
+ Shapes.clear();
+
+ sShapeHdr tShapeHdr;
+
+ std::list tTextures = *(Packer->GetTexturePackPtr());
+ std::list::iterator it;
+ cTexturePackerTex * tTex;
+
+ for ( it = tTextures.begin(); it != tTextures.end(); it++ ) {
+ tTex = &(*it);
+
+ if ( tTex->Placed() ) {
+ std::string name = FileNameFromPath(tTex->Name() );
+
+ memset( tShapeHdr.Name, 0, HDR_NAME_SIZE );
+ StrCopy( tShapeHdr.Name, name.c_str(), HDR_NAME_SIZE );
+
+ tShapeHdr.ResourceID = MakeHash( name );
+ tShapeHdr.Width = tTex->Width();
+ tShapeHdr.Height = tTex->Height();
+ tShapeHdr.DestWidth = tTex->Width();
+ tShapeHdr.DestHeight = tTex->Height();
+ tShapeHdr.OffsetX = 0;
+ tShapeHdr.OffsetY = 0;
+ tShapeHdr.X = tTex->X();
+ tShapeHdr.Y = tTex->Y();
+ tShapeHdr.Date = FileGetModificationDate( tTex->Name() );
+
+ fs->write( reinterpret_cast (&tShapeHdr), sizeof(sShapeHdr) );
+ }
+ }
+}
+
+sTextureHdr cTexturePacker::CreateTextureHdr( cTexturePacker * Packer ) {
+ sTextureHdr TexHdr;
+
+ std::string name( FileNameFromPath( Packer->GetFilepath() ) );
+
+ memset( TexHdr.Name, 0, HDR_NAME_SIZE );
+ StrCopy( TexHdr.Name, name.c_str(), HDR_NAME_SIZE );
+
+ TexHdr.ResourceID = MakeHash( name );
+ TexHdr.Size = FileSize( Packer->GetFilepath() );
+ TexHdr.Width = Packer->GetWidth();
+ TexHdr.Height = Packer->GetHeight();
+ TexHdr.ShapeCount = Packer->GetPlacedCount();
+
+ return TexHdr;
+}
+
+void cTexturePacker::ChildSave( const EE_SAVETYPE& Format ) {
+ if ( NULL != mChild ) {
+ cTexturePacker * Parent = mChild->GetParent();
+ cTexturePacker * LastParent = NULL;
+ Int32 ParentCount = 0;
+
+ // Find the grand parent
+ while ( NULL != Parent ) {
+ ParentCount++;
+ LastParent = Parent;
+ Parent = Parent->GetParent();
+ }
+
+ std::string fFpath = FileRemoveExtension( LastParent->GetFilepath() );
+ std::string fExt = FileExtension( LastParent->GetFilepath() );
+ std::string fName = fFpath + "_ch" + toStr( ParentCount ) + "." + fExt;
+
+ mChild->Save( fName, Format );
+ }
+}
+
+cTexturePacker * cTexturePacker::GetChild() const {
+ return mChild;
+}
+
+cTexturePacker * cTexturePacker::GetParent() const {
+ return mParent;
+}
+
+std::list * cTexturePacker::GetTexturePackPtr() {
+ return &mTextures;
+}
+
+const std::string& cTexturePacker::GetFilepath() const {
+ return mFilepath;
+}
+
+const Int32& cTexturePacker::GetWidth() const {
+ return mWidth;
+}
+
+const Int32& cTexturePacker::GetHeight() const {
+ return mHeight;
+}
+
+const Int32& cTexturePacker::GetPlacedCount() const {
+ return mPlacedCount;
+}
+
+}}
diff --git a/src/graphics/ctexturepacker.hpp b/src/graphics/ctexturepacker.hpp
new file mode 100644
index 000000000..eef272135
--- /dev/null
+++ b/src/graphics/ctexturepacker.hpp
@@ -0,0 +1,130 @@
+#ifndef EE_GRAPHICSCTEXTUREATLAS
+#define EE_GRAPHICSCTEXTUREATLAS
+
+/*!
+**
+** Copyright (c) 2009 by John W. Ratcliff mailto:jratcliffscarab@gmail.com
+**
+** The MIT license:
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is furnished
+** to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in all
+** copies or substantial portions of the Software.
+
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+/*! NOTE by Martin Lucas Golini
+** This implementation is based on the John W. Ratcliff texture atlas implementation.
+** Implementation differ from the original, but i use the base texture atlas algorithm.
+*/
+
+#include "base.hpp"
+#include "packerhelper.hpp"
+#include "ctexturepackernode.hpp"
+#include "ctexturepackertex.hpp"
+
+namespace EE { namespace Graphics {
+
+using namespace Private;
+
+class EE_API cTexturePacker {
+ public:
+ cTexturePacker();
+
+ ~cTexturePacker();
+
+ bool AddTexture( const std::string& TexturePath );
+
+ bool AddTexturesPath( std::string TexturesPath );
+
+ Int32 PackTextures( const Uint32& MaxWidth, const Uint32& MaxHeight, const bool& ForcePowOfTwo = true, const Uint32& PixelBorder = 0, const bool& AllowFlipping = false );
+
+ void Save( const std::string& Filepath, const EE_SAVETYPE& Format = EE_SAVE_TYPE_DDS );
+
+ void Close();
+
+ inline const Int32& Width() const { return mWidth; }
+
+ inline const Int32& Height() const { return mHeight; }
+ protected:
+ enum PackStrategy {
+ PackBig,
+ PackTiny,
+ PackFail
+ };
+
+ std::list mTextures;
+
+ Int32 mLongestEdge;
+ Int32 mTotalArea;
+ cTexturePackerNode * mFreeList;
+ Int32 mWidth;
+ Int32 mHeight;
+ bool mPacked;
+ bool mAllowFlipping;
+ cTexturePacker * mChild;
+ Int32 mStrategy;
+ Int32 mCount;
+ cTexturePacker * mParent;
+ std::string mFilepath;
+ Int32 mPlacedCount;
+
+ cTexturePacker * GetChild() const;
+
+ cTexturePacker * GetParent() const;
+
+ std::list * GetTexturePackPtr();
+
+ const std::string& GetFilepath() const;
+
+ void ChildSave( const EE_SAVETYPE& Format );
+
+ void SaveShapes();
+
+ void NewFree( Int32 x, Int32 y, Int32 width, Int32 height );
+
+ bool MergeNodes();
+
+ void Validate();
+
+ cTexturePackerTex * GetLonguestEdge();
+
+ cTexturePackerTex * GetShortestEdge();
+
+ Int32 GetChildCount();
+
+ const Int32& GetWidth() const;
+
+ const Int32& GetHeight() const;
+
+ const Int32& GetPlacedCount() const;
+
+ sTextureHdr CreateTextureHdr( cTexturePacker * Packer );
+
+ void CreateShapesHdr( cTexturePacker * Packer, std::vector& Shapes, std::fstream * fs );
+
+ cTexturePackerNode * GetBestFit( cTexturePackerTex * t, cTexturePackerNode ** prevBestFit, Int32 * EdgeCount );
+
+ void InsertTexture( cTexturePackerTex * t, cTexturePackerNode * bestFit, Int32 edgeCount, cTexturePackerNode * previousBestFit );
+
+ void AddBorderToTextures( const Int32& BorderSize );
+
+ void CreateChild( const Uint32& MaxWidth, const Uint32& MaxHeight, const bool& ForcePowOfTwo, const Uint32& PixelBorder, const bool& AllowFlipping );
+};
+
+}}
+
+#endif
diff --git a/src/graphics/ctexturepackernode.cpp b/src/graphics/ctexturepackernode.cpp
new file mode 100644
index 000000000..14a97c6e6
--- /dev/null
+++ b/src/graphics/ctexturepackernode.cpp
@@ -0,0 +1,100 @@
+#include "ctexturepackernode.hpp"
+
+namespace EE { namespace Graphics { namespace Private {
+
+cTexturePackerNode::cTexturePackerNode( Int32 x, Int32 y, Int32 width, Int32 height ) {
+ mX = x;
+ mY = y;
+ mWidth = width;
+ mHeight = height;
+ mNext = NULL;
+}
+
+cTexturePackerNode * cTexturePackerNode::GetNext() const {
+ return mNext;
+}
+
+bool cTexturePackerNode::Fits( Int32 width, Int32 height, Int32 &edgeCount, const bool& AllowFlipping ) const {
+ bool ret = false;
+
+ edgeCount = 0;
+
+ if ( width == mWidth || height == mHeight || width == mHeight || height == mWidth ) {
+ if ( width == mWidth ) {
+ edgeCount++;
+ if ( height == mHeight ) edgeCount++;
+ }
+ else if ( AllowFlipping && width == mHeight ) {
+ edgeCount++;
+ if ( height == mWidth ) edgeCount++;
+ }
+ else if ( AllowFlipping && height == mWidth ) {
+ edgeCount++;
+ }
+ else if ( height == mHeight ) {
+ edgeCount++;
+ }
+ }
+
+ if ( width <= mWidth && height <= mHeight ) {
+ ret = true;
+ } else if ( AllowFlipping && height <= mWidth && width <= mHeight ) {
+ ret = true;
+ }
+
+ return ret;
+}
+
+void cTexturePackerNode::GetRect( eeRecti &r ) const {
+ r = eeRecti( mX, mY, mX + mWidth - 1, mY + mHeight - 1 );
+}
+
+void cTexturePackerNode::Validate( cTexturePackerNode * n ) {
+ eeRecti r1;
+ eeRecti r2;
+ GetRect( r1 );
+ n->GetRect( r2 );
+ assert( !r1.Intersect(r2) );
+}
+
+bool cTexturePackerNode::Merge( const cTexturePackerNode& n ) {
+ bool ret = false;
+
+ eeRecti r1;
+ eeRecti r2;
+
+ GetRect( r1 );
+ n.GetRect( r2 );
+
+ r1.Right++;
+ r1.Bottom++;
+ r2.Right++;
+ r2.Bottom++;
+
+ if ( r1.Left == r2.Left && r1.Right == r2.Right && r1.Top == r2.Bottom ) // if we share the top edge then..
+ {
+ mY = n.Y();
+ mHeight += n.Height();
+ ret = true;
+ }
+ else if ( r1.Left == r2.Left && r1.Right == r2.Right && r1.Bottom == r2.Top ) // if we share the bottom edge
+ {
+ mHeight += n.Height();
+ ret = true;
+ }
+ else if ( r1.Top == r2.Top && r1.Bottom == r2.Top && r1.Left == r2.Right ) // if we share the left edge
+ {
+ mX = n.X();
+ mWidth += n.Width();
+ ret = true;
+ }
+ else if ( r1.Top == r2.Top && r1.Bottom == r2.Top && r1.Right == r2.Left ) // if we share the left edge
+ {
+ mWidth += n.Width();
+ ret = true;
+ }
+
+ return ret;
+}
+
+}}}
diff --git a/src/graphics/ctexturepackernode.hpp b/src/graphics/ctexturepackernode.hpp
new file mode 100644
index 000000000..a6e393718
--- /dev/null
+++ b/src/graphics/ctexturepackernode.hpp
@@ -0,0 +1,49 @@
+#ifndef EE_GRAPHICSPRIVATECTEXTUREPACKERNODE
+#define EE_GRAPHICSPRIVATECTEXTUREPACKERNODE
+
+#include "base.hpp"
+
+namespace EE { namespace Graphics { namespace Private {
+
+class cTexturePackerNode {
+ public:
+ cTexturePackerNode( Int32 x, Int32 y, Int32 width, Int32 height );
+
+ bool Fits( Int32 wid, Int32 hit, Int32 &edgeCount, const bool& AllowFlipping = false ) const;
+
+ void GetRect( eeRecti &r ) const;
+
+ void Validate( cTexturePackerNode * n );
+
+ bool Merge( const cTexturePackerNode &n );
+
+ cTexturePackerNode * GetNext() const;
+
+ inline void SetNext( cTexturePackerNode * Next ) { mNext = Next; }
+
+ inline const Int32& X() const { return mX; }
+
+ inline const Int32& Y() const { return mY; }
+
+ inline void X( const Int32& x ) { mX = x; }
+
+ inline void Y( const Int32& y ) { mY = y; }
+
+ inline const Int32& Width() const { return mWidth; }
+
+ inline const Int32& Height() const { return mHeight; }
+
+ inline void Width( const Int32& W ) { mWidth = W; }
+
+ inline void Height( const Int32& H ) { mHeight = H; }
+ protected:
+ cTexturePackerNode * mNext;
+ Int32 mX;
+ Int32 mY;
+ Int32 mWidth;
+ Int32 mHeight;
+};
+
+}}}
+
+#endif
diff --git a/src/graphics/ctexturepackertex.cpp b/src/graphics/ctexturepackertex.cpp
new file mode 100644
index 000000000..67a4be16f
--- /dev/null
+++ b/src/graphics/ctexturepackertex.cpp
@@ -0,0 +1,38 @@
+#include "ctexturepackertex.hpp"
+#include "../helper/SOIL/stb_image.h"
+
+namespace EE { namespace Graphics { namespace Private {
+
+cTexturePackerTex::cTexturePackerTex( const std::string& Name ) :
+ mName(Name),
+ mWidth(0),
+ mHeight(0),
+ mX(0),
+ mY(0),
+ mLongestEdge(0),
+ mArea(0),
+ mFlipped(false),
+ mPlaced(false),
+ mLoadedInfo(false),
+ mDisabled(false)
+{
+ Int32 c;
+
+ if ( stbi_info( Name.c_str(), &mWidth, &mHeight, &c ) ) {
+ mArea = mWidth * mHeight;
+ mLongestEdge = ( mWidth >= mHeight ) ? mWidth : mHeight;
+ mLoadedInfo = true;
+ }
+}
+
+void cTexturePackerTex::Place( Int32 x, Int32 y, bool flipped ) {
+ if ( !mPlaced ) {
+ mX = x;
+ mY = y;
+ mFlipped = flipped;
+ mPlaced = true;
+ }
+}
+
+}}}
+
diff --git a/src/graphics/ctexturepackertex.hpp b/src/graphics/ctexturepackertex.hpp
new file mode 100644
index 000000000..8510aff28
--- /dev/null
+++ b/src/graphics/ctexturepackertex.hpp
@@ -0,0 +1,61 @@
+#ifndef EE_GRAPHICSPRIVATECTEXTUREPACKERTEX
+#define EE_GRAPHICSPRIVATECTEXTUREPACKERTEX
+
+#include "base.hpp"
+
+namespace EE { namespace Graphics { namespace Private {
+
+class cTexturePackerTex {
+ public:
+ cTexturePackerTex( const std::string& Name );
+
+ void Place( Int32 x, Int32 y, bool flipped );
+
+ inline const std::string& Name() const { return mName; }
+
+ inline const Int32& X() const { return mX; }
+
+ inline const Int32& Y() const { return mY; }
+
+ inline void X( const Int32& x ) { mX = x; }
+
+ inline void Y( const Int32& y ) { mY = y; }
+
+ inline const Int32& Width() const { return mWidth; }
+
+ inline const Int32& Height() const { return mHeight; }
+
+ inline void Width( const Int32& W ) { mWidth = W; }
+
+ inline void Height( const Int32& H ) { mHeight = H; }
+
+ inline const bool& LoadedInfo() const { return mLoadedInfo; }
+
+ inline const Int32& Area() const { return mArea; }
+
+ inline const bool& Placed() const { return mPlaced; }
+
+ inline const bool& Flipped() const { return mFlipped; }
+
+ inline const Int32& LongestEdge() const { return mLongestEdge; }
+
+ inline const bool& Disabled() const { return mDisabled; }
+
+ inline void Disabled( const bool& d ) { mDisabled = d; }
+ protected:
+ std::string mName;
+ Int32 mWidth;
+ Int32 mHeight;
+ Int32 mX;
+ Int32 mY;
+ Int32 mLongestEdge;
+ Int32 mArea;
+ bool mFlipped;
+ bool mPlaced;
+ bool mLoadedInfo;
+ bool mDisabled;
+};
+
+}}}
+
+#endif
diff --git a/src/graphics/packerhelper.hpp b/src/graphics/packerhelper.hpp
new file mode 100644
index 000000000..6376c2140
--- /dev/null
+++ b/src/graphics/packerhelper.hpp
@@ -0,0 +1,40 @@
+#ifndef EE_PACKER_HELPER
+#define EE_PACKER_HELPER
+
+#include "base.hpp"
+
+namespace EE { namespace Graphics { namespace Private {
+
+#define HDR_NAME_SIZE 64
+
+typedef struct sShapeHdrS {
+ char Name[ HDR_NAME_SIZE ];
+ Uint32 Date;
+ Int32 X;
+ Int32 Y;
+ Int32 Width;
+ Int32 Height;
+ Uint32 ResourceID;
+ Int32 OffsetX;
+ Int32 OffsetY;
+ Int32 DestWidth;
+ Int32 DestHeight;
+} sShapeHdr;
+
+typedef struct sTextureHdrS {
+ char Name[ HDR_NAME_SIZE ];
+ Uint32 ResourceID;
+ Uint32 Size;
+ Int32 Width;
+ Int32 Height;
+ Int32 ShapeCount;
+} sTextureHdr;
+
+typedef struct sTextureGroupHdrS {
+ Uint32 Magic;
+ Uint32 TextureCount;
+} sTextureGroupHdr;
+
+}}}
+
+#endif
diff --git a/src/helper/SOIL/stb_image.c b/src/helper/SOIL/stb_image.c
index 6907820a2..0c5d96ea9 100644
--- a/src/helper/SOIL/stb_image.c
+++ b/src/helper/SOIL/stb_image.c
@@ -1,4 +1,4 @@
-/* stbi-1.28 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
+/* stbi-1.29 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
when you control the images you're loading
no warranty implied; use at your own risk
@@ -20,7 +20,9 @@
- decoded from memory or through stdio FILE (define STBI_NO_STDIO to remove code)
- supports installable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
- Latest revisions:
+ Latest revisions:
+ 1.30 (2010-08-18) added stbi_info support for BMP,PSD,HDR,PIC by Martin Golini
+ 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville
1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ)
1.27 (2010-08-01) cast-to-uint8 to fix warnings (Laurent Gomila)
allow trailing 0s at end of image data (Laurent Gomila)
@@ -42,7 +44,6 @@
See end of file for full revision history.
TODO:
- stbi_info support for BMP,PSD,HDR,PIC
rewrite stbi_info and load_file variations to share file handling code
(current system allows individual functions to be called directly,
since each does all the work, but I doubt anyone uses this in practice)
@@ -62,6 +63,8 @@
Extensions, features Janez Zemva
Jetro Lauha (stbi_info) Jonathan Blow
James "moose2000" Brown (iPhone PNG) Laurent Gomila
+ Aruelien Pocheville
+ Martin Golini
If your name should be here but isn't, let Sean know.
@@ -108,10 +111,6 @@ typedef unsigned char validate_uint32[sizeof(uint32)==4 ? 1 : -1];
#define STBI_NO_WRITE
#endif
-#ifndef STBI_NO_DDS
-#include "stbi_DDS.h"
-#endif
-
#define STBI_NOTUSED(v) v=v
#ifdef _MSC_VER
@@ -162,10 +161,15 @@ extern int stbi_png_info_from_file (FILE *f, int *x, int
extern int stbi_bmp_test_memory (stbi_uc const *buffer, int len);
extern stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp);
-extern stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_bmp_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_bmp_test_file (FILE *f);
-extern stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+extern stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_bmp_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_bmp_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it a tga?
@@ -182,30 +186,45 @@ extern stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int
extern int stbi_psd_test_memory (stbi_uc const *buffer, int len);
extern stbi_uc *stbi_psd_load (char const *filename, int *x, int *y, int *comp, int req_comp);
-extern stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_psd_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_psd_test_file (FILE *f);
-extern stbi_uc *stbi_psd_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+extern stbi_uc *stbi_psd_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_psd_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_psd_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it an hdr?
extern int stbi_hdr_test_memory (stbi_uc const *buffer, int len);
extern float * stbi_hdr_load (char const *filename, int *x, int *y, int *comp, int req_comp);
-extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_hdr_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_hdr_test_file (FILE *f);
-extern float * stbi_hdr_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+extern float * stbi_hdr_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_hdr_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_hdr_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it a pic?
extern int stbi_pic_test_memory (stbi_uc const *buffer, int len);
extern stbi_uc *stbi_pic_load (char const *filename, int *x, int *y, int *comp, int req_comp);
-extern stbi_uc *stbi_pic_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern stbi_uc *stbi_pic_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_pic_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_pic_test_file (FILE *f);
-extern stbi_uc *stbi_pic_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+extern stbi_uc *stbi_pic_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_pic_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_pic_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it a gif?
@@ -221,7 +240,10 @@ extern stbi_uc *stbi_gif_load_from_file (FILE *f, int *x, int
extern int stbi_gif_info (char const *filename, int *x, int *y, int *comp);
extern int stbi_gif_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
-
+
+#ifndef STBI_NO_DDS
+#include "stbi_DDS.h"
+#endif
// this is not threadsafe
static const char *failure_reason;
@@ -400,6 +422,8 @@ int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len)
#ifndef STBI_NO_HDR
return stbi_hdr_test_memory(buffer, len);
#else
+ STBI_NOTUSED(buffer);
+ STBI_NOTUSED(len);
return 0;
#endif
}
@@ -489,7 +513,7 @@ static void start_mem(stbi *s, uint8 const *buffer, int len)
#ifndef STBI_NO_STDIO
static void refill_buffer(stbi *s)
{
- int n = (int)fread(s->buffer_start, 1, s->buflen, s->img_file);
+ int n = fread(s->buffer_start, 1, s->buflen, s->img_file);
if (n == 0) {
s->from_file = 0;
s->img_buffer = s->img_buffer_end-1;
@@ -536,7 +560,7 @@ static void skip(stbi *s, int n)
{
#ifndef STBI_NO_STDIO
if (s->img_file) {
- int blen = (int)( s->img_buffer_end - s->img_buffer );
+ int blen = s->img_buffer_end - s->img_buffer;
if (blen < n) {
s->img_buffer = s->img_buffer_end;
fseek(s->img_file, n - blen, SEEK_CUR);
@@ -551,7 +575,7 @@ static int getn(stbi *s, stbi_uc *buffer, int n)
{
#ifndef STBI_NO_STDIO
if (s->img_file) {
- int blen = (int)( s->img_buffer_end - s->img_buffer );
+ int blen = s->img_buffer_end - s->img_buffer;
if (blen < n) {
int res;
memcpy(buffer, s->img_buffer, blen);
@@ -741,7 +765,7 @@ typedef struct
typedef struct
{
- #if STBI_SIMD
+ #ifdef STBI_SIMD
unsigned short dequant2[4][64];
#endif
stbi s;
@@ -1020,7 +1044,7 @@ __forceinline static uint8 clamp(int x)
t1 += p2+p4; \
t0 += p1+p3;
-#if STBI_SIMD
+#ifdef STBI_SIMD
typedef unsigned short stbi_dequantize_t;
#else
typedef uint8 stbi_dequantize_t;
@@ -1135,7 +1159,7 @@ static int parse_entropy_coded_data(jpeg *z)
reset(z);
if (z->scan_n == 1) {
int i,j;
- #if STBI_SIMD
+ #ifdef STBI_SIMD
__declspec(align(16))
#endif
short data[64];
@@ -1149,7 +1173,7 @@ static int parse_entropy_coded_data(jpeg *z)
for (j=0; j < h; ++j) {
for (i=0; i < w; ++i) {
if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0;
- #if STBI_SIMD
+ #ifdef STBI_SIMD
stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]);
#else
idct_block(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]);
@@ -1179,7 +1203,7 @@ static int parse_entropy_coded_data(jpeg *z)
int x2 = (i*z->img_comp[n].h + x)*8;
int y2 = (j*z->img_comp[n].v + y)*8;
if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0;
- #if STBI_SIMD
+ #ifdef STBI_SIMD
stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]);
#else
idct_block(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]);
@@ -1227,7 +1251,7 @@ static int process_marker(jpeg *z, int m)
if (t > 3) return e("bad DQT table","Corrupt JPEG");
for (i=0; i < 64; ++i)
z->dequant[t][dezigzag[i]] = get8u(&z->s);
- #if STBI_SIMD
+ #ifdef STBI_SIMD
for (i=0; i < 64; ++i)
z->dequant2[t][i] = z->dequant[t][i];
#endif
@@ -1547,7 +1571,7 @@ static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const
}
}
-#if STBI_SIMD
+#ifdef STBI_SIMD
static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row;
void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func)
@@ -1656,7 +1680,7 @@ static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int re
if (n >= 3) {
uint8 *y = coutput[0];
if (z->s.img_n == 3) {
- #if STBI_SIMD
+ #ifdef STBI_SIMD
stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n);
#else
YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s.img_x, n);
@@ -1704,9 +1728,18 @@ unsigned char *stbi_jpeg_load(char const *filename, int *x, int *y, int *comp, i
unsigned char *stbi_jpeg_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp)
{
+ #ifdef STBI_SMALL_STACK
+ unsigned char *result;
+ jpeg *j = (jpeg *) malloc(sizeof(*j));
+ start_mem(&j->s, buffer, len);
+ result = load_jpeg_image(j,x,y,comp,req_comp);
+ free(j);
+ return result;
+ #else
jpeg j;
start_mem(&j.s, buffer,len);
return load_jpeg_image(&j, x,y,comp,req_comp);
+ #endif
}
static int stbi_jpeg_info_raw(jpeg *j, int *x, int *y, int *comp)
@@ -3061,7 +3094,7 @@ stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int
stbi s;
start_mem(&s, buffer, len);
return bmp_load(&s, x,y,comp,req_comp);
-}
+}
// Targa Truevision - TGA
// by Jonathan Dummer
@@ -3075,12 +3108,9 @@ static int tga_info(stbi *s, int *x, int *y, int *comp)
if( sz > 1 ) return 0; // only RGB or indexed allowed
sz = get8u(s); // image type
// only RGB or grey allowed, +/- RLE
- if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0;
- get16le(s); // discard palette start
- get16le(s); // discard palette length
- get8(s); // discard bits per palette color entry
- get16le(s); // discard x origin
- get16le(s); // discard y origin
+ if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0;
+ skip(s,9);
+
tga_w = get16le(s);
if( tga_w < 1 ) return 0; // test width
tga_h = get16le(s);
@@ -3095,6 +3125,7 @@ static int tga_info(stbi *s, int *x, int *y, int *comp)
return 1; // seems to have passed everything
}
+#ifndef STBI_NO_STDIO
int stbi_tga_info_from_file(FILE *f, int *x, int *y, int *comp)
{
stbi s;
@@ -3105,6 +3136,7 @@ int stbi_tga_info_from_file(FILE *f, int *x, int *y, int *comp)
fseek(f, n, SEEK_SET);
return r;
}
+#endif
int stbi_tga_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp)
{
@@ -4500,11 +4532,20 @@ int stbi_info_from_file(FILE *f, int *x, int *y, int *comp)
if (stbi_png_info_from_file(f, x, y, comp))
return 1;
if (stbi_gif_info_from_file(f, x, y, comp))
+ return 1;
+ if (stbi_bmp_info_from_file(f, x, y, comp))
+ return 1;
+ if (stbi_psd_info_from_file(f, x, y, comp))
+ return 1;
+ if (stbi_pic_info_from_file(f, x, y, comp))
return 1;
- // @TODO: stbi_bmp_info_from_file
- // @TODO: stbi_psd_info_from_file
+ #ifndef STBI_NO_DDS
+ if (stbi_dds_info_from_file(f, x, y, comp, NULL))
+ return 1;
+ #endif
#ifndef STBI_NO_HDR
- // @TODO: stbi_hdr_info_from_file
+ if (stbi_hdr_info_from_file(f, x, y, comp))
+ return 1;
#endif
// test tga last because it's a crappy test!
if (stbi_tga_info_from_file(f, x, y, comp))
@@ -4520,11 +4561,20 @@ int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *c
if (stbi_png_info_from_memory(buffer, len, x, y, comp))
return 1;
if (stbi_gif_info_from_memory(buffer, len, x, y, comp))
+ return 1;
+ if(stbi_bmp_info_from_memory(buffer, len, x, y, comp))
return 1;
- // @TODO: stbi_bmp_info_from_memory
- // @TODO: stbi_psd_info_from_memory
+ if(stbi_psd_info_from_memory(buffer, len, x, y, comp))
+ return 1;
+ if(stbi_pic_info_from_memory(buffer, len, x, y, comp))
+ return 1;
+ #ifndef STBI_NO_DDS
+ if (stbi_dds_info_from_memory(buffer, len, x, y, comp, NULL))
+ return 1;
+ #endif
#ifndef STBI_NO_HDR
- // @TODO: stbi_hdr_info_from_memory
+ if(stbi_hdr_info_from_memory(buffer, len, x, y, comp))
+ return 1;
#endif
// test tga last because it's a crappy test!
if (stbi_tga_info_from_memory(buffer, len, x, y, comp))
@@ -4535,12 +4585,233 @@ int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *c
// add in my DDS loading support
#ifndef STBI_NO_DDS
#include "stbi_DDS_c.h"
-#endif
+#endif
+
+static int bmp_info(stbi *s, int *x, int *y, int *comp) {
+ int hsz;
+ if (get8(s) != 'B' || get8(s) != 'M') return 0;
+ skip(s,12);
+ hsz = get32le(s);
+ if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return 0;
+ if (hsz == 12) {
+ *x = get16le(s);
+ *y = get16le(s);
+ } else {
+ *x = get32le(s);
+ *y = get32le(s);
+ }
+ if (get16le(s) != 1) return 0;
+ *comp = get16le(s) / 8;
+ return 1;
+}
+
+int stbi_bmp_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp)
+{
+ stbi s;
+ start_mem(&s,buffer, len);
+ return bmp_info( &s, x, y, comp );
+}
+
+#ifndef STBI_NO_STDIO
+int stbi_bmp_info(char const *filename, int *x, int *y, int *comp)
+{
+ int res;
+ FILE *f = fopen(filename, "rb");
+ if (!f) return 0;
+ res = stbi_bmp_info_from_file( f, x, y, comp );
+ fclose(f);
+ return res;
+}
+
+int stbi_bmp_info_from_file(FILE *f, int *x, int *y, int *comp)
+{
+ stbi s;
+ int res;
+ long n = ftell(f);
+ start_file(&s, f);
+ res = bmp_info(&s, x, y, comp);
+ fseek(f, n, SEEK_SET);
+ return res;
+}
+#endif
+
+static int psd_info(stbi *s, int *x, int *y, int *comp)
+{
+ int channelCount;
+ if (get32(s) != 0x38425053) return 0;
+ if (get16(s) != 1) return 0;
+ skip(s, 6);
+ channelCount = get16(s);
+ if (channelCount < 0 || channelCount > 16) return 0;
+ *y = get32(s);
+ *x = get32(s);
+ if (get16(s) != 8) return 0;
+ if (get16(s) != 3) return 0;
+ *comp = 4;
+ return 1;
+}
+
+int stbi_psd_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp)
+{
+ stbi s;
+ start_mem(&s,buffer, len);
+ return psd_info( &s, x, y, comp );
+}
+
+#ifndef STBI_NO_STDIO
+int stbi_psd_info(char const *filename, int *x, int *y, int *comp)
+{
+ int res;
+ FILE *f = fopen(filename, "rb");
+ if (!f) return 0;
+ res = stbi_psd_info_from_file( f, x, y, comp );
+ fclose(f);
+ return res;
+}
+
+int stbi_psd_info_from_file(FILE *f, int *x, int *y, int *comp)
+{
+ stbi s;
+ int res;
+ long n = ftell(f);
+ start_file(&s, f);
+ res = psd_info(&s, x, y, comp);
+ fseek(f, n, SEEK_SET);
+ return res;
+}
+#endif
+
+static int pic_info(stbi *s, int *x, int *y, int *comp)
+{
+ skip(s, 92);
+
+ *x = get16(s);
+ *y = get16(s);
+ if (at_eof(s)) return 0;
+ if ((1 << 28) / (*x) < (*y)) return 0;
+
+ skip(s, 8);
+
+ int act_comp=0,num_packets=0,chained;
+ pic_packet_t packets[10];
+
+ do {
+ pic_packet_t *packet;
+
+ if (num_packets==sizeof(packets)/sizeof(packets[0]))
+ return 0;
+
+ packet = &packets[num_packets++];
+ chained = get8(s);
+ packet->size = get8u(s);
+ packet->type = get8u(s);
+ packet->channel = get8u(s);
+ act_comp |= packet->channel;
+
+ if (at_eof(s)) return 0;
+ if (packet->size != 8) return 0;
+ } while (chained);
+
+ *comp = (act_comp & 0x10 ? 4 : 3);
+
+ return 1;
+}
+
+int stbi_pic_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp)
+{
+ stbi s;
+ start_mem(&s,buffer, len);
+ return pic_info( &s, x, y, comp );
+}
+
+#ifndef STBI_NO_STDIO
+int stbi_pic_info(char const *filename, int *x, int *y, int *comp)
+{
+ int res;
+ FILE *f = fopen(filename, "rb");
+ if (!f) return 0;
+ res = stbi_pic_info_from_file( f, x, y, comp );
+ fclose(f);
+ return res;
+}
+
+int stbi_pic_info_from_file(FILE *f, int *x, int *y, int *comp)
+{
+ stbi s;
+ int res;
+ long n = ftell(f);
+ start_file(&s, f);
+ res = pic_info(&s, x, y, comp);
+ fseek(f, n, SEEK_SET);
+ return res;
+}
+#endif
+
+#ifndef STBI_NO_HDR
+static int hdr_info(stbi *s, int *x, int *y, int *comp)
+{
+ char buffer[HDR_BUFLEN];
+ char *token;
+ int valid = 0;
+
+ if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) return 0;
+
+ for(;;) {
+ token = hdr_gettoken(s,buffer);
+ if (token[0] == 0) break;
+ if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1;
+ }
+
+ if (!valid) return 0;
+ token = hdr_gettoken(s,buffer);
+ if (strncmp(token, "-Y ", 3)) return 0;
+ token += 3;
+ *y = strtol(token, &token, 10);
+ while (*token == ' ') ++token;
+ if (strncmp(token, "+X ", 3)) return 0;
+ token += 3;
+ *x = strtol(token, NULL, 10);
+ *comp = 3;
+ return 1;
+}
+
+int stbi_hdr_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp)
+{
+ stbi s;
+ start_mem(&s,buffer, len);
+ return hdr_info( &s, x, y, comp );
+}
+
+#ifndef STBI_NO_STDIO
+int stbi_hdr_info(char const *filename, int *x, int *y, int *comp)
+{
+ int res;
+ FILE *f = fopen(filename, "rb");
+ if (!f) return 0;
+ res = stbi_hdr_info_from_file( f, x, y, comp );
+ fclose(f);
+ return res;
+}
+
+int stbi_hdr_info_from_file(FILE *f, int *x, int *y, int *comp)
+{
+ stbi s;
+ int res;
+ long n = ftell(f);
+ start_file(&s, f);
+ res = hdr_info(&s, x, y, comp);
+ fseek(f, n, SEEK_SET);
+ return res;
+}
+#endif
+#endif
#endif // STBI_HEADER_FILE_ONLY
/*
- revision history:
+ revision history:
+ 1.30 (2010-08-18) added stbi_info support for BMP,PSD,HDR,PIC by Martin Golini
+ 1.29 (2010-08-16) various warning fixes from Aurelien Pocheville
1.28 (2010-08-01) fix bug in GIF palette transparency (SpartanJ)
1.27 (2010-08-01)
cast-to-uint8 to fix warnings
diff --git a/src/helper/SOIL/stb_image.h b/src/helper/SOIL/stb_image.h
index 85a22d292..6bd8b725a 100644
--- a/src/helper/SOIL/stb_image.h
+++ b/src/helper/SOIL/stb_image.h
@@ -210,7 +210,7 @@ typedef struct
extern int stbi_register_loader(stbi_loader *loader);
// define faster low-level operations (typically SIMD support)
-#if STBI_SIMD
+#ifdef STBI_SIMD
typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize);
// compute an integer IDCT on "input"
// input[x] = data[x] * dequantize[x]
@@ -232,7 +232,6 @@ extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func);
// TYPE-SPECIFIC ACCESS
-
#ifdef STBI_TYPE_SPECIFIC_FUNCTIONS
// is it a jpeg?
@@ -267,9 +266,14 @@ extern int stbi_bmp_test_memory (stbi_uc const *buffer, int len);
extern stbi_uc *stbi_bmp_load (char const *filename, int *x, int *y, int *comp, int req_comp);
extern stbi_uc *stbi_bmp_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_bmp_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_bmp_test_file (FILE *f);
extern stbi_uc *stbi_bmp_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_bmp_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_bmp_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it a tga?
@@ -277,9 +281,14 @@ extern int stbi_tga_test_memory (stbi_uc const *buffer, int len);
extern stbi_uc *stbi_tga_load (char const *filename, int *x, int *y, int *comp, int req_comp);
extern stbi_uc *stbi_tga_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_tga_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_tga_test_file (FILE *f);
extern stbi_uc *stbi_tga_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_tga_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_tga_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it a psd?
@@ -287,9 +296,14 @@ extern int stbi_psd_test_memory (stbi_uc const *buffer, int len);
extern stbi_uc *stbi_psd_load (char const *filename, int *x, int *y, int *comp, int req_comp);
extern stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_psd_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_psd_test_file (FILE *f);
extern stbi_uc *stbi_psd_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_psd_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_psd_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it an hdr?
@@ -297,9 +311,14 @@ extern int stbi_hdr_test_memory (stbi_uc const *buffer, int len);
extern float * stbi_hdr_load (char const *filename, int *x, int *y, int *comp, int req_comp);
extern float * stbi_hdr_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_hdr_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_hdr_test_file (FILE *f);
extern float * stbi_hdr_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_hdr_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_hdr_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it a pic?
@@ -307,9 +326,14 @@ extern int stbi_pic_test_memory (stbi_uc const *buffer, int len);
extern stbi_uc *stbi_pic_load (char const *filename, int *x, int *y, int *comp, int req_comp);
extern stbi_uc *stbi_pic_load_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
+extern int stbi_pic_info_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *comp);
+
#ifndef STBI_NO_STDIO
extern int stbi_pic_test_file (FILE *f);
extern stbi_uc *stbi_pic_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
+
+extern int stbi_pic_info (char const *filename, int *x, int *y, int *comp);
+extern int stbi_pic_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// is it a gif?
@@ -326,12 +350,12 @@ extern int stbi_gif_info (char const *filename, int *x, int
extern int stbi_gif_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
-#endif//STBI_TYPE_SPECIFIC_FUNCTIONS
-
-#ifndef STBI_NO_DDS
-#include "stbi_DDS.h"
+#ifndef STBI_NO_DDS
+#include "stbi_DDS.h"
#endif
+#endif//STBI_TYPE_SPECIFIC_FUNCTIONS
+
#ifdef __cplusplus
}
#endif
@@ -340,3 +364,4 @@ extern int stbi_gif_info_from_file (FILE *f, int *x, int
//
//// end header file /////////////////////////////////////////////////////
#endif // STBI_INCLUDE_STB_IMAGE_H
+
diff --git a/src/helper/SOIL/stbi_DDS_c.h b/src/helper/SOIL/stbi_DDS_c.h
index bf2f18d1e..eefbef451 100755
--- a/src/helper/SOIL/stbi_DDS_c.h
+++ b/src/helper/SOIL/stbi_DDS_c.h
@@ -338,9 +338,13 @@ int stbi_dds_info(char const *filename, int *x, int *y, int *comp, int *isco
int stbi_dds_info_from_file(FILE *f, int *x, int *y, int *comp, int *iscompressed)
{
- stbi s;
- start_file(&s, f);
- return dds_get_info( &s, x, y, comp, iscompressed );
+ stbi s;
+ int res;
+ long n = ftell(f);
+ start_file(&s, f);
+ res = dds_get_info(&s, x, y, comp, iscompressed);
+ fseek(f, n, SEEK_SET);
+ return res;
}
#endif
diff --git a/src/helper/haikuttf/sophist.h b/src/helper/haikuttf/sophist.h
index 0e8ac5933..3818b6b8e 100644
--- a/src/helper/haikuttf/sophist.h
+++ b/src/helper/haikuttf/sophist.h
@@ -1,4 +1,4 @@
-/* sophist.h - 0.2 - public domain - Sean Barrett 2010
+/* sophist.h - 0.3 - public domain - Sean Barrett 2010
** Knowledge drawn from Brian Hook's posh.h and http://predef.sourceforge.net
** Sophist provides portable types; you typedef/#define them to your own names
**
@@ -47,38 +47,40 @@ typedef unsigned short SOPHIST_uint16;
typedef unsigned int SOPHIST_uint32;
#endif
-#if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) \
- || (defined(__alpha) && defined(__DECC))
+#ifndef SOPHIST_NO_64
+ #if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) \
+ || (defined(__alpha) && defined(__DECC))
- typedef signed __int64 SOPHIST_int64;
- typedef unsigned __int64 SOPHIST_uint64;
- #define SOPHIST_has_64 1
- #define SOPHIST_int64_constant(x) (x##i64)
- #define SOPHIST_uint64_constant(x) (x##ui64)
- #define SOPHIST_printf_format64 "I64"
+ typedef signed __int64 SOPHIST_int64;
+ typedef unsigned __int64 SOPHIST_uint64;
+ #define SOPHIST_has_64 1
+ #define SOPHIST_int64_constant(x) (x##i64)
+ #define SOPHIST_uint64_constant(x) (x##ui64)
+ #define SOPHIST_printf_format64 "I64"
-#elif defined(__LP64__) || defined(__powerpc64__) || defined(SOPHIST_sparc64)
+ #elif defined(__LP64__) || defined(__powerpc64__) || defined(SOPHIST_sparc64)
- typedef signed long SOPHIST_int64;
- typedef unsigned long SOPHIST_uint64;
+ typedef signed long SOPHIST_int64;
+ typedef unsigned long SOPHIST_uint64;
- #define SOPHIST_has_64 1
- #define SOPHIST_int64_constant(x) ((SOPHIST_int64) x)
- #define SOPHIST_uint64_constant(x) ((SOPHIST_uint64) x)
- #define SOPHIST_printf_format64 "l"
+ #define SOPHIST_has_64 1
+ #define SOPHIST_int64_constant(x) ((SOPHIST_int64) x)
+ #define SOPHIST_uint64_constant(x) ((SOPHIST_uint64) x)
+ #define SOPHIST_printf_format64 "l"
-#elif defined(_LONG_LONG) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) \
- || defined(__GNUC__) || defined(__MWERKS__) || defined(__APPLE_CC__) \
- || defined(sgi) || defined (__sgi) || defined(__sgi__) \
- || defined(_CRAYC)
+ #elif defined(_LONG_LONG) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) \
+ || defined(__GNUC__) || defined(__MWERKS__) || defined(__APPLE_CC__) \
+ || defined(sgi) || defined (__sgi) || defined(__sgi__) \
+ || defined(_CRAYC)
- typedef signed long long SOPHIST_int64;
- typedef unsigned long long SOPHIST_uint64;
+ typedef signed long long SOPHIST_int64;
+ typedef unsigned long long SOPHIST_uint64;
- #define SOPHIST_has_64 1
- #define SOPHIST_int64_constant(x) (x##LL)
- #define SOPHIST_uint64_constant(x) (x##ULL)
- #define SOPHIST_printf_format64 "ll"
+ #define SOPHIST_has_64 1
+ #define SOPHIST_int64_constant(x) (x##LL)
+ #define SOPHIST_uint64_constant(x) (x##ULL)
+ #define SOPHIST_printf_format64 "ll"
+ #endif
#endif
#ifndef SOPHIST_has_64
@@ -142,7 +144,7 @@ SOPHIST_compiletime_assert(intptr, sizeof(SOPHIST_intptr) == sizeof(char *));
#define SOPHIST_endian SOPHIST_big_endian
#endif
-#endif // __INCLUDE_SOPHIST_H__
+#endif /* __INCLUDE_SOPHIST_H__ */
#ifdef SOPHIST_selftest
#include
@@ -154,6 +156,7 @@ int main(int argc, char **argv)
SOPHIST_uint8 bytes[4];
SOPHIST_uint32 num;
} x;
+
#if SOPHIST_has_64
char buffer[32];
sprintf(buffer, "%016" SOPHIST_printf_format64 "x",
@@ -175,6 +178,10 @@ int main(int argc, char **argv)
}
fputs(fail ? "Failed.\n" : "Passed.\n", stdout);
+
+ argc = argc; /* attempt to suppress unused variable warnings */
+ argv = argv;
+
return 0;
}
#endif
diff --git a/src/math/cmtrand.hpp b/src/math/cmtrand.hpp
index 8e7411e17..ae48758b8 100755
--- a/src/math/cmtrand.hpp
+++ b/src/math/cmtrand.hpp
@@ -65,7 +65,7 @@
namespace EE { namespace Math {
-class MTRand {
+class EE_API MTRand {
public:
static const Uint32 M = 397;
static const Int32 N = 624;
diff --git a/src/math/math.hpp b/src/math/math.hpp
index c6ce72273..d5fbc5b97 100755
--- a/src/math/math.hpp
+++ b/src/math/math.hpp
@@ -39,10 +39,17 @@ eeFloat EE_API Degrees( const eeFloat& Radians );
template
T NextPowOfTwo( T Size ) {
- T PowerOfTwo = 1;
- while (PowerOfTwo < Size)
- PowerOfTwo *= 2;
- return PowerOfTwo;
+ T p = 1;
+
+ while ( p < Size )
+ p <<= 1;
+
+ return p;
+}
+
+template
+T IsPow2( T v ) {
+ return ( ( v & ( v - 1 ) ) == 0 );
}
template
diff --git a/src/system/cobjectloader.hpp b/src/system/cobjectloader.hpp
index b754bb2e1..98a91d03a 100644
--- a/src/system/cobjectloader.hpp
+++ b/src/system/cobjectloader.hpp
@@ -6,7 +6,7 @@
namespace EE { namespace System {
-class cObjectLoader : cThread {
+class EE_API cObjectLoader : cThread {
public:
typedef boost::function1 ObjLoadCallback;
diff --git a/src/system/crc4.hpp b/src/system/crc4.hpp
index ac7d32e5a..3814dc3d9 100755
--- a/src/system/crc4.hpp
+++ b/src/system/crc4.hpp
@@ -6,7 +6,7 @@
namespace EE { namespace System {
/** @brief RC4 Encryption Class. For more information check Wikipedia: http://en.wikipedia.org/wiki/RC4. \n All the Decrypting functions call the Encrypting functions, there are there only for clarity, not really usefull. Use them as you wish. */
-class cRC4 {
+class EE_API cRC4 {
public:
cRC4();
~cRC4();
diff --git a/src/system/cresourceloader.cpp b/src/system/cresourceloader.cpp
index 3575bc125..112945b80 100644
--- a/src/system/cresourceloader.cpp
+++ b/src/system/cresourceloader.cpp
@@ -145,5 +145,9 @@ void cResourceLoader::SetLoaded() {
}
}
+eeFloat cResourceLoader::Progress() {
+ return ( (eeFloat)mObjsLoaded.size() / (eeFloat)( mObjs.size() + mObjsLoaded.size() ) ) * 100.f;
+}
+
}}
diff --git a/src/system/cresourceloader.hpp b/src/system/cresourceloader.hpp
index 82bb74372..5e8fa04d4 100644
--- a/src/system/cresourceloader.hpp
+++ b/src/system/cresourceloader.hpp
@@ -8,7 +8,7 @@ namespace EE { namespace System {
#define THREADS_AUTO (0xFFFFFFFF)
-class cResourceLoader {
+class EE_API cResourceLoader {
public:
typedef boost::function1 ResLoadCallback;
@@ -32,6 +32,8 @@ class cResourceLoader {
void Threaded( const bool& threaded );
bool Clear( const bool& ClearObjectsLoaded = true );
+
+ eeFloat Progress();
protected:
bool mLoaded;
bool mLoading;
diff --git a/src/system/ctimeelapsed.cpp b/src/system/ctimeelapsed.cpp
index 4a7ffa98c..c54ff440c 100755
--- a/src/system/ctimeelapsed.cpp
+++ b/src/system/ctimeelapsed.cpp
@@ -2,7 +2,7 @@
namespace EE { namespace System {
-cTimeElapsed::cTimeElapsed() : mFirstCheck( getMicroseconds() ), mLastCheck( getMicroseconds() ), mElapsed(0)
+cTimeElapsed::cTimeElapsed() : mFirstCheck( getMicroseconds() ), mLastCheck( getMicroseconds() ), mElapsed(0)
{
}
@@ -11,14 +11,14 @@ cTimeElapsed::~cTimeElapsed()
}
eeDouble cTimeElapsed::Elapsed() {
- mElapsed = ( getMicroseconds() - mLastCheck ) / (eeDouble)EE_CLOCKS_PER_SEC * 1000;
- mLastCheck = getMicroseconds();
-
+ mElapsed = (eeDouble)( getMicroseconds() - mLastCheck ) / 1000.0;
+ mLastCheck = getMicroseconds();
+
return mElapsed;
}
eeDouble cTimeElapsed::ElapsedSinceStart() {
- return ( getMicroseconds() - mFirstCheck ) / (eeDouble)EE_CLOCKS_PER_SEC * 1000;
+ return (eeDouble)( getMicroseconds() - mFirstCheck ) / 1000.0;
}
void cTimeElapsed::Reset() {
diff --git a/src/system/ctimeelapsed.hpp b/src/system/ctimeelapsed.hpp
index 744c8691b..dec1be77f 100755
--- a/src/system/ctimeelapsed.hpp
+++ b/src/system/ctimeelapsed.hpp
@@ -13,17 +13,17 @@ class EE_API cTimeElapsed : private cTimer {
~cTimeElapsed();
/** Time elapsed between this call and the last call to Elapsed() */
- eeDouble Elapsed();
+ eeDouble Elapsed();
/** Time elapsed between the last Reset ( First Reset is when the class is instantiated ) */
- eeDouble ElapsedSinceStart();
+ eeDouble ElapsedSinceStart();
/** Restart the initial counter. ( set it as now ) */
- void Reset();
+ void Reset();
protected:
- eeUint mFirstCheck;
- eeUint mLastCheck;
- eeDouble mElapsed;
+ eeUint mFirstCheck;
+ eeUint mLastCheck;
+ eeDouble mElapsed;
};
}}
diff --git a/src/system/ctimer.cpp b/src/system/ctimer.cpp
index e02330542..0ea228ea0 100755
--- a/src/system/ctimer.cpp
+++ b/src/system/ctimer.cpp
@@ -21,7 +21,7 @@ bool cTimer::setOption( const std::string key, const void * val ) {
// Get the current process core mask
DWORD procMask;
DWORD sysMask;
-
+
#if _MSC_VER >= 1400 && defined (_M_X64)
GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&procMask, (PDWORD_PTR)&sysMask);
#else
@@ -45,7 +45,7 @@ void cTimer::reset() {
// Get the current process core mask
DWORD procMask;
DWORD sysMask;
-
+
#if _MSC_VER >= 1400 && defined (_M_X64)
GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&procMask, (PDWORD_PTR)&sysMask);
#else
@@ -80,7 +80,7 @@ void cTimer::reset() {
mLastTime = 0;
mZeroClock = clock();
#else
- zeroClock = clock();
+ mZeroClock = clock();
gettimeofday(&start, NULL);
#endif
}
@@ -177,20 +177,12 @@ unsigned long cTimer::getMicroseconds() {
unsigned long cTimer::getMillisecondsCPU() {
clock_t newClock = clock();
- #if EE_PLATFORM == EE_PLATFORM_WIN32
- return (unsigned long)( (eeFloat)( newClock - mZeroClock ) / ( (eeFloat)CLOCKS_PER_SEC / 1000.0 ) );
- #else
- return (unsigned long)( (eeFloat)( newClock - zeroClock ) / ( (eeFloat)EE_CLOCKS_PER_SEC / 1000.0) );
- #endif
+ return (unsigned long)( (eeDouble)( newClock - mZeroClock ) / ( (eeDouble)CLOCKS_PER_SEC / 1000.0 ) );
}
unsigned long cTimer::getMicrosecondsCPU() {
clock_t newClock = clock();
- #if EE_PLATFORM == EE_PLATFORM_WIN32
- return (unsigned long)( (eeFloat)( newClock - mZeroClock ) / ( (eeFloat)CLOCKS_PER_SEC / 1000000.0 ) );
- #else
- return (unsigned long)( (eeFloat)( newClock - zeroClock ) / ((eeFloat)EE_CLOCKS_PER_SEC / 1000000.0) );
- #endif
+ return (unsigned long)( (eeDouble)( newClock - mZeroClock ) / ( (eeDouble)CLOCKS_PER_SEC / 1000000.0 ) );
}
}}
diff --git a/src/system/ctimer.hpp b/src/system/ctimer.hpp
index 2ac1868bf..6c707dc04 100644
--- a/src/system/ctimer.hpp
+++ b/src/system/ctimer.hpp
@@ -27,9 +27,8 @@ namespace EE { namespace System {
class EE_API cTimer {
private:
+ clock_t mZeroClock;
#if EE_PLATFORM == EE_PLATFORM_WIN32
- clock_t mZeroClock;
-
unsigned long mStartTick;
LONGLONG mLastTime;
LARGE_INTEGER mStartTime;
@@ -42,7 +41,6 @@ class EE_API cTimer {
}
#else
struct timeval start;
- clock_t zeroClock;
#endif
public:
/** Timer constructor. MUST be called on same thread that calls getMilliseconds() */
diff --git a/src/test/ee.cpp b/src/test/ee.cpp
index 299b9ec14..aac6c8932 100644
--- a/src/test/ee.cpp
+++ b/src/test/ee.cpp
@@ -1,11 +1,12 @@
#include "../ee.h"
/**
+@TODO Load Animated Sprites from Shape Groups.
+@TODO Create a texture packer tool ( texture atlas ).
@TODO Create a Vertex Buffer Object class ( with and without GL_ARB_vertex_buffer_object ).
@TODO Add support for Frame Buffer Object and to switch rendering to FBO and Screen.
@TODO Create a basic UI system ( add basic controls, add skinning support ).
@TODO Support multitexturing.
-@TODO Create a texture packer tool ( pack various textures into one texture ).
@TODO Encapsulate SDL and OpenGL ( and remove unnecessary dependencies ).
@TODO Add some Surface Grid class, to create special effects ( waved texture, and stuff like that ).
@TODO Support color cursors ( not only black and white cursors, that really sucks ) - Imposible with SDL 1.2
@@ -190,6 +191,8 @@ class cEETest : private cThread {
eeFloat mAxisY;
Uint32 mFace;
+
+ cTextureGroupLoader * mTGL;
};
@@ -254,6 +257,8 @@ void cEETest::Init() {
Scenes[1] = boost::bind( &cEETest::Screen2, this );
Scenes[2] = boost::bind( &cEETest::Screen3, this );
+ mTGL = new cTextureGroupLoader( MyPath + "res/1.etg", true );
+
InBuf.Start();
SetRandomSeed();
@@ -408,11 +413,11 @@ void cEETest::CmdSetPartsNum ( const std::vector < std::wstring >& params ) {
if ( params.size() >= 2 ) {
try {
Int32 tInt = boost::lexical_cast( wstringTostring( params[1] ) );
- if ( tInt >= 0 && tInt <= 10000 ) {
+ if ( tInt >= 0 && tInt <= 100000 ) {
PS[2].Create(WormHole, tInt, TN[5], EE->GetWidth() * 0.5f, EE->GetHeight() * 0.5f, 32, true);
Con.PushText( L"Wormhole Particles Number Changed to: " + toWStr(tInt) );
} else
- Con.PushText( L"Valid parameters are between 0 and 10000 (0 = no limit)." );
+ Con.PushText( L"Valid parameters are between 0 and 100000 (0 = no limit)." );
} catch (boost::bad_lexical_cast&) {
Con.PushText( L"Invalid Parameter. Expected int value from '" + params[1] + L"'." );
}
@@ -1088,6 +1093,19 @@ void cEETest::Process() {
else
mFontLoader.Update();
+ if ( !mTGL->IsLoaded() )
+ mTGL->Update();
+ else {
+ cShapeGroup * tSG = cShapeGroupManager::instance()->GetByName( "1.png" );
+
+ if ( NULL != tSG ) {
+ cShape * tS = tSG->GetByName( "rn01.png" );
+
+ if ( NULL != tS )
+ tS->Draw( 320, 0 );
+ }
+ }
+
if ( KM->IsKeyUp(KEY_F12) ) EE->TakeScreenshot( MyPath + "data/screenshots/" ); //After render and before Display
EE->Display();
@@ -1108,6 +1126,8 @@ void cEETest::End() {
cLog::instance()->Save();
+ delete mTGL;
+
cEngine::DestroySingleton();
}
@@ -1146,6 +1166,19 @@ void cEETest::Particles() {
int main (int argc, char * argv []) {
cEETest Test;
Test.Process();
+/*
+ cTexturePacker tp;
+ std::string Path = "/home/downloads/files/temp/bnb/allin/";
+
+ if ( argc > 1 )
+ Path = std::string( argv[1] );
+
+ tp.AddTexturesPath( Path );
+
+ tp.PackTextures( 256, 256 );
+
+ tp.Save( AppPath() + "res/1.png", EE_SAVE_TYPE_PNG );
+*/
return 0;
}
diff --git a/src/ui/cuibackground.hpp b/src/ui/cuibackground.hpp
index 0f7c2e1aa..fbb3a3393 100644
--- a/src/ui/cuibackground.hpp
+++ b/src/ui/cuibackground.hpp
@@ -5,7 +5,7 @@
namespace EE { namespace UI {
-class cUIBackground {
+class EE_API cUIBackground {
public:
cUIBackground();
cUIBackground( const eeColorA& Color, const eeUint& Corners = 0, const EE_RENDERALPHAS& BlendMode = ALPHA_NORMAL );
diff --git a/src/ui/cuiborder.hpp b/src/ui/cuiborder.hpp
index 477725f16..9019ef68d 100644
--- a/src/ui/cuiborder.hpp
+++ b/src/ui/cuiborder.hpp
@@ -5,7 +5,7 @@
namespace EE { namespace UI {
-class cUIBorder {
+class EE_API cUIBorder {
public:
cUIBorder();
cUIBorder( const cUIBorder& border );
diff --git a/src/utils/cinterpolation.hpp b/src/utils/cinterpolation.hpp
index d0cb11265..2aa428fbd 100644
--- a/src/utils/cinterpolation.hpp
+++ b/src/utils/cinterpolation.hpp
@@ -17,7 +17,7 @@ class Point1d {
typedef Point1d cPoint1df;
/** @brief A interpolation movement manager, used for movement interpolations. */
-class cInterpolation {
+class EE_API cInterpolation {
public:
cInterpolation();
diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp
index bc9a696a2..24aec9dce 100755
--- a/src/utils/utils.cpp
+++ b/src/utils/utils.cpp
@@ -16,9 +16,8 @@
#if EE_PLATFORM == EE_PLATFORM_WIN32
#include
-#else
- #include
#endif
+#include
#if EE_PLATFORM == EE_PLATFORM_WIN32
#include
@@ -32,14 +31,9 @@
namespace EE { namespace Utils {
-bool FileExists(const std::string& filepath) {
- std::fstream fs;
- fs.open( filepath.c_str(), std::ios::in );
- if( fs.is_open() ) {
- fs.close();
- return true;
- }
- return false;
+bool FileExists( const std::string& Filepath ) {
+ struct stat st;
+ return ( stat( Filepath.c_str(), &st ) == 0 );
}
Uint32 eeGetTicks() {
@@ -197,13 +191,13 @@ std::vector FilesGetInPath( const std::string& path ) {
}
Uint32 FileSize( const std::string& Filepath ) {
- std::ifstream f;
- f.open(Filepath.c_str(), std::ios_base::binary | std::ios_base::in);
- if (!f.good() || f.eof() || !f.is_open()) { return 0; }
- f.seekg(0, std::ios_base::beg);
- std::ifstream::pos_type begin_pos = f.tellg();
- f.seekg(0, std::ios_base::end);
- return static_cast(f.tellg() - begin_pos);
+ struct stat st;
+ int res = stat( Filepath.c_str(), &st );
+
+ if ( 0 == res )
+ return st.st_size;
+
+ return 0;
}
eeDouble GetSystemTime() {
@@ -337,6 +331,18 @@ std::string FileExtension( const std::string& filepath, const bool& lowerExt ) {
return tstr;
}
+std::string FileRemoveExtension( const std::string& filepath ) {
+ return filepath.substr( 0, filepath.find_last_of(".") );
+}
+
+std::string FileNameFromPath( const std::string& filepath ) {
+ return filepath.substr( filepath.find_last_of("/\\") + 1 );
+}
+
+std::string FileRemoveFileName( const std::string& filepath ) {
+ return filepath.substr( 0, filepath.find_last_of("/\\") + 1 );
+}
+
eeInt GetNumCPUs() {
eeInt nprocs = -1;
@@ -389,4 +395,14 @@ bool FileWrite( const std::string& filepath, const std::vector& data ) {
return FileWrite( filepath, reinterpret_cast ( &data[0] ), (Uint32)data.size() );
}
+Uint32 FileGetModificationDate( const std::string& Filepath ) {
+ struct stat st;
+ int res = stat( Filepath.c_str(), &st );
+
+ if ( 0 == res )
+ return st.st_mtime;
+
+ return 0;
+}
+
}}
diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp
index 631b1d64b..56279e178 100755
--- a/src/utils/utils.hpp
+++ b/src/utils/utils.hpp
@@ -5,7 +5,7 @@
namespace EE { namespace Utils {
/** @return True if the file exists */
- bool EE_API FileExists(const std::string& filepath);
+ bool EE_API FileExists( const std::string& Filepath );
/** @return The number of milliseconds since the EE++ library initialization. Note that this value wraps if the program runs for more than ~49 days. */
Uint32 EE_API eeGetTicks();
@@ -63,6 +63,15 @@ namespace EE { namespace Utils {
*/
std::string FileExtension( const std::string& filepath, const bool& lowerExt = true );
+ /** @return The file name of a file path */
+ std::string FileNameFromPath( const std::string& filepath );
+
+ /** @return Removes the file name from a path, and return the path. */
+ std::string FileRemoveFileName( const std::string& filepath );
+
+ /** @return Removes the extension of a filepath */
+ std::string FileRemoveExtension( const std::string& filepath );
+
/** Write a file in binary mode and close it. */
bool FileWrite( const std::string& filepath, const Uint8* data, const Uint32& dataSize );
@@ -71,6 +80,9 @@ namespace EE { namespace Utils {
/** @return The Number of CPUs of the system. */
eeInt GetNumCPUs();
+
+ /** @return The modification date of the file */
+ Uint32 FileGetModificationDate( const std::string& Filepath );
}
}