From ea34c1faa65b384e35c4c2ba9be59b5c296c1e4e Mon Sep 17 00:00:00 2001 From: "spartanj@gmail.com" Date: Mon, 25 Jul 2011 00:53:23 -0300 Subject: [PATCH] Updated Physics module integrating the lastest changes to Chipmunk Physics 6. Small fixes to SDL 1.3 version to avoid crashes on Windows. Avoid to compile SDL 1.2 when compiling SDL 1.3 in Windows. --- ee.files | 1 + ee.win.cbp | 10 ++- src/gaming/cgameobject.hpp | 2 +- src/gaming/cgameobjectshape.hpp | 2 +- src/gaming/cgameobjectshapeex.hpp | 2 +- src/gaming/cgameobjectsprite.hpp | 2 +- src/gaming/cgameobjectvirtual.hpp | 2 +- src/gaming/clayer.hpp | 2 +- src/gaming/cmap.hpp | 2 +- src/gaming/cobjectlayer.hpp | 2 +- src/gaming/ctilelayer.hpp | 2 +- src/gaming/mapeditor/cmapeditor.cpp | 1 + src/graphics/cvertexbuffer.hpp | 2 +- src/graphics/cvertexbufferogl.hpp | 2 +- src/graphics/cvertexbuffervbo.hpp | 2 +- src/graphics/renderer/cgl.hpp | 4 +- src/graphics/renderer/crenderergl.hpp | 2 +- src/graphics/renderer/crenderergl3.hpp | 2 +- src/physics/carbiter.cpp | 24 ++++++ src/physics/carbiter.hpp | 12 +++ src/physics/cbody.cpp | 68 ++++++++++++++++- src/physics/cbody.hpp | 74 ++++++++++++++++-- src/physics/constraints/cconstraint.cpp | 29 ++++++- src/physics/constraints/cconstraint.hpp | 12 +++ src/physics/cphysicsmanager.hpp | 2 +- src/physics/cspace.cpp | 76 ++++++++++++++++++- src/physics/cspace.hpp | 57 ++++++++++++++ src/physics/physicshelper.hpp | 1 + src/window/backend/SDL/base.hpp | 22 ++++++ src/window/backend/SDL/cbackendsdl.hpp | 4 +- src/window/backend/SDL/cclipboardsdl.cpp | 2 +- src/window/backend/SDL/cclipboardsdl.hpp | 5 +- src/window/backend/SDL/ccursormanagersdl.cpp | 2 +- src/window/backend/SDL/ccursormanagersdl.hpp | 5 +- src/window/backend/SDL/ccursorsdl.cpp | 2 +- src/window/backend/SDL/ccursorsdl.hpp | 5 +- src/window/backend/SDL/cinputsdl.cpp | 2 +- src/window/backend/SDL/cinputsdl.hpp | 13 ++-- .../backend/SDL/cjoystickmanagersdl.cpp | 4 +- .../backend/SDL/cjoystickmanagersdl.hpp | 10 +-- src/window/backend/SDL/cjoysticksdl.cpp | 2 +- src/window/backend/SDL/cjoysticksdl.hpp | 4 +- src/window/backend/SDL/cwindowsdl.cpp | 3 +- src/window/backend/SDL/cwindowsdl.hpp | 13 ++-- src/window/backend/SDL13/base.hpp | 1 - src/window/backend/SDL13/cinputsdl.cpp | 2 + src/window/backend/SDL13/cwindowsdl.cpp | 4 +- src/window/cinput.cpp | 18 +++-- src/window/inputhelper.hpp | 7 +- 49 files changed, 448 insertions(+), 81 deletions(-) create mode 100644 src/window/backend/SDL/base.hpp diff --git a/ee.files b/ee.files index 038ccc7c3..11c0d3de2 100644 --- a/ee.files +++ b/ee.files @@ -797,3 +797,4 @@ src/ui/tools/ctexturegroupnew.hpp src/ui/tools/ctexturegroupnew.cpp src/ui/tools/ctexturegroupshapeeditor.hpp src/ui/tools/ctexturegroupshapeeditor.cpp +src/window/backend/SDL/base.hpp diff --git a/ee.win.cbp b/ee.win.cbp index a2faa97c3..4ccc82253 100644 --- a/ee.win.cbp +++ b/ee.win.cbp @@ -33,7 +33,7 @@ - + @@ -786,6 +786,8 @@ + + @@ -832,6 +834,12 @@ + + + + + + diff --git a/src/gaming/cgameobject.hpp b/src/gaming/cgameobject.hpp index 29e17c68c..3471d757a 100644 --- a/src/gaming/cgameobject.hpp +++ b/src/gaming/cgameobject.hpp @@ -9,7 +9,7 @@ using namespace EE::Graphics; namespace EE { namespace Gaming { -class cGameObject { +class EE_API cGameObject { public: cGameObject( const Uint32& Flags ); diff --git a/src/gaming/cgameobjectshape.hpp b/src/gaming/cgameobjectshape.hpp index 2cda550d8..a120730de 100644 --- a/src/gaming/cgameobjectshape.hpp +++ b/src/gaming/cgameobjectshape.hpp @@ -9,7 +9,7 @@ using namespace EE::Graphics; namespace EE { namespace Gaming { -class cGameObjectShape : public cGameObject { +class EE_API cGameObjectShape : public cGameObject { public: cGameObjectShape( const Uint32& Flags = GObjFlags::GAMEOBJECT_STATIC, cShape * Shape = NULL, const eeVector2f& Pos = eeVector2f() ); diff --git a/src/gaming/cgameobjectshapeex.hpp b/src/gaming/cgameobjectshapeex.hpp index 141123643..42f893c24 100644 --- a/src/gaming/cgameobjectshapeex.hpp +++ b/src/gaming/cgameobjectshapeex.hpp @@ -6,7 +6,7 @@ namespace EE { namespace Gaming { -class cGameObjectShapeEx : public cGameObjectShape { +class EE_API cGameObjectShapeEx : public cGameObjectShape { public: cGameObjectShapeEx( const Uint32& Flags = GObjFlags::GAMEOBJECT_STATIC, cShape * Shape = NULL, const eeVector2f& Pos = eeVector2f(), EE_PRE_BLEND_FUNC Blend = ALPHA_NORMAL, EE_RENDERTYPE Render = RN_NORMAL, eeFloat Angle = 0.f, eeFloat Scale = 1.f, eeColorA Color = eeColorA() ); diff --git a/src/gaming/cgameobjectsprite.hpp b/src/gaming/cgameobjectsprite.hpp index 5c0da6b32..a84d40a40 100644 --- a/src/gaming/cgameobjectsprite.hpp +++ b/src/gaming/cgameobjectsprite.hpp @@ -9,7 +9,7 @@ using namespace EE::Graphics; namespace EE { namespace Gaming { -class cGameObjectSprite : public cGameObject { +class EE_API cGameObjectSprite : public cGameObject { public: cGameObjectSprite( const Uint32& Flags = GObjFlags::GAMEOBJECT_ANIMATED, cSprite * Sprite = NULL ); diff --git a/src/gaming/cgameobjectvirtual.hpp b/src/gaming/cgameobjectvirtual.hpp index b19733407..8a43772b7 100644 --- a/src/gaming/cgameobjectvirtual.hpp +++ b/src/gaming/cgameobjectvirtual.hpp @@ -10,7 +10,7 @@ namespace EE { namespace Gaming { class cLayer; -class cGameObjectVirtual : public cGameObject { +class EE_API cGameObjectVirtual : public cGameObject { public: cGameObjectVirtual( Uint32 DataId, const Uint32& Flags = GObjFlags::GAMEOBJECT_STATIC, Uint32 RealType = GAMEOBJECT_TYPE_VIRTUAL, const eeVector2f& Pos = eeVector2f() ); diff --git a/src/gaming/clayer.hpp b/src/gaming/clayer.hpp index 8ed8c55c4..5e282afb4 100644 --- a/src/gaming/clayer.hpp +++ b/src/gaming/clayer.hpp @@ -7,7 +7,7 @@ namespace EE { namespace Gaming { class cMap; -class cLayer { +class EE_API cLayer { public: typedef std::map PropertiesMap; diff --git a/src/gaming/cmap.hpp b/src/gaming/cmap.hpp index eaff108e7..2678501ad 100644 --- a/src/gaming/cmap.hpp +++ b/src/gaming/cmap.hpp @@ -16,7 +16,7 @@ namespace EE { namespace Gaming { #define MAP_LAYER_UNKNOWN 0xFFFFFFFF -class cMap { +class EE_API cMap { public: typedef std::map PropertiesMap; typedef std::list GOTypesList; //! Special object types used in this map diff --git a/src/gaming/cobjectlayer.hpp b/src/gaming/cobjectlayer.hpp index 3686b30c0..22abf0046 100644 --- a/src/gaming/cobjectlayer.hpp +++ b/src/gaming/cobjectlayer.hpp @@ -8,7 +8,7 @@ namespace EE { namespace Gaming { class cMap; -class cObjectLayer : public cLayer { +class EE_API cObjectLayer : public cLayer { public: typedef std::list ObjList; diff --git a/src/gaming/ctilelayer.hpp b/src/gaming/ctilelayer.hpp index cc9a42073..8462e5fe9 100644 --- a/src/gaming/ctilelayer.hpp +++ b/src/gaming/ctilelayer.hpp @@ -6,7 +6,7 @@ namespace EE { namespace Gaming { -class cTileLayer : public cLayer { +class EE_API cTileLayer : public cLayer { public: virtual ~cTileLayer(); diff --git a/src/gaming/mapeditor/cmapeditor.cpp b/src/gaming/mapeditor/cmapeditor.cpp index d098110d5..e0c209412 100644 --- a/src/gaming/mapeditor/cmapeditor.cpp +++ b/src/gaming/mapeditor/cmapeditor.cpp @@ -406,6 +406,7 @@ void cMapEditor::CreateNewMap() { } void cMapEditor::MapCreated() { + mCurLayer = NULL; mLayerList->ListBox()->Clear(); FillSGCombo(); diff --git a/src/graphics/cvertexbuffer.hpp b/src/graphics/cvertexbuffer.hpp index 670834b43..5d6795f8b 100644 --- a/src/graphics/cvertexbuffer.hpp +++ b/src/graphics/cvertexbuffer.hpp @@ -6,7 +6,7 @@ namespace EE { namespace Graphics { -class cVertexBuffer { +class EE_API cVertexBuffer { public: static cVertexBuffer * Create( const Uint32& VertexFlags = VERTEX_FLAGS_DEFAULT, EE_DRAW_MODE DrawType = DM_QUADS, const Int32& ReserveVertexSize = 0, const Int32& ReserveIndexSize = 0, EE_VBO_USAGE_TYPE UsageType = VBO_USAGE_TYPE_STATIC ); diff --git a/src/graphics/cvertexbufferogl.hpp b/src/graphics/cvertexbufferogl.hpp index 2bff528f0..6e1925aac 100644 --- a/src/graphics/cvertexbufferogl.hpp +++ b/src/graphics/cvertexbufferogl.hpp @@ -5,7 +5,7 @@ namespace EE { namespace Graphics { -class cVertexBufferOGL : public cVertexBuffer { +class EE_API cVertexBufferOGL : public cVertexBuffer { public: cVertexBufferOGL( const Uint32& VertexFlags = VERTEX_FLAGS_DEFAULT, EE_DRAW_MODE DrawType = DM_QUADS, const Int32& ReserveVertexSize = 0, const Int32& ReserveIndexSize = 0, EE_VBO_USAGE_TYPE UsageType = VBO_USAGE_TYPE_STATIC ); diff --git a/src/graphics/cvertexbuffervbo.hpp b/src/graphics/cvertexbuffervbo.hpp index b019cad43..427f09099 100644 --- a/src/graphics/cvertexbuffervbo.hpp +++ b/src/graphics/cvertexbuffervbo.hpp @@ -5,7 +5,7 @@ namespace EE { namespace Graphics { -class cVertexBufferVBO : public cVertexBuffer { +class EE_API cVertexBufferVBO : public cVertexBuffer { public: cVertexBufferVBO( const Uint32& VertexFlags = VERTEX_FLAGS_DEFAULT, EE_DRAW_MODE DrawType = DM_QUADS, const Int32& ReserveVertexSize = 0, const Int32& ReserveIndexSize = 0, EE_VBO_USAGE_TYPE UsageType = VBO_USAGE_TYPE_STATIC ); diff --git a/src/graphics/renderer/cgl.hpp b/src/graphics/renderer/cgl.hpp index e213cac99..76014a874 100644 --- a/src/graphics/renderer/cgl.hpp +++ b/src/graphics/renderer/cgl.hpp @@ -17,7 +17,7 @@ enum EEGL_extensions { EEGL_EXT_framebuffer_object, EEGL_ARB_multitexture, EEGL_EXT_texture_compression_s3tc, - EEGL_ARB_vertex_buffer_object, + EEGL_ARB_vertex_buffer_object, EEGL_ARB_vertex_array_object }; @@ -32,7 +32,7 @@ enum EEGL_version { class cRendererGL; class cRendererGL3; -class cGL { +class EE_API cGL { static cGL * ms_singleton; public: static cGL * CreateSingleton( EEGL_version ver ); diff --git a/src/graphics/renderer/crenderergl.hpp b/src/graphics/renderer/crenderergl.hpp index eef06eb22..a18ae21b3 100644 --- a/src/graphics/renderer/crenderergl.hpp +++ b/src/graphics/renderer/crenderergl.hpp @@ -8,7 +8,7 @@ namespace EE { namespace Graphics { //! Avoid compilling the fixed pipeline renderer for GLES2, because it's not supported. #ifndef EE_GLES2 -class cRendererGL : public cGL { +class EE_API cRendererGL : public cGL { public: cRendererGL(); diff --git a/src/graphics/renderer/crenderergl3.hpp b/src/graphics/renderer/crenderergl3.hpp index d4cdf02c6..cb529ce15 100644 --- a/src/graphics/renderer/crenderergl3.hpp +++ b/src/graphics/renderer/crenderergl3.hpp @@ -39,7 +39,7 @@ enum EEGL_SHADERS { EEGL_SHADERS_COUNT }; -class cRendererGL3 : public cGL { +class EE_API cRendererGL3 : public cGL { public: cRendererGL3(); diff --git a/src/physics/carbiter.cpp b/src/physics/carbiter.cpp index ffd06c9b9..61c1ac111 100644 --- a/src/physics/carbiter.cpp +++ b/src/physics/carbiter.cpp @@ -80,4 +80,28 @@ cpArbiter * cArbiter::Arbiter() const { return mArbiter; } +cpFloat cArbiter::Elasticity() { + return cpArbiterGetElasticity( mArbiter); +} + +void cArbiter::Elasticity( cpFloat value ) { + cpArbiterSetElasticity( mArbiter, value ); +} + +cpFloat cArbiter::Friction() { + return cpArbiterGetFriction( mArbiter ); +} + +void cArbiter::Friction( cpFloat value ) { + cpArbiterSetFriction( mArbiter, value ); +} + +cVect cArbiter::SurfaceVelocity() { + return tovect( cpArbiterGetSurfaceVelocity( mArbiter ) ); +} + +void cArbiter::SurfaceVelocity( cVect value ) { + cpArbiterSetSurfaceVelocity( mArbiter, tocpv( value ) ); +} + CP_NAMESPACE_END diff --git a/src/physics/carbiter.hpp b/src/physics/carbiter.hpp index a836d305b..68f845333 100644 --- a/src/physics/carbiter.hpp +++ b/src/physics/carbiter.hpp @@ -34,6 +34,18 @@ class CP_API cArbiter { cpContactPointSet GetContactPointSet(); cpArbiter * Arbiter() const; + + cpFloat Elasticity(); + + void Elasticity( cpFloat value ); + + cpFloat Friction(); + + void Friction( cpFloat value ); + + cVect SurfaceVelocity(); + + void SurfaceVelocity( cVect value ); protected: cpArbiter * mArbiter; }; diff --git a/src/physics/cbody.cpp b/src/physics/cbody.cpp index bb0a67d65..469e54de6 100644 --- a/src/physics/cbody.cpp +++ b/src/physics/cbody.cpp @@ -1,5 +1,8 @@ #include "cbody.hpp" #include "cphysicsmanager.hpp" +#include "cshape.hpp" +#include "constraints/cconstraint.hpp" +#include "carbiter.hpp" CP_NAMESPACE_BEGIN @@ -57,6 +60,10 @@ void cBody::Activate() { cpBodyActivate( mBody ); } +void cBody::ActivateStatic( cBody *body, cShape * filter ) { + cpBodyActivateStatic( mBody, filter->Shape() ); +} + void cBody::Sleep() { cpBodySleep( mBody ); } @@ -145,6 +152,14 @@ void cBody::AngVel( const cpFloat& rotVel ) { cpBodySetAngVel( mBody, rotVel ); } +cpFloat cBody::Torque() const { + return cpBodyGetTorque( mBody ); +} + +void cBody::Torque( const cpFloat& torque ) { + cpBodySetTorque( mBody, torque ); +} + cVect cBody::Rot() const { return tovect( cpBodyGetRot( mBody ) ); } @@ -165,10 +180,6 @@ void cBody::AngVelLimit( const cpFloat& speed ) { cpBodySetAngVelLimit( mBody, speed ); } -void cBody::Slew( cVect pos, cpFloat dt ) { - //cpBodySlew( mBody, tocpv( pos ), dt ); -} - void cBody::UpdateVelocity( cVect gravity, cpFloat damping, cpFloat dt ) { cpBodyUpdateVelocity( mBody, tocpv( gravity ), damping, dt ); } @@ -209,4 +220,53 @@ void cBody::Data( void * data ) { mData = data; } +static void BodyShapeIteratorFunc ( cpBody * body, cpShape * shape, void * data ) { + cBody::cShapeIterator * it = reinterpret_cast ( data ); + it->Body->OnEachShape( reinterpret_cast( shape->data ), it ); +} + +void cBody::EachShape( ShapeIteratorFunc Func, void * data ) { + cShapeIterator it( this, data, Func ); + cpBodyEachShape( mBody, &BodyShapeIteratorFunc, (void*)&it ); +} + +void cBody::OnEachShape( cShape * Shape, cShapeIterator * it ) { + if ( it->Func.IsSet() ) { + it->Func( it->Body, Shape, it->Data ); + } +} + +static void BodyConstraintIteratorFunc( cpBody * body, cpConstraint * constraint, void * data ) { + cBody::cConstraintIterator * it = reinterpret_cast ( data ); + it->Body->OnEachConstraint( reinterpret_cast ( constraint->data ), it ); +} + +void cBody::EachConstraint( ConstraintIteratorFunc Func, void * data ) { + cConstraintIterator it( this, data, Func ); + cpBodyEachConstraint( mBody, &BodyConstraintIteratorFunc, (void*)&it ); +} + +void cBody::OnEachConstraint( cConstraint * Constraint, cConstraintIterator * it ) { + if ( it->Func.IsSet() ) { + it->Func( this, Constraint, it->Data ); + } +} + +static void BodyArbiterIteratorFunc( cpBody * body, cpArbiter * arbiter, void * data ) { + cBody::cArbiterIterator * it = reinterpret_cast ( data ); + cArbiter tarb( arbiter ); + it->Body->OnEachArbiter( &tarb, it ); +} + +void cBody::EachArbiter( ArbiterIteratorFunc Func, void * data ) { + cArbiterIterator it( this, data, Func ); + cpBodyEachArbiter( mBody, &BodyArbiterIteratorFunc, (void*)&it ); +} + +void cBody::OnEachArbiter( cArbiter * Arbiter, cArbiterIterator * it ) { + if ( it->Func.IsSet() ) { + it->Func( this, Arbiter, it->Data ); + } +} + CP_NAMESPACE_END diff --git a/src/physics/cbody.hpp b/src/physics/cbody.hpp index 64afc3ec2..1f0ffa0d5 100644 --- a/src/physics/cbody.hpp +++ b/src/physics/cbody.hpp @@ -5,9 +5,55 @@ CP_NAMESPACE_BEGIN -//! TODO: Search for a IsGrounded replacement. +class cShape; +class cConstraint; +class cArbiter; + class CP_API cBody { public: + typedef cb::Callback3 ShapeIteratorFunc; + typedef cb::Callback3 ConstraintIteratorFunc; + typedef cb::Callback3 ArbiterIteratorFunc; + + class cShapeIterator { + public: + cShapeIterator( cBody * body, void * data, ShapeIteratorFunc func ) : + Body( body ), + Data( data ), + Func( func ) + {} + + cBody * Body; + void * Data; + ShapeIteratorFunc Func; + }; + + class cConstraintIterator { + public: + cConstraintIterator( cBody * body, void * data, ConstraintIteratorFunc func ) : + Body( body ), + Data( data ), + Func( func ) + {} + + cBody * Body; + void * Data; + ConstraintIteratorFunc Func; + }; + + class cArbiterIterator { + public: + cArbiterIterator( cBody * body, void * data, ArbiterIteratorFunc func ) : + Body( body ), + Data( data ), + Func( func ) + {} + + cBody * Body; + void * Data; + ArbiterIteratorFunc Func; + }; + static cBody * New( cpFloat m, cpFloat i ); static cBody * New( cpBody * body ); @@ -22,10 +68,12 @@ class CP_API cBody { cBody(); - ~cBody(); + virtual ~cBody(); void Activate(); + void ActivateStatic( cBody *body, cShape * filter ); + void Sleep(); void SleepWithGroup( cBody * Group ); @@ -70,6 +118,10 @@ class CP_API cBody { void AngVel( const cpFloat& angVel ); + cpFloat Torque() const; + + void Torque( const cpFloat& torque ); + cVect Rot() const; cpFloat VelLimit() const; @@ -80,8 +132,6 @@ class CP_API cBody { void AngVelLimit( const cpFloat& speed ); - void Slew( cVect pos, cpFloat dt ); - void UpdateVelocity( cVect gravity, cpFloat damping, cpFloat dt ); void UpdatePosition( cpFloat dt ); @@ -101,11 +151,23 @@ class CP_API cBody { void * Data() const; void Data( void * data ); + + void EachShape( ShapeIteratorFunc Func, void * data ); + + virtual void OnEachShape( cShape * Shape, cShapeIterator * it ); + + void EachConstraint( ConstraintIteratorFunc Func, void * data ); + + virtual void OnEachConstraint( cConstraint * Constraint, cConstraintIterator * it ); + + void EachArbiter( ArbiterIteratorFunc Func, void * data ); + + virtual void OnEachArbiter( cArbiter * Arbiter, cArbiterIterator * it ); protected: friend class cSpace; - cpBody * mBody; - void * mData; + cpBody * mBody; + void * mData; void SetData(); }; diff --git a/src/physics/constraints/cconstraint.cpp b/src/physics/constraints/cconstraint.cpp index f1870df76..5e5db5c6b 100644 --- a/src/physics/constraints/cconstraint.cpp +++ b/src/physics/constraints/cconstraint.cpp @@ -7,12 +7,17 @@ void cConstraint::Free( cConstraint * constraint ) { cpSAFE_DELETE( constraint ); } -cConstraint::cConstraint( cpConstraint * Constraint ) { +cConstraint::cConstraint( cpConstraint * Constraint ) : + mData( NULL ) +{ mConstraint = Constraint; SetData(); } -cConstraint::cConstraint() { +cConstraint::cConstraint() : + mConstraint( NULL ), + mData( NULL ) +{ } cConstraint::~cConstraint() { @@ -54,6 +59,26 @@ void cConstraint::MaxBias( const cpFloat& maxbias ) { mConstraint->maxBias = maxbias; } +cpFloat cConstraint::ErrorBias() { + return cpConstraintGetErrorBias( mConstraint ); +} + +void cConstraint::ErrorBias( cpFloat value ) { + cpConstraintSetErrorBias( mConstraint, value ); +} + +void cConstraint::Data( void * data ) { + mData = data; +} + +void * cConstraint::Data() const { + return mData; +} + +cpFloat cConstraint::Impulse() { + return cpConstraintGetImpulse( mConstraint ); +} + void cConstraint::Draw() { } diff --git a/src/physics/constraints/cconstraint.hpp b/src/physics/constraints/cconstraint.hpp index f4a7abff7..f9ec8ab0a 100644 --- a/src/physics/constraints/cconstraint.hpp +++ b/src/physics/constraints/cconstraint.hpp @@ -29,9 +29,21 @@ class CP_API cConstraint { void MaxBias( const cpFloat& maxbias ); virtual void Draw(); + + cpFloat ErrorBias(); + + void ErrorBias( cpFloat value ); + + void Data( void * data ); + + void * Data() const; + + cpFloat Impulse(); protected: cpConstraint * mConstraint; + void * mData; + cConstraint(); void SetData(); diff --git a/src/physics/cphysicsmanager.hpp b/src/physics/cphysicsmanager.hpp index 6702ecd77..a1b656b36 100644 --- a/src/physics/cphysicsmanager.hpp +++ b/src/physics/cphysicsmanager.hpp @@ -37,7 +37,7 @@ class CP_API cPhysicsManager : public tSingleton { ~cPhysicsManager(); /** The Memory Manager will keep track of all the allocations from cSpace, cBody, cShape and cConstraint and will release any non-released pointer. - *** This is a lazy deallocation for the lazy programmers. It is disabled by defeault. + *** This is a lazy deallocation for the lazy programmers. It is disabled by default. *** To work properly set as active before allocating anything, activate it just before the singleton creation. */ void MemoryManager( bool MemoryManager ); diff --git a/src/physics/cspace.cpp b/src/physics/cspace.cpp index 75798b072..8c3fb8378 100644 --- a/src/physics/cspace.cpp +++ b/src/physics/cspace.cpp @@ -17,7 +17,9 @@ void cSpace::Free( cSpace * space ) { cpSAFE_DELETE( space ); } -cSpace::cSpace() { +cSpace::cSpace() : + mData( NULL ) +{ mSpace = cpSpaceNew(); mSpace->data = (void*)this; mStaticBody = cpNew( cBody, ( mSpace->staticBody ) ); @@ -48,6 +50,14 @@ cSpace::~cSpace() { cPhysicsManager::instance()->RemoveSpace( this ); } +void cSpace::Data( void * data ) { + mData = data; +} + +void * cSpace::Data() const { + return mData; +} + void cSpace::Step( const cpFloat& dt ) { cpSpaceStep( mSpace, dt ); } @@ -116,6 +126,22 @@ cpFloat cSpace::CollisionBias() const { return mSpace->collisionBias; } +cpTimestamp cSpace::CollisionPersistence() { + return cpSpaceGetCollisionPersistence( mSpace ); +} + +void cSpace::CollisionPersistence( cpTimestamp value ) { + cpSpaceSetCollisionPersistence( mSpace, value ); +} + +bool cSpace::EnableContactGraph() { + return cpTrue == cpSpaceGetEnableContactGraph( mSpace ); +} + +void cSpace::EnableContactGraph( bool value ) { + cpSpaceSetEnableContactGraph( mSpace, value ); +} + cBody * cSpace::StaticBody() const { return mStaticBody; } @@ -556,4 +582,52 @@ void cSpace::PointQuery( cVect point, cpLayers layers, cpGroup group, PointQuery cpSpacePointQuery( mSpace, tocpv( point ), layers, group, &RecieverPointQueryFunc, reinterpret_cast( &tPointQuery ) ); } +void cSpace::ReindexShape( cShape * shape ) { + cpSpaceReindexShape( mSpace, shape->Shape() ); +} + +void cSpace::ReindexShapesForBody( cBody *body ) { + cpSpaceReindexShapesForBody( mSpace, body->Body() ); +} + +void cSpace::ReindexStatic() { + cpSpaceReindexStatic( mSpace ); +} + +void cSpace::UseSpatialHash( cpFloat dim, int count ) { + cpSpaceUseSpatialHash( mSpace, dim, count ); +} + +static void SpaceBodyIteratorFunc( cpBody * body, void *data ) { + cSpace::cBodyIterator * it = reinterpret_cast ( data ); + it->Space->OnEachBody( reinterpret_cast( body->data ), it ); +} + +void cSpace::EachBody( BodyIteratorFunc Func, void * data ) { + cBodyIterator it( this, data, Func ); + cpSpaceEachBody( mSpace, &SpaceBodyIteratorFunc, (void*)&it ); +} + +void cSpace::OnEachBody( cBody * Body, cBodyIterator * it ) { + if ( it->Func.IsSet() ) { + it->Func( it->Space, Body, it->Data ); + } +} + +static void SpaceShapeIteratorFunc ( cpShape * shape, void * data ) { + cSpace::cShapeIterator * it = reinterpret_cast ( data ); + it->Space->OnEachShape( reinterpret_cast( shape->data ), it ); +} + +void cSpace::EachShape( ShapeIteratorFunc Func, void * data ) { + cShapeIterator it( this, data, Func ); + cpSpaceEachShape( mSpace, &SpaceShapeIteratorFunc, (void*)&it ); +} + +void cSpace::OnEachShape( cShape * Shape, cShapeIterator * it ) { + if ( it->Func.IsSet() ) { + it->Func( it->Space, Shape, it->Data ); + } +} + CP_NAMESPACE_END diff --git a/src/physics/cspace.hpp b/src/physics/cspace.hpp index 1094e2321..ce9f96255 100644 --- a/src/physics/cspace.hpp +++ b/src/physics/cspace.hpp @@ -19,6 +19,8 @@ class CP_API cSpace { typedef cb::Callback2 BBQueryFunc; typedef cb::Callback4 SegmentQueryFunc; typedef cb::Callback2 PointQueryFunc; + typedef cb::Callback3 BodyIteratorFunc; + typedef cb::Callback3 ShapeIteratorFunc; class cCollisionHandler { public: @@ -90,6 +92,32 @@ class CP_API cSpace { void * Data; }; + class cBodyIterator { + public: + cBodyIterator( cSpace * space, void * data, BodyIteratorFunc func ) : + Space( space ), + Data( data ), + Func( func ) + {} + + cSpace * Space; + void * Data; + BodyIteratorFunc Func; + }; + + class cShapeIterator { + public: + cShapeIterator( cSpace * space, void * data, ShapeIteratorFunc func ) : + Space( space ), + Data( data ), + Func( func ) + {} + + cSpace * Space; + void * Data; + ShapeIteratorFunc Func; + }; + static cSpace * New(); static void Free( cSpace * space ); @@ -132,6 +160,14 @@ class CP_API cSpace { cpFloat CollisionBias() const; + cpTimestamp CollisionPersistence(); + + void CollisionPersistence( cpTimestamp value ); + + bool EnableContactGraph(); + + void EnableContactGraph( bool value ); + bool Contains( cShape * shape ); bool Contains( cBody * body ); @@ -193,9 +229,30 @@ class CP_API cSpace { void SegmentQuery( cVect start, cVect end, cpLayers layers, cpGroup group, SegmentQueryFunc func, void * data ); void PointQuery( cVect point, cpLayers layers, cpGroup group, PointQueryFunc func, void * data ); + + void Data( void * data ); + + void * Data() const; + + void ReindexShape( cShape * shape ); + + void ReindexShapesForBody( cBody *body ); + + void ReindexStatic(); + + void UseSpatialHash( cpFloat dim, int count ); + + void EachShape( ShapeIteratorFunc Func, void * data ); + + virtual void OnEachShape( cShape * Shape, cShapeIterator * it ); + + void EachBody( BodyIteratorFunc Func, void * data ); + + virtual void OnEachBody( cBody * Body, cBodyIterator * it ); protected: cpSpace * mSpace; cBody * mStaticBody; + void * mData; std::list mBodys; std::list mShapes; std::list mConstraints; diff --git a/src/physics/physicshelper.hpp b/src/physics/physicshelper.hpp index a7c78950b..6f961093b 100644 --- a/src/physics/physicshelper.hpp +++ b/src/physics/physicshelper.hpp @@ -1,6 +1,7 @@ #ifndef EE_PHYSICS_HELPER #define EE_PHYSICS_HELPER +#include "base.hpp" #include "../graphics/base.hpp" CP_NAMESPACE_BEGIN diff --git a/src/window/backend/SDL/base.hpp b/src/window/backend/SDL/base.hpp new file mode 100644 index 000000000..106ffa12b --- /dev/null +++ b/src/window/backend/SDL/base.hpp @@ -0,0 +1,22 @@ +#ifndef EE_WINDOWBACKEND_BASE_SDL12_HPP +#define EE_WINDOWBACKEND_BASE_SDL12_HPP + +#include "../../base.hpp" + +#ifdef EE_BACKEND_SDL_ACTIVE + +#include + +#if SDL_VERSION_ATLEAST(1,3,0) + #ifndef EE_BACKEND_SDL_1_3 + #define EE_BACKEND_SDL_1_3 + #endif +#else + #ifndef EE_BACKEND_SDL_1_2 + #define EE_BACKEND_SDL_1_2 + #endif +#endif + +#endif + +#endif diff --git a/src/window/backend/SDL/cbackendsdl.hpp b/src/window/backend/SDL/cbackendsdl.hpp index 866795a6d..abeb8c261 100644 --- a/src/window/backend/SDL/cbackendsdl.hpp +++ b/src/window/backend/SDL/cbackendsdl.hpp @@ -2,11 +2,11 @@ #define EE_WINDOWCBACKENDSDL_HPP #include "../../cbackend.hpp" +#include "base.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 #include "cwindowsdl.hpp" -#include namespace EE { namespace Window { namespace Backend { namespace SDL { diff --git a/src/window/backend/SDL/cclipboardsdl.cpp b/src/window/backend/SDL/cclipboardsdl.cpp index 2ae5bc971..436a8296e 100644 --- a/src/window/backend/SDL/cclipboardsdl.cpp +++ b/src/window/backend/SDL/cclipboardsdl.cpp @@ -1,7 +1,7 @@ #include "cclipboardsdl.hpp" #include "cwindowsdl.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 namespace EE { namespace Window { namespace Backend { namespace SDL { diff --git a/src/window/backend/SDL/cclipboardsdl.hpp b/src/window/backend/SDL/cclipboardsdl.hpp index 9b03c98e6..841e6e59e 100644 --- a/src/window/backend/SDL/cclipboardsdl.hpp +++ b/src/window/backend/SDL/cclipboardsdl.hpp @@ -2,12 +2,11 @@ #define EE_WINDOWCCLIPBOARDSDL_HPP #include "../../cbackend.hpp" +#include "base.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 -#include "../../base.hpp" #include "../../cclipboard.hpp" -#include #if EE_PLATFORM == EE_PLATFORM_WIN || EE_PLATFORM == EE_PLATFORM_MACOSX || defined( EE_X11_PLATFORM ) #include diff --git a/src/window/backend/SDL/ccursormanagersdl.cpp b/src/window/backend/SDL/ccursormanagersdl.cpp index 310d65706..e12e819b7 100644 --- a/src/window/backend/SDL/ccursormanagersdl.cpp +++ b/src/window/backend/SDL/ccursormanagersdl.cpp @@ -1,7 +1,7 @@ #include "ccursormanagersdl.hpp" #include "ccursorsdl.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 namespace EE { namespace Window { namespace Backend { namespace SDL { diff --git a/src/window/backend/SDL/ccursormanagersdl.hpp b/src/window/backend/SDL/ccursormanagersdl.hpp index 5790fb263..c4bec7629 100644 --- a/src/window/backend/SDL/ccursormanagersdl.hpp +++ b/src/window/backend/SDL/ccursormanagersdl.hpp @@ -2,10 +2,9 @@ #define EE_WINDOWCCURSORMANAGERSDL_HPP #include "../../ccursormanager.hpp" +#include "base.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE - -#include +#ifdef EE_BACKEND_SDL_1_2 using namespace EE::Window; diff --git a/src/window/backend/SDL/ccursorsdl.cpp b/src/window/backend/SDL/ccursorsdl.cpp index fc1526323..6586279dc 100644 --- a/src/window/backend/SDL/ccursorsdl.cpp +++ b/src/window/backend/SDL/ccursorsdl.cpp @@ -1,6 +1,6 @@ #include "ccursorsdl.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 namespace EE { namespace Window { namespace Backend { namespace SDL { diff --git a/src/window/backend/SDL/ccursorsdl.hpp b/src/window/backend/SDL/ccursorsdl.hpp index 98eca41c9..c6be4e576 100644 --- a/src/window/backend/SDL/ccursorsdl.hpp +++ b/src/window/backend/SDL/ccursorsdl.hpp @@ -1,9 +1,10 @@ #ifndef EE_WINDOWCCURSORSDL_HPP #define EE_WINDOWCCURSORSDL_HPP -#include "../../ccursor.hpp" +#include "../../ccursor.hpp" +#include "base.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 using namespace EE::Window; diff --git a/src/window/backend/SDL/cinputsdl.cpp b/src/window/backend/SDL/cinputsdl.cpp index 484640382..d13fb9012 100644 --- a/src/window/backend/SDL/cinputsdl.cpp +++ b/src/window/backend/SDL/cinputsdl.cpp @@ -2,7 +2,7 @@ #include "cjoystickmanagersdl.hpp" #include "ccursormanagersdl.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 namespace EE { namespace Window { namespace Backend { namespace SDL { diff --git a/src/window/backend/SDL/cinputsdl.hpp b/src/window/backend/SDL/cinputsdl.hpp index 5cd52d7b7..a63227539 100644 --- a/src/window/backend/SDL/cinputsdl.hpp +++ b/src/window/backend/SDL/cinputsdl.hpp @@ -1,12 +1,13 @@ -#ifndef EE_WINDOWCINPUTSDL_HPP +#ifndef EE_WINDOWCINPUTSDL_HPP #define EE_WINDOWCINPUTSDL_HPP #include "../../cbackend.hpp" +#include "base.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 + +#include "../../cinput.hpp" -#include "../../cinput.hpp" -#include #if EE_PLATFORM == EE_PLATFORM_WIN || EE_PLATFORM == EE_PLATFORM_MACOSX || defined( EE_X11_PLATFORM ) #include #endif @@ -16,7 +17,7 @@ namespace EE { namespace Window { namespace Backend { namespace SDL { class EE_API cInputSDL : public cInput { public: virtual ~cInputSDL(); - + void Update(); bool GrabInput(); @@ -28,7 +29,7 @@ class EE_API cInputSDL : public cInput { friend class cWindowSDL; cInputSDL( Window::cWindow * window ); - + virtual void Init(); }; diff --git a/src/window/backend/SDL/cjoystickmanagersdl.cpp b/src/window/backend/SDL/cjoystickmanagersdl.cpp index 5c2c7954e..07ed667b3 100644 --- a/src/window/backend/SDL/cjoystickmanagersdl.cpp +++ b/src/window/backend/SDL/cjoystickmanagersdl.cpp @@ -1,7 +1,7 @@ #include "cjoystickmanagersdl.hpp" #include "cjoysticksdl.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 namespace EE { namespace Window { namespace Backend { namespace SDL { @@ -39,7 +39,7 @@ void cJoystickManagerSDL::Open() { void cJoystickManagerSDL::Close() { if ( SDL_WasInit( SDL_INIT_JOYSTICK ) ) { SDL_QuitSubSystem( SDL_INIT_JOYSTICK ); - + mInit = false; } } diff --git a/src/window/backend/SDL/cjoystickmanagersdl.hpp b/src/window/backend/SDL/cjoystickmanagersdl.hpp index 311aa2ee0..6eacb4ba1 100644 --- a/src/window/backend/SDL/cjoystickmanagersdl.hpp +++ b/src/window/backend/SDL/cjoystickmanagersdl.hpp @@ -2,20 +2,20 @@ #define EE_WINDOWCJOYSTICKMANAGERSDL_HPP #include "../../cbackend.hpp" +#include "base.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE - +#ifdef EE_BACKEND_SDL_1_2 + #include "../../cjoystickmanager.hpp" -#include namespace EE { namespace Window { namespace Backend { namespace SDL { class EE_API cJoystickManagerSDL : public cJoystickManager { public: cJoystickManagerSDL(); - + virtual ~cJoystickManagerSDL(); - + void Update(); void Close(); diff --git a/src/window/backend/SDL/cjoysticksdl.cpp b/src/window/backend/SDL/cjoysticksdl.cpp index 00e0ce090..1aa626aa3 100644 --- a/src/window/backend/SDL/cjoysticksdl.cpp +++ b/src/window/backend/SDL/cjoysticksdl.cpp @@ -1,6 +1,6 @@ #include "cjoysticksdl.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 namespace EE { namespace Window { namespace Backend { namespace SDL { diff --git a/src/window/backend/SDL/cjoysticksdl.hpp b/src/window/backend/SDL/cjoysticksdl.hpp index dbf6b6350..b488fa61a 100644 --- a/src/window/backend/SDL/cjoysticksdl.hpp +++ b/src/window/backend/SDL/cjoysticksdl.hpp @@ -2,11 +2,11 @@ #define EE_WINDOWCJOYSTICKSDL_HPP #include "../../cbackend.hpp" +#include "base.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 #include "../../cjoystick.hpp" -#include namespace EE { namespace Window { namespace Backend { namespace SDL { diff --git a/src/window/backend/SDL/cwindowsdl.cpp b/src/window/backend/SDL/cwindowsdl.cpp index e64cfa34d..3d2a8fe9e 100644 --- a/src/window/backend/SDL/cwindowsdl.cpp +++ b/src/window/backend/SDL/cwindowsdl.cpp @@ -1,6 +1,6 @@ #include "cwindowsdl.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 #include "cclipboardsdl.hpp" #include "cinputsdl.hpp" @@ -369,7 +369,6 @@ eeWindowHandler cWindowSDL::GetWindowHandler() { #elif defined( EE_X11_PLATFORM ) return mWMinfo.info.x11.display; #elif EE_PLATFORM == EE_PLATFORM_MACOSX - //return mWMinfo.cocoa.window; return mWMinfo.info.x11.display; #else return 0; diff --git a/src/window/backend/SDL/cwindowsdl.hpp b/src/window/backend/SDL/cwindowsdl.hpp index 370814c0a..a2c9f2a9d 100644 --- a/src/window/backend/SDL/cwindowsdl.hpp +++ b/src/window/backend/SDL/cwindowsdl.hpp @@ -2,11 +2,12 @@ #define EE_WINDOWCWINDOWSDL_HPP #include "../../cbackend.hpp" +#include "base.hpp" -#ifdef EE_BACKEND_SDL_ACTIVE +#ifdef EE_BACKEND_SDL_1_2 #include "../../cwindow.hpp" -#include + #if EE_PLATFORM == EE_PLATFORM_WIN || EE_PLATFORM == EE_PLATFORM_MACOSX || defined( EE_X11_PLATFORM ) #include #endif @@ -16,13 +17,13 @@ namespace EE { namespace Window { namespace Backend { namespace SDL { class EE_API cWindowSDL : public cWindow { public: cWindowSDL( WindowSettings Settings, ContextSettings Context ); - + virtual ~cWindowSDL(); - + bool Create( WindowSettings Settings, ContextSettings Context ); - + void ToggleFullscreen(); - + void Caption( const std::string& Caption ); bool Icon( const std::string& Path ); diff --git a/src/window/backend/SDL13/base.hpp b/src/window/backend/SDL13/base.hpp index 0b97e8eab..094ff8647 100644 --- a/src/window/backend/SDL13/base.hpp +++ b/src/window/backend/SDL13/base.hpp @@ -16,4 +16,3 @@ #endif #endif - diff --git a/src/window/backend/SDL13/cinputsdl.cpp b/src/window/backend/SDL13/cinputsdl.cpp index 173dc6e37..38cd62900 100644 --- a/src/window/backend/SDL13/cinputsdl.cpp +++ b/src/window/backend/SDL13/cinputsdl.cpp @@ -289,6 +289,8 @@ void cInputSDL::Init() { void cInputSDL::InitializeTables() { Uint32 i; + memset( &mKeyCodesTable[0], 0, SDL_NUM_SCANCODES ); + for ( i = SDL_SCANCODE_A; i <= SDL_SCANCODE_Z; i++ ) mKeyCodesTable[ i ] = KEY_A + i - SDL_SCANCODE_A; diff --git a/src/window/backend/SDL13/cwindowsdl.cpp b/src/window/backend/SDL13/cwindowsdl.cpp index 8716bb387..571c1e159 100644 --- a/src/window/backend/SDL13/cwindowsdl.cpp +++ b/src/window/backend/SDL13/cwindowsdl.cpp @@ -337,11 +337,11 @@ void cWindowSDL::SetGamma( eeFloat Red, eeFloat Green, eeFloat Blue ) { eeWindowHandler cWindowSDL::GetWindowHandler() { #if EE_PLATFORM == EE_PLATFORM_WIN - return mWMinfo.window; + return mWMinfo.info.win.window; #elif defined( EE_X11_PLATFORM ) return mWMinfo.info.x11.display; #elif EE_PLATFORM == EE_PLATFORM_MACOSX - return mWMinfo.cocoa.window; + return mWMinfo.info.cocoa.window; #else return 0; #endif diff --git a/src/window/cinput.cpp b/src/window/cinput.cpp index c5d925df6..9a089ab71 100644 --- a/src/window/cinput.cpp +++ b/src/window/cinput.cpp @@ -40,7 +40,10 @@ void cInput::SendEvent( InputEvent * Event ) { void cInput::ProcessEvent( InputEvent * Event ) { switch( Event->Type ) { case InputEvent::KeyDown: - { + { + if ( Event->key.keysym.sym > EE_KEYS_NUM ) + break; + if ( Event->key.keysym.mod != 0xFFFFFFFF ) mInputMod = Event->key.keysym.mod; @@ -48,7 +51,10 @@ void cInput::ProcessEvent( InputEvent * Event ) { break; } case InputEvent::KeyUp: - { + { + if ( Event->key.keysym.sym > EE_KEYS_NUM ) + break; + PushKey( &mKeysDown [ Event->key.keysym.sym / 8 ], Event->key.keysym.sym % 8, false ); PushKey( &mKeysUp [ Event->key.keysym.sym / 8 ], Event->key.keysym.sym % 8, true ); break; @@ -103,7 +109,7 @@ void cInput::ProcessEvent( InputEvent * Event ) { mLastButtonLeftClick = eeGetTicks(); mTClick = mLastButtonLeftClick - mLastButtonLeftClicked; - + if ( mTClick < mDoubleClickInterval && mTClick > 0 ) { mDoubleClickTrigger |= EE_BUTTON_MASK(EE_BUTTON_LEFT); mLastButtonLeftClick = 0; @@ -114,7 +120,7 @@ void cInput::ProcessEvent( InputEvent * Event ) { mLastButtonRightClick = eeGetTicks(); mTClick = mLastButtonRightClick - mLastButtonRightClicked; - + if ( mTClick < mDoubleClickInterval && mTClick > 0 ) { mDoubleClickTrigger |= EE_BUTTON_MASK(EE_BUTTON_RIGHT); mLastButtonRightClick = 0; @@ -125,7 +131,7 @@ void cInput::ProcessEvent( InputEvent * Event ) { mLastButtonMiddleClick = eeGetTicks(); mTClick = mLastButtonMiddleClick - mLastButtonMiddleClicked; - + if ( mTClick < mDoubleClickInterval && mTClick > 0 ) { mDoubleClickTrigger |= EE_BUTTON_MASK(EE_BUTTON_MIDDLE); mLastButtonMiddleClick = 0; @@ -146,7 +152,7 @@ void cInput::ProcessEvent( InputEvent * Event ) { break; } } - + SendEvent( Event ); } diff --git a/src/window/inputhelper.hpp b/src/window/inputhelper.hpp index ff4af4b28..f5d50e1de 100644 --- a/src/window/inputhelper.hpp +++ b/src/window/inputhelper.hpp @@ -5,11 +5,12 @@ #include "base.hpp" namespace EE { namespace Window { - -#define EE_KEYS_SPACE (336/8) + +#define EE_KEYS_NUM (336) +#define EE_KEYS_SPACE (EE_KEYS_NUM/8) Uint32 EE_API eeConvertKeyCharacter( const Uint32& KeyCode, const Uint16& Unicode, const Uint32& Modifiers ); }} -#endif +#endif