From ba14875becd177c7d8b23cb05597ea80c9826a30 Mon Sep 17 00:00:00 2001 From: spartanj Date: Thu, 16 Dec 2010 03:23:41 -0300 Subject: [PATCH] Removed inline declarations in cSprite. Reimplemented some methods, and changed the name of others for some consistency. Added some methods to cSprite. Added sprites events. --- src/graphics/csprite.cpp | 524 +++++++++++++++++++++++++++++---------- src/graphics/csprite.hpp | 173 ++++++++----- src/test/ee.cpp | 14 +- src/ui/cuisprite.cpp | 2 +- 4 files changed, 510 insertions(+), 203 deletions(-) diff --git a/src/graphics/csprite.cpp b/src/graphics/csprite.cpp index 63f9dd87d..6b534ea21 100755 --- a/src/graphics/csprite.cpp +++ b/src/graphics/csprite.cpp @@ -1,15 +1,99 @@ #include "csprite.hpp" +#include "../window/cengine.hpp" #include "cglobalshapegroup.hpp" #include "cshapegroupmanager.hpp" +using namespace EE::Window; + +#define SPR_FGET( Flag ) ( mFlags & Flag ) + namespace EE { namespace Graphics { -cSprite::cSprite() { - Reset(); +cSprite::cSprite() : + mFlags( SPRITE_FLAG_AUTO_ANIM | SPRITE_FLAG_SCALE_CENTERED | SPRITE_FLAG_EVENTS_ENABLED ), + mPos(), + mAngle( 0.f ), + mScale( 1.f ), + mAnimSpeed( 16.f ), + mColor( 255,255,255,255 ), + mVertexColors( NULL ), + mRepeations( -1 ), + mBlend( ALPHA_NORMAL ), + mEffect( RN_NORMAL ), + mCurrentFrame( 0 ), + mfCurrentFrame( 0.f ), + mCurrentSubFrame( 0 ), + mSubFrames( 1 ), + mAnimTo( 0 ) +{ + mCb.Reset(); } cSprite::~cSprite() { - ClearFrame(); +} + +cSprite& cSprite::operator =( const cSprite& Other ) { + mFrames = Other.mFrames; + mFlags = Other.mFlags; + mPos = Other.mPos; + mAngle = Other.mAngle; + mScale = Other.mScale; + mAnimSpeed = Other.mAnimSpeed; + mColor = Other.mColor; + mRepeations = Other.mRepeations; + mBlend = Other.mBlend; + mEffect = Other.mEffect; + mCurrentFrame = Other.mCurrentFrame; + mfCurrentFrame = Other.mfCurrentFrame; + mCurrentSubFrame = Other.mCurrentSubFrame; + mSubFrames = Other.mSubFrames; + mAnimTo = Other.mAnimTo; + mCb = Other.mCb; + + if ( NULL != Other.mVertexColors ) { + mVertexColors = eeNewArray( eeColorA, 4 ); + mVertexColors[0] = Other.mVertexColors[0]; + mVertexColors[1] = Other.mVertexColors[1]; + mVertexColors[2] = Other.mVertexColors[2]; + mVertexColors[3] = Other.mVertexColors[3]; + } else { + mVertexColors = NULL; + } + + return *this; +} + +cSprite * cSprite::Copy() { + cSprite * Spr = eeNew( cSprite, () ); + + Spr->mFrames = mFrames; + Spr->mFlags = mFlags; + Spr->mPos = mPos; + Spr->mAngle = mAngle; + Spr->mScale = mScale; + Spr->mAnimSpeed = mAnimSpeed; + Spr->mColor = mColor; + Spr->mRepeations = mRepeations; + Spr->mBlend = mBlend; + Spr->mEffect = mEffect; + Spr->mCurrentFrame = mCurrentFrame; + Spr->mfCurrentFrame = mfCurrentFrame; + Spr->mCurrentSubFrame = mCurrentSubFrame; + Spr->mSubFrames = mSubFrames; + Spr->mAnimTo = mAnimTo; + Spr->mCb = mCb; + + if ( NULL != mVertexColors ) { + Spr->mVertexColors = eeNewArray( eeColorA, 4 ); + Spr->mVertexColors[0] = mVertexColors[0]; + Spr->mVertexColors[1] = mVertexColors[1]; + Spr->mVertexColors[2] = mVertexColors[2]; + Spr->mVertexColors[3] = mVertexColors[3]; + } else { + Spr->mVertexColors = NULL; + } + + return Spr; } void cSprite::ClearFrame() { @@ -22,64 +106,53 @@ void cSprite::ClearFrame() { void cSprite::Reset() { ClearFrame(); - mAutoAnim = true; - mAnimSpeed = 0.02f; - mScale = 1; - mRepeations = -1; - mReverseAnim = false; - mAnimPaused = false; - mAlpha = 255; - mAngle = 0; - mColor = eeRGBA(255, 255, 255, mAlpha); + mFlags = SPRITE_FLAG_AUTO_ANIM | SPRITE_FLAG_SCALE_CENTERED | SPRITE_FLAG_EVENTS_ENABLED; - mScaleCentered = true; - mBlend = ALPHA_NORMAL; - mEffect = RN_NORMAL; + mAnimSpeed = 16.f; + mScale = 1; + mRepeations = -1; - mColor0.voidRGB = true; - mColor1.voidRGB = true; - mColor2.voidRGB = true; - mColor3.voidRGB = true; + mAngle = 0; + mColor = eeColorA(255, 255, 255, 255); - mFrameData.CurrentFrame = 0; - mFrameData.CurrentSubFrame = 0; - mFrameData.fCurrentFrame = 0.f; - mFrameData.SubFrames = 1; + mBlend = ALPHA_NORMAL; + mEffect = RN_NORMAL; + + mCurrentFrame = 0; + mCurrentSubFrame = 0; + mfCurrentFrame = 0.f; + mSubFrames = 1; + mAnimTo = 0; + + DisableVertexColors(); } void cSprite::CurrentFrame (const eeFloat &CurFrame ) { - mFrameData.fCurrentFrame = CurFrame; - mFrameData.CurrentFrame = (eeUint)CurFrame; + mfCurrentFrame = CurFrame; + mCurrentFrame = (eeUint)CurFrame; - if ( mFrameData.fCurrentFrame >= mFrames.size() ) { - mFrameData.fCurrentFrame = (eeFloat)mFrames.size() - 1; - mFrameData.CurrentFrame = (eeUint)mFrames.size() - 1; + if ( mfCurrentFrame >= mFrames.size() ) { + mfCurrentFrame = (eeFloat)mFrames.size() - 1; + mCurrentFrame = (eeUint)mFrames.size() - 1; } - if ( mFrameData.fCurrentFrame < 0 ) { - mFrameData.fCurrentFrame = 0.0f; - mFrameData.CurrentFrame = 0; + if ( mfCurrentFrame < 0 ) { + mfCurrentFrame = 0.0f; + mCurrentFrame = 0; } } void cSprite::CurrentSubFrame( const eeUint& CurSubFrame ) { - if ( CurSubFrame < mFrameData.SubFrames ) - mFrameData.CurrentSubFrame = CurSubFrame; + if ( CurSubFrame < mSubFrames ) + mCurrentSubFrame = CurSubFrame; } eeVector2f cSprite::GetRotationCenter( const eeRectf& DestRECT ) { return eeVector2f ( DestRECT.Left + (DestRECT.Right - DestRECT.Left - 1.0f) * 0.5f , DestRECT.Top + (DestRECT.Bottom - DestRECT.Top - 1.0f) * 0.5f ); } -eeRecti cSprite::SprSrcRect() { - if ( mFrames.size() ) - return GetCurrentShape()->SrcRect(); - else - return eeRecti(); -} - -eeRectf cSprite::SprDestRectf() { - eeRectf TmpR; +eeAABB cSprite::GetAABB() { + eeAABB TmpR; if ( mFrames.size() ) { if ( mAngle != 0 || mEffect >= 4 ) { @@ -98,74 +171,73 @@ eeRectf cSprite::SprDestRectf() { TmpR.Bottom = MaxY; } else { // The method used if mAngle != 0 works for mAngle = 0, but i prefer to use the faster way cShape* S = GetCurrentShape(); - if ( S != NULL && mScaleCentered ) + if ( S != NULL && SPR_FGET( SPRITE_FLAG_SCALE_CENTERED ) ) if (mScale == 1.f) - TmpR = eeRectf( mX, mY, mX + S->DestWidth(), mY + S->DestHeight() ); + TmpR = eeRectf( mPos.x, mPos.y, mPos.x + S->DestWidth(), mPos.y + S->DestHeight() ); else { eeFloat halfW = S->DestWidth() * 0.5f; eeFloat halfH = S->DestHeight() * 0.5f; - TmpR = eeRectf( mX + halfW - halfW * mScale, mY + halfH - halfH * mScale, mX + halfW + halfW * mScale, mY + halfH + halfH * mScale ); + TmpR = eeRectf( mPos.x + halfW - halfW * mScale, mPos.y + halfH - halfH * mScale, mPos.x + halfW + halfW * mScale, mPos.y + halfH + halfH * mScale ); } else - TmpR = eeRectf(mX, mY, mX + S->DestWidth() * mScale, mY + + S->DestHeight() * mScale); + TmpR = eeRectf(mPos.x, mPos.y, mPos.x + S->DestWidth() * mScale, mPos.y + + S->DestHeight() * mScale); } } return TmpR; } -eeRecti cSprite::SprDestRECT() { - eeRectf R = SprDestRectf(); - return eeRecti( (Int32)R.Left, (Int32)R.Top, (Int32)R.Right, (Int32)R.Bottom ); +const eeVector2f cSprite::Position() const { + return mPos; } -eeAABB cSprite::GetAABB() { - return SprDestRectf(); +void cSprite::Position(const eeFloat& x, const eeFloat& y) { + mPos.x = x; + mPos.y = y; } -void cSprite::UpdatePos(const eeFloat& x, const eeFloat& y) { - mX = x; - mY = y; -} - -void cSprite::UpdatePos( const eeVector2f& NewPos ) { - UpdatePos( NewPos.x, NewPos.y ); +void cSprite::Position( const eeVector2f& NewPos ) { + mPos = NewPos; } void cSprite::UpdateSize( const eeFloat& Width, const eeFloat& Height, const eeUint& FrameNum ) { eeUint FN; if ( FrameNum >= mFrames.size() ) - FN = mFrameData.CurrentFrame; + FN = mCurrentFrame; else FN = FrameNum; - cShape* S = mFrames[FN].Spr[mFrameData.CurrentSubFrame]; + cShape* S = mFrames[FN].Spr[mCurrentSubFrame]; S->DestWidth( Width ); S->DestHeight( Height ); } -void cSprite::UpdateVertexColors( const eeRGBA& Color0, const eeRGBA& Color1, const eeRGBA& Color2, const eeRGBA& Color3 ) { - mColor0 = Color0; - mColor1 = Color1; - mColor2 = Color2; - mColor3 = Color3; - mColor0.voidRGB = false; - mColor1.voidRGB = false; - mColor2.voidRGB = false; - mColor3.voidRGB = false; +void cSprite::UpdateVertexColors( const eeColorA& Color0, const eeColorA& Color1, const eeColorA& Color2, const eeColorA& Color3 ) { + DisableVertexColors(); + + mVertexColors = eeNewArray( eeColorA, 4 ); + mVertexColors[0] = Color0; + mVertexColors[1] = Color1; + mVertexColors[2] = Color2; + mVertexColors[3] = Color3; +} + +void cSprite::DisableVertexColors() { + eeSAFE_DELETE_ARRAY( mVertexColors ); } void cSprite::Update( const eeFloat& x, const eeFloat& y, const eeFloat& Scale, const eeFloat& Angle, const Uint8& Alpha, const eeRGBA& Color ) { - mX = x; - mY = y; + mPos.x = x; + mPos.y = y; mScale = Scale; mAngle = Angle; mColor = Color; + this->Alpha(Alpha); } Uint32 cSprite::GetTexture(const eeUint& FrameNum, const eeUint& SubFrameNum) { - if ( FrameNum < mFrames.size() && SubFrameNum < mFrameData.SubFrames ) + if ( FrameNum < mFrames.size() && SubFrameNum < mSubFrames ) return mFrames[FrameNum].Spr[SubFrameNum]->GetTexture()->Id(); return 0; @@ -200,9 +272,9 @@ void cSprite::CreateAnimation( const eeUint& SubFramesNum ) { Reset(); if ( SubFramesNum < 1 ) - mFrameData.SubFrames = 1; + mSubFrames = 1; else - mFrameData.SubFrames = SubFramesNum; + mSubFrames = SubFramesNum; } bool cSprite::AddFrames( const std::vector Shapes ) { @@ -239,13 +311,13 @@ bool cSprite::AddSubFrame( cShape * Shape, const eeUint& NumFrame, const eeUint& else NF = NumFrame; - if ( NumSubFrame >= mFrameData.SubFrames ) + if ( NumSubFrame >= mSubFrames ) NSF = 0; else NSF = NumSubFrame; - if ( mFrames[NF].Spr.size() != (eeUint)mFrameData.SubFrames ) - mFrames[NF].Spr.resize( mFrameData.SubFrames ); + if ( mFrames[NF].Spr.size() != (eeUint)mSubFrames ) + mFrames[NF].Spr.resize( mSubFrames ); mFrames[NF].Spr[NSF] = Shape; @@ -255,7 +327,7 @@ bool cSprite::AddSubFrame( cShape * Shape, const eeUint& NumFrame, const eeUint& eeUint cSprite::AddFrame( cShape * Shape ) { eeUint id = FramePos(); - AddSubFrame( Shape, id, mFrameData.CurrentSubFrame ); + AddSubFrame( Shape, id, mCurrentSubFrame ); return id; } @@ -263,7 +335,7 @@ eeUint cSprite::AddFrame( cShape * Shape ) { eeUint cSprite::AddFrame(const Uint32& TexId, const eeFloat& DestWidth, const eeFloat& DestHeight, const eeFloat& offSetX, const eeFloat& offSetY, const eeRecti& TexSector) { eeUint id = FramePos(); - if ( AddSubFrame( TexId, id, mFrameData.CurrentSubFrame, DestWidth, DestHeight, offSetX, offSetY, TexSector ) ) + if ( AddSubFrame( TexId, id, mCurrentSubFrame, DestWidth, DestHeight, offSetX, offSetY, TexSector ) ) return id; return 0; @@ -302,66 +374,84 @@ bool cSprite::AddSubFrame(const Uint32& TexId, const eeUint& NumFrame, const eeU } void cSprite::Animate( const eeFloat& ElapsedTime ) { - if ( mFrames.size() > 1 && mAutoAnim && !mAnimPaused ) { - eeUint Size = (eeUint)mFrames.size() - 1; + if ( mFrames.size() > 1 && SPR_FGET( SPRITE_FLAG_AUTO_ANIM ) && !SPR_FGET( SPRITE_FLAG_ANIM_PAUSED ) ) { + eeUint Size = (eeUint)mFrames.size() - 1; eeFloat Elapsed = ( ElapsedTime != -99999.f ) ? (eeFloat)ElapsedTime : (eeFloat)cEngine::instance()->Elapsed(); if ( mRepeations == 0 ) return; - if ( !mReverseAnim ) - mFrameData.fCurrentFrame += ( Elapsed * mAnimSpeed ); + if ( !SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ) ) + mfCurrentFrame += ( ( mAnimSpeed * Elapsed ) / 1000.f ); else - mFrameData.fCurrentFrame -= ( Elapsed * mAnimSpeed ); + mfCurrentFrame -= ( ( mAnimSpeed * Elapsed ) / 1000.f ); - mFrameData.CurrentFrame = (eeUint)mFrameData.fCurrentFrame; + mCurrentFrame = (eeUint)mfCurrentFrame; - if ( !mReverseAnim && mFrameData.fCurrentFrame >= Size + 1.0f ) { + if ( SPR_FGET( SPRITE_FLAG_ANIM_TO_FRAME_AND_STOP ) ) { + if ( mAnimTo == mCurrentFrame ) { + mFlags &= ~SPRITE_FLAG_ANIM_TO_FRAME_AND_STOP; + + GoToAndStop( mAnimTo ); + + FireEvent( SPRITE_EVENT_END_ANIM_TO ); + + return; + } + } + + if ( !SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ) && mfCurrentFrame >= Size + 1.0f ) { if ( mRepeations < 0 ) { - mFrameData.fCurrentFrame = 0.0f; - mFrameData.CurrentFrame = 0; + mfCurrentFrame = 0.0f; + mCurrentFrame = 0; + FireEvent( SPRITE_EVENT_FIRST_FRAME ); } else { if ( mRepeations == 0 ) { - mFrameData.fCurrentFrame = (eeFloat)Size; - mFrameData.CurrentFrame = Size; + mfCurrentFrame = (eeFloat)Size; + mCurrentFrame = Size; + FireEvent( SPRITE_EVENT_LAST_FRAME ); } else { - mFrameData.fCurrentFrame = 0.0f; - mFrameData.CurrentFrame = 0; - + mfCurrentFrame = 0.0f; + mCurrentFrame = 0; mRepeations--; + FireEvent( SPRITE_EVENT_FIRST_FRAME ); } } - } else if ( mReverseAnim && mFrameData.fCurrentFrame < 0.0f ) { + } else if ( SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ) && mfCurrentFrame < 0.0f ) { if ( mRepeations < 0 ) { - mFrameData.fCurrentFrame = Size + 1.0f; - mFrameData.CurrentFrame = Size; + mfCurrentFrame = Size + 1.0f; + mCurrentFrame = Size; + FireEvent( SPRITE_EVENT_LAST_FRAME ); } else { if ( mRepeations == 0 ) { - mFrameData.fCurrentFrame = 0.0f; - mFrameData.CurrentFrame = 0; + mfCurrentFrame = 0.0f; + mCurrentFrame = 0; + FireEvent( SPRITE_EVENT_FIRST_FRAME ); } else { - mFrameData.fCurrentFrame = Size + 1.0f; - mFrameData.CurrentFrame = Size; - + mfCurrentFrame = Size + 1.0f; + mCurrentFrame = Size; mRepeations--; + FireEvent( SPRITE_EVENT_LAST_FRAME ); } } } - if ( mFrameData.fCurrentFrame < 0.0f ) { - if ( mReverseAnim ) { - mFrameData.fCurrentFrame = 0.0f; - mFrameData.CurrentFrame = 0; + if ( mfCurrentFrame < 0.0f ) { + if ( SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ) ) { + mfCurrentFrame = 0.0f; + mCurrentFrame = 0; + FireEvent( SPRITE_EVENT_FIRST_FRAME ); } else { - mFrameData.fCurrentFrame = (eeFloat)Size; - mFrameData.CurrentFrame = Size; + mfCurrentFrame = (eeFloat)Size; + mCurrentFrame = Size; + FireEvent( SPRITE_EVENT_LAST_FRAME ); } } } } eeUint cSprite::GetEndFrame() { - if ( mReverseAnim ) { + if ( SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ) ) { return 0; } else { return (eeUint)mFrames.size() - 1; @@ -369,11 +459,13 @@ eeUint cSprite::GetEndFrame() { } void cSprite::SetReverseFromStart() { - mReverseAnim = true; + if ( !SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ) ) + mFlags |= SPRITE_FLAG_REVERSE_ANIM; + eeUint Size = (eeUint)mFrames.size() - 1; - mFrameData.fCurrentFrame = (eeFloat)Size; - mFrameData.CurrentFrame = Size; + mfCurrentFrame = (eeFloat)Size; + mCurrentFrame = Size; } void cSprite::Draw( const EE_PRE_BLEND_FUNC& Blend, const EE_RENDERTYPE& Effect, const eeFloat& ElapsedTime ) { @@ -384,10 +476,10 @@ void cSprite::Draw( const EE_PRE_BLEND_FUNC& Blend, const EE_RENDERTYPE& Effect, if ( S == NULL ) return; - if ( mColor0.voidRGB ) - S->Draw( mX, mY, mColor, mAngle, mScale, Blend, Effect, mScaleCentered ); + if ( NULL == mVertexColors ) + S->Draw( mPos.x, mPos.y, mColor, mAngle, mScale, Blend, Effect, 0 != SPR_FGET( SPRITE_FLAG_SCALE_CENTERED ) ); else - S->Draw( mX, mY, mAngle, mScale, mColor0, mColor1, mColor2, mColor3, Blend, Effect, mScaleCentered ); + S->Draw( mPos.x, mPos.y, mAngle, mScale, mVertexColors[0], mVertexColors[1], mVertexColors[2], mVertexColors[3], Blend, Effect, 0 != SPR_FGET( SPRITE_FLAG_SCALE_CENTERED ) ); } void cSprite::Draw() { @@ -406,7 +498,7 @@ eeUint cSprite::GetFrame( const eeUint& FrameNum ) { eeUint FN; if ( FrameNum >= mFrames.size() ) - FN = mFrameData.CurrentFrame; + FN = mCurrentFrame; else FN = FrameNum; @@ -416,8 +508,8 @@ eeUint cSprite::GetFrame( const eeUint& FrameNum ) { eeUint cSprite::GetSubFrame( const eeUint& SubFrame ) { eeUint SFN; - if ( SubFrame >= mFrameData.SubFrames ) - SFN = mFrameData.CurrentSubFrame; + if ( SubFrame >= mSubFrames ) + SFN = mCurrentSubFrame; else SFN = SubFrame; @@ -490,7 +582,14 @@ void cSprite::SetRepeations( const int& Repeations ) { } void cSprite::SetAutoAnimate( const bool& Autoanim ) { - mAutoAnim = Autoanim; + if ( Autoanim ) { + if ( !SPR_FGET( SPRITE_FLAG_AUTO_ANIM ) ) + mFlags |= SPRITE_FLAG_AUTO_ANIM; + } else { + if ( SPR_FGET( SPRITE_FLAG_AUTO_ANIM ) ) + mFlags &= ~SPRITE_FLAG_AUTO_ANIM; + } + } eeQuad2f cSprite::GetQuad() { @@ -498,16 +597,17 @@ eeQuad2f cSprite::GetQuad() { cShape* S = GetCurrentShape(); eeRectf TmpR; - if ( mScaleCentered ) + if ( SPR_FGET( SPRITE_FLAG_SCALE_CENTERED ) ) { if ( mScale == 1.0f ) - TmpR = eeRectf( mX, mY, mX + S->DestWidth(), mY + S->DestHeight() ); + TmpR = eeRectf( mPos.x, mPos.y, mPos.x + S->DestWidth(), mPos.y + S->DestHeight() ); else { eeFloat halfW = S->DestWidth() * 0.5f; eeFloat halfH = S->DestHeight() * 0.5f; - TmpR = eeRectf( mX + halfW - halfW * mScale, mY + halfH - halfH * mScale, mX + halfW + halfW * mScale, mY + halfH + halfH * mScale ); + TmpR = eeRectf( mPos.x + halfW - halfW * mScale, mPos.y + halfH - halfH * mScale, mPos.x + halfW + halfW * mScale, mPos.y + halfH + halfH * mScale ); } - else - TmpR = eeRectf( mX, mY, mX + S->DestWidth() * mScale, mY + S->DestHeight() * mScale ); + } else { + TmpR = eeRectf( mPos.x, mPos.y, mPos.x + S->DestWidth() * mScale, mPos.y + S->DestHeight() * mScale ); + } eeQuad2f Q = eeQuad2f( eeVector2f( TmpR.Left, TmpR.Top ), eeVector2f( TmpR.Left, TmpR.Bottom ), eeVector2f( TmpR.Right, TmpR.Bottom ), eeVector2f( TmpR.Right, TmpR.Top ) ); @@ -557,23 +657,193 @@ eeQuad2f cSprite::GetQuad() { cShape* cSprite::GetCurrentShape() { if ( mFrames.size() ) - return mFrames[ mFrameData.CurrentFrame ].Spr[ mFrameData.CurrentSubFrame ]; + return mFrames[ mCurrentFrame ].Spr[ mCurrentSubFrame ]; return NULL; } -cShape* cSprite::GetShape( const eeUint& frame ) { +cShape * cSprite::GetShape( const eeUint& frame ) { if ( frame < mFrames.size() ) - return mFrames[ frame ].Spr[ mFrameData.CurrentSubFrame ]; + return mFrames[ frame ].Spr[ mCurrentSubFrame ]; return NULL; } -cShape* cSprite::GetShape( const eeUint& frame, const eeUint& SubFrame ) { +cShape * cSprite::GetShape( const eeUint& frame, const eeUint& SubFrame ) { if ( frame < mFrames.size() ) return mFrames[ frame ].Spr[ SubFrame ]; return NULL; } +void cSprite::X( const eeFloat& X ) { + mPos.x = X; +} + +eeFloat cSprite::X() const { + return mPos.x; +} + +void cSprite::Y( const eeFloat& Y ) { + mPos.y = Y; +} + +eeFloat cSprite::Y() const { + return mPos.y; +} + +void cSprite::Angle( const eeFloat& Angle) { + mAngle = Angle; +} + +eeFloat cSprite::Angle() const { + return mAngle; +} + +void cSprite::Scale( const eeFloat& Scale ) { + mScale = Scale; +} + +eeFloat cSprite::Scale() const { + return mScale; +} + +void cSprite::AnimSpeed( const eeFloat& AnimSpeed ) { + mAnimSpeed = AnimSpeed; +} + +eeFloat cSprite::AnimSpeed() const { + return mAnimSpeed; +} + +bool cSprite::AnimPaused() const { + return 0 != SPR_FGET( SPRITE_FLAG_ANIM_PAUSED ); +} + +void cSprite::AnimPaused( const bool& Pause ) { + if ( Pause ) { + if ( !SPR_FGET( SPRITE_FLAG_ANIM_PAUSED ) ) + mFlags |= SPRITE_FLAG_ANIM_PAUSED; + } else { + if ( SPR_FGET( SPRITE_FLAG_ANIM_PAUSED ) ) + mFlags &= ~SPRITE_FLAG_ANIM_PAUSED; + } +} + +void cSprite::Color( const eeColorA& Color) { + mColor = Color; +} + +const eeColorA& cSprite::Color() const { + return mColor; +} + +void cSprite::Alpha( const Uint8& Alpha ) { + mColor.Alpha = Alpha; +} + +const Uint8& cSprite::Alpha() const { + return mColor.Alpha; +} + +bool cSprite::ScaleCentered() const { + return 0 != SPR_FGET( SPRITE_FLAG_SCALE_CENTERED ); +} + +void cSprite::ScaleCentered( const bool& ScaleCentered ) { + if ( ScaleCentered ) { + if ( !SPR_FGET( SPRITE_FLAG_SCALE_CENTERED ) ) + mFlags |= SPRITE_FLAG_SCALE_CENTERED; + } else { + if ( SPR_FGET( SPRITE_FLAG_SCALE_CENTERED ) ) + mFlags &= ~SPRITE_FLAG_SCALE_CENTERED; + } +} + +const eeUint& cSprite::CurrentFrame() const { + return mCurrentFrame; +} + +const eeFloat& cSprite::ExactCurrentFrame() const { + return mfCurrentFrame; +} + +void cSprite::ExactCurrentFrame( const eeFloat& CurrentFrame ) { + mfCurrentFrame = CurrentFrame; +} + +const eeUint& cSprite::CurrentSubFrame() const { + return mCurrentSubFrame; +} + +void cSprite::SetRenderType( const EE_RENDERTYPE& Effect ) { + mEffect = Effect; +} + +void cSprite::SetRenderAlphas( const EE_PRE_BLEND_FUNC& Blend ) { + mBlend = Blend; +} + +void cSprite::ReverseAnim( const bool& Reverse ) { + if ( Reverse ) { + if ( !SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ) ) + mFlags |= SPRITE_FLAG_REVERSE_ANIM; + } else { + if ( SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ) ) + mFlags &= ~SPRITE_FLAG_REVERSE_ANIM; + } +} + +bool cSprite::ReverseAnim() const { + return 0 != SPR_FGET( SPRITE_FLAG_REVERSE_ANIM ); +} + +Uint32 cSprite::GetNumFrames() { + return (Uint32)mFrames.size(); +} + +void cSprite::GoToAndPlay( Uint32 GoTo ) { + if ( GoTo ) + GoTo--; + + if ( GoTo < mFrames.size() ) { + mCurrentFrame = GoTo; + mfCurrentFrame = (eeFloat)GoTo; + + AnimPaused( false ); + } +} + +void cSprite::GoToAndStop( Uint32 GoTo ) { + GoToAndPlay( GoTo ); + AnimPaused( true ); +} + +void cSprite::AnimToFrameAndStop( Uint32 GoTo ) { + if ( GoTo ) + GoTo--; + + if ( GoTo < mFrames.size() ) { + mAnimTo = GoTo; + + mFlags |= SPRITE_FLAG_ANIM_TO_FRAME_AND_STOP; + + AnimPaused( false ); + } +} + +void cSprite::SetEventsCallback( const SpriteCallback& Cb ) { + mCb = Cb; +} + +void cSprite::ClearCallback() { + mCb.Reset(); +} + +void cSprite::FireEvent( const Uint32& Event ) { + if ( SPR_FGET( SPRITE_FLAG_EVENTS_ENABLED ) && mCb.IsSet() ) { + mCb( Event, this ); + } +} + }} diff --git a/src/graphics/csprite.hpp b/src/graphics/csprite.hpp index 8893c6e70..ce7ec5f0c 100755 --- a/src/graphics/csprite.hpp +++ b/src/graphics/csprite.hpp @@ -2,45 +2,52 @@ #define EECSPRITE_H #include "base.hpp" -#include "../window/cengine.hpp" #include "ctexturefactory.hpp" #include "cshape.hpp" #include "cshapegroup.hpp" -using namespace EE::Window; - namespace EE { namespace Graphics { /** @brief A Sprite controller class, can hold and control sprites animations. */ class EE_API cSprite { public: + typedef cb::Callback2< void, Uint32, cSprite * > SpriteCallback; + + enum SpriteEvents { + SPRITE_EVENT_LAST_FRAME, + SPRITE_EVENT_FIRST_FRAME, + SPRITE_EVENT_END_ANIM_TO + }; + cSprite(); ~cSprite(); + cSprite& operator =( const cSprite& Other ); + /** Set the x axis position */ - void X(const eeFloat &X) { mX = X; } + void X( const eeFloat& X ); /** Get the x axis position */ - eeFloat X() const { return mX; } + eeFloat X() const; /** Set the y axis position */ - void Y(const eeFloat& Y) { mY = Y; } + void Y( const eeFloat& Y ); /** Get the y axis position */ - eeFloat Y() const { return mY; } + eeFloat Y() const; /** Set the Angle for the rendered sprite */ - void Angle( const eeFloat &Angle) { mAngle = Angle; } + void Angle( const eeFloat& Angle ); /** Get the Angle for the rendered sprite */ - eeFloat Angle() const { return mAngle; } + eeFloat Angle() const; /** Set the Scale for the rendered sprite */ - void Scale( const eeFloat &Scale) { mScale = Scale; } + void Scale( const eeFloat& Scale ); /** Get the Scale for the rendered sprite */ - eeFloat Scale() const { return mScale; } + eeFloat Scale() const; /** Set the Frame Number Sprite Width * @param FrameNum If the Frame Number is 0 use the Current Frame Number @@ -60,99 +67,90 @@ class EE_API cSprite { /** Get the Frame Number Sprite Height */ eeFloat Height( const eeUint& FrameNum = 0, const eeUint& SubFrame = 0 ); - /** Set the sprite animation speed */ - void AnimSpeed( const eeFloat& AnimSpeed) { mAnimSpeed = AnimSpeed; } + /** Set the sprite animation speed ( AnimSpeed equals to Animation Frames per Second ) */ + void AnimSpeed( const eeFloat& AnimSpeed ); - /** Get the sprite animation speed */ - eeFloat AnimSpeed() const { return mAnimSpeed; } + /** Get the sprite animation speed ( AnimSpeed equals to Animation Frames per Second ) */ + eeFloat AnimSpeed() const; /** @return If the animation is paused */ - bool AnimPause() const { return mAnimPaused; } + bool AnimPaused() const; /** Set the animation paused or not */ - void AnimPause( const bool& Pause ) { mAnimPaused = Pause; } + void AnimPaused( const bool& Pause ); /** Set the sprite color */ - void Color( const eeRGBA& Color) { mColor = Color; }; + void Color( const eeColorA& Color); /** Get the sprite color */ - eeRGBA Color() const { return mColor; } + const eeColorA& Color() const; /** Set the sprite Color Alpha */ - void Alpha( const Uint8& Alpha) { - mAlpha = Alpha; - mColor.Alpha = (Uint8)mAlpha; - } + void Alpha( const Uint8& Alpha ); /** Get the sprite Color Alpha */ - eeFloat Alpha() const { return mAlpha; } + const Uint8& Alpha() const; /** Get if the sprite it's scaled from the center */ - bool ScaleCentered() const { return mScaleCentered; } + bool ScaleCentered() const; /** Set if the sprite it's scaled centered or scaled from the Left - Top position of the sprite ( default True ) */ - void ScaleCentered(const bool &ScaleCentered) { mScaleCentered = ScaleCentered; } + void ScaleCentered(const bool& ScaleCentered ); /** Set the Current Frame */ void CurrentFrame( const eeFloat& CurFrame ); /** Get the Current Frame */ - eeUint CurrentFrame() const { return mFrameData.CurrentFrame; } + const eeUint& CurrentFrame() const; /** Get the Exact Current FrameData * @return The eeFloat fpoint of the current frame, the exact position of the interpolation. */ - eeFloat ExactCurrentFrame() const { return mFrameData.fCurrentFrame; } + const eeFloat& ExactCurrentFrame() const; /** Set the exact current FrameData */ - void ExactCurrentFrame( const eeFloat& CurrentFrame ) { mFrameData.fCurrentFrame = CurrentFrame; } + void ExactCurrentFrame( const eeFloat& CurrentFrame ); /** Set the Current Sub Frame */ void CurrentSubFrame( const eeUint &CurSubFrame ); /** Get the Current Sub Frame */ - eeUint CurrentSubFrame() const { return mFrameData.CurrentSubFrame; } + const eeUint& CurrentSubFrame() const; /** Set the Render Type */ - void SetRenderType( const EE_RENDERTYPE& Effect ) { mEffect = Effect; } + void SetRenderType( const EE_RENDERTYPE& Effect ); /** Set the Blend Mode */ - void SetRenderAlphas( const EE_PRE_BLEND_FUNC& Blend ) { mBlend = Blend; } + void SetRenderAlphas( const EE_PRE_BLEND_FUNC& Blend ); /** Reset the sprite as a new one. */ void Reset(); - /** Get the current Source RECT of the sprite. The texture coordinates of the sprite. */ - eeRecti SprSrcRect(); - - /** Get the current Destination RECT of the sprite. The sprite coordinates on the screen. (the AABB, axis-aligned bounding box) */ - eeRectf SprDestRectf(); - - /** Get the current Destination RECT of the sprite. The sprite coordinates on the screen (the AABB, axis-aligned bounding box). */ - eeRecti SprDestRECT(); - /** @return The AABB (axis-aligned bounding box) */ eeAABB GetAABB(); /** Update the sprite position */ - void UpdatePos( const eeFloat& x, const eeFloat& y ); + void Position( const eeFloat& x, const eeFloat& y ); /** Update the sprite position from a Vector */ - void UpdatePos( const eeVector2f& NewPos ); + void Position( const eeVector2f& NewPos ); + + /** @return The Position of the sprite */ + const eeVector2f Position() const; /** Update the sprite size of a frame number */ void UpdateSize( const eeFloat& Width, const eeFloat& Height, const eeUint& FrameNum = 0 ); - /** Update the scale of the sprite */ - void UpdateScale( const eeFloat& Scale ) { if(Scale>0) mScale = Scale; } - /** Update the colors of every vertex rendered of the sprite ( this will override the default color ) * @param Color0 The Left - Top vertex color * @param Color1 The Left - Bottom vertex color * @param Color2 The Right - Bottom vertex color * @param Color3 The Right - Top vertex color */ - void UpdateVertexColors( const eeRGBA& Color0, const eeRGBA& Color1, const eeRGBA& Color2, const eeRGBA& Color3 ); + void UpdateVertexColors( const eeColorA& Color0, const eeColorA& Color1, const eeColorA& Color2, const eeColorA& Color3 ); + + /** This will disable the vertex colors */ + void DisableVertexColors(); /** Update the sprite * @param x Set the x axis position @@ -291,16 +289,16 @@ class EE_API cSprite { void OffSet( const eeVector2f& offset ); /** Reverse the animation from last frame to first mFrames. */ - void ReverseAnim( const bool& Reverse ) { mReverseAnim = Reverse; } + void ReverseAnim( const bool& Reverse ); /** @return If the animation is reversed */ - bool ReverseAnim() const { return mReverseAnim; } + bool ReverseAnim() const; /** @return The current last frame */ eeUint GetEndFrame(); /** @return The number of frames */ - eeUint GetNumFrames() { return (eeUint)mFrames.size(); } + Uint32 GetNumFrames(); /** Will set Reverse active and set the first frame as the last frame */ void SetReverseFromStart(); @@ -309,29 +307,63 @@ class EE_API cSprite { cShape * GetCurrentShape(); /** @return The Shape Frame from the current sub frame */ - cShape* GetShape( const eeUint& frame ); + cShape * GetShape( const eeUint& frame ); /** @return The Shape Frame from the SubFrame */ - cShape* GetShape( const eeUint& frame, const eeUint& SubFrame ); + cShape * GetShape( const eeUint& frame, const eeUint& SubFrame ); + + /** Start playing from + ** @param GoTo Frame that goes from 1 to Number of Frames + */ + void GoToAndPlay( Uint32 GoTo ); + + /** Go to a frame and stop + ** @param GoTo Frame that goes from 1 to Number of Frames + */ + void GoToAndStop( Uint32 GoTo ); + + /** Animate to frame and when reach the frame stops */ + void AnimToFrameAndStop( Uint32 GoTo ); + + /** Set the sprite events callback */ + void SetEventsCallback( const SpriteCallback& Cb ); + + /** Removes the current callback */ + void ClearCallback(); + + /** Creates a copy of the current sprite and returned it */ + cSprite * Copy(); protected: - eeFloat mX, mY, mAngle, mScale, mAnimSpeed; - bool mAutoAnim; - bool mScaleCentered; - EE_PRE_BLEND_FUNC mBlend; - EE_RENDERTYPE mEffect; + enum SpriteFlags { + SPRITE_FLAG_AUTO_ANIM = ( 1 << 0 ), + SPRITE_FLAG_SCALE_CENTERED = ( 1 << 1 ), + SPRITE_FLAG_REVERSE_ANIM = ( 1 << 2 ), + SPRITE_FLAG_ANIM_PAUSED = ( 1 << 3 ), + SPRITE_FLAG_ANIM_TO_FRAME_AND_STOP = ( 1 << 4 ), + SPRITE_FLAG_EVENTS_ENABLED = ( 1 << 5 ) + }; - eeRGBA mColor, mColor0, mColor1, mColor2, mColor3; - Uint8 mAlpha; - Int16 mRepeations; //!< Number of repetions of the animation, default -1 that equals to loop. - bool mReverseAnim; - bool mAnimPaused; + Uint32 mFlags; + eeVector2f mPos; + eeFloat mAngle; + eeFloat mScale; + eeFloat mAnimSpeed; - struct FrameData { - eeUint CurrentFrame; - eeFloat fCurrentFrame; - eeUint CurrentSubFrame; - eeUint SubFrames; - } mFrameData; + eeColorA mColor; + eeColorA * mVertexColors; + + eeInt mRepeations; //!< Number of repetions of the animation, default -1 that equals to loop. + + EE_PRE_BLEND_FUNC mBlend; + EE_RENDERTYPE mEffect; + + SpriteCallback mCb; + + eeUint mCurrentFrame; + eeFloat mfCurrentFrame; + eeUint mCurrentSubFrame; + eeUint mSubFrames; + eeUint mAnimTo; class cFrame { public: @@ -340,13 +372,18 @@ class EE_API cSprite { std::vector mFrames; eeUint FramePos(); + void ClearFrame(); + void Animate( const eeFloat& ElapsedTime = -99999.f ); eeVector2f GetRotationCenter( const eeRectf& DestRECT ); eeUint GetFrame( const eeUint& FrameNum ); + eeUint GetSubFrame( const eeUint& SubFrame ); + + void FireEvent( const Uint32& Event ); }; }} diff --git a/src/test/ee.cpp b/src/test/ee.cpp index 96e46670f..c402ca10c 100644 --- a/src/test/ee.cpp +++ b/src/test/ee.cpp @@ -838,8 +838,8 @@ void cEETest::LoadTextures() { EE->ShowCursor(false); CL1.AddFrame(TN[2]); - CL1.UpdatePos(500,400); - CL1.Scale(0.5f); + CL1.Position( 500, 400 ); + CL1.Scale( 0.5f ); CL2.AddFrame(TN[0], 96, 96); CL2.Color( eeRGBA( 255, 255, 255, 255 ) ); @@ -847,7 +847,7 @@ void cEETest::LoadTextures() { mTGL = eeNew( cTextureGroupLoader, ( MyPath + "data/bnb/bnb.etg" ) ); mBlindy.AddFramesByPattern( "rn" ); - mBlindy.UpdatePos( 320.f, 0.f ); + mBlindy.Position( 320.f, 0.f ); Map.myFont = reinterpret_cast ( &FF ); @@ -1013,12 +1013,12 @@ void cEETest::Screen2() { eeColorA Col(255,255,255,(int)alpha); TNP[1]->DrawEx( (eeFloat)EE->GetWidth() - 128.f, (eeFloat)EE->GetHeight() - 128.f, 128.f, 128.f, ang, 1, Col, Col, Col, Col, ALPHA_BLENDONE, RN_FLIPMIRROR); - SP.UpdatePos(alpha,alpha); + SP.Position( alpha, alpha ); SP.Draw(); CL1.SetRenderType( RN_ISOMETRIC ); - if (IntersectRectCircle( CL1.SprDestRectf(), Mousef.x, Mousef.y, 80.f )) + if (IntersectRectCircle( CL1.GetAABB(), Mousef.x, Mousef.y, 80.f )) CL1.Color( eeRGBA(255, 0, 0, 200) ); else CL1.Color( eeRGBA(255, 255, 255, 200) ); @@ -1032,7 +1032,7 @@ void cEETest::Screen2() { CL1.Angle(ang); CL1.Scale(scale * 0.5f); - CL2.UpdatePos( (eeFloat)Mousef.x - 64.f, (eeFloat)Mousef.y + 128.f ); + CL2.Position( (eeFloat)Mousef.x - 64.f, (eeFloat)Mousef.y + 128.f ); CL2.Angle(-ang); CL1.Draw(); @@ -1192,7 +1192,7 @@ void cEETest::Render() { mFB->Bind(); mFB->Clear(); - mBlindy.UpdatePos( 128-16, 128-16 ); + mBlindy.Position( 128-16, 128-16 ); mBlindy.Draw(); mVBO->Bind(); diff --git a/src/ui/cuisprite.cpp b/src/ui/cuisprite.cpp index 445948539..1166730bd 100644 --- a/src/ui/cuisprite.cpp +++ b/src/ui/cuisprite.cpp @@ -31,7 +31,7 @@ void cUISprite::Draw() { if ( mVisible ) { if ( NULL != mSprite && 0.f != mAlpha ) { UpdateSize(); - mSprite->UpdatePos( (eeFloat)mScreenPos.x, (eeFloat)mScreenPos.y ); + mSprite->Position( (eeFloat)mScreenPos.x, (eeFloat)mScreenPos.y ); mSprite->Draw( mBlend, mRender ); } }