Browse Source

Merge branch 'development'

Mike Lilligreen 11 years ago
parent
commit
9aaed1cea2
32 changed files with 1000 additions and 108 deletions
  1. 1 1
      README.md
  2. 1 0
      engine/source/2d/assets/ParticleAssetEmitter.cc
  3. 15 2
      engine/source/2d/assets/ParticleAssetField.cc
  4. 1 1
      engine/source/2d/assets/ParticleAsset_ScriptBinding.h
  5. 12 0
      engine/source/2d/core/SpriteBatch.cc
  6. 1 0
      engine/source/2d/core/SpriteBatch.h
  7. 12 0
      engine/source/2d/core/SpriteBatchItem.cc
  8. 68 1
      engine/source/2d/core/Utility.cc
  9. 2 0
      engine/source/2d/core/Utility.h
  10. 3 1
      engine/source/2d/gui/SceneWindow_ScriptBinding.h
  11. 168 36
      engine/source/2d/gui/guiSpriteCtrl.cc
  12. 18 7
      engine/source/2d/gui/guiSpriteCtrl.h
  13. 325 21
      engine/source/2d/gui/guiSpriteCtrl_ScriptBindings.h
  14. 33 0
      engine/source/2d/sceneobject/CompositeSprite_ScriptBinding.h
  15. 2 2
      engine/source/2d/sceneobject/ImageFont_ScriptBinding.h
  16. 2 2
      engine/source/2d/sceneobject/ParticlePlayer_ScriptBinding.h
  17. 2 2
      engine/source/2d/sceneobject/SceneObject.cc
  18. 4 2
      engine/source/2d/sceneobject/SceneObject.h
  19. 0 2
      engine/source/2d/sceneobject/SceneObject_ScriptBinding.h
  20. 4 4
      engine/source/2d/sceneobject/ShapeVector_ScriptBinding.h
  21. 1 0
      engine/source/game/defaultGame.cc
  22. 2 2
      engine/source/game/version.h
  23. 230 2
      engine/source/graphics/gFont.cc
  24. 4 0
      engine/source/graphics/gFont.h
  25. 53 1
      engine/source/input/actionMap.cc
  26. 1 1
      engine/source/io/stream.h
  27. 2 1
      engine/source/persistence/taml/json/tamlJSONReader.cc
  28. 3 0
      engine/source/persistence/taml/taml.cc
  29. 4 2
      engine/source/platformWin32/winDInputDevice.cc
  30. 1 1
      engine/source/platformWin32/winDInputDevice.h
  31. 25 14
      engine/source/platformWin32/winDirectInput.cc
  32. BIN
      engine/source/platformWin32/winInput_ScriptBinding.h

+ 1 - 1
README.md

@@ -1,5 +1,5 @@
 ![Torque Logo](http://static.garagegames.com/static/pg/logokits/Torque-Logo_H.png)
-## Torque 2D 3.0
+## Torque 2D 3.1
 
 MIT Licensed Open Source version of Torque 2D from GarageGames. Maintained by the T2D Steering Committee and contributions from the community.
 

+ 1 - 0
engine/source/2d/assets/ParticleAssetEmitter.cc

@@ -205,6 +205,7 @@ ParticleAssetEmitter::ParticleAssetEmitter() :
     mAnimationAsset.registerRefreshNotify( this );
     
     mNamedImageFrame = "";
+    mUsingNamedFrame = false;
 }
 
 //------------------------------------------------------------------------------

+ 15 - 2
engine/source/2d/assets/ParticleAssetField.cc

@@ -670,8 +670,21 @@ void ParticleAssetField::onTamlCustomRead( const TamlCustomNode* pCustomNode )
         keys.push_back( key );
     }
 
-    // Set the value bounds.
-    setValueBounds( maxTime, minValue, maxValue, defaultValue );
+    // If value bounds are present but no keys, assign the field its default values.
+    if ( !keys.size() )
+    {
+        DataKey key;
+        key.mTime = getMinTime();
+        key.mValue = getDefaultValue();
+        keys.push_back( key );
+    }
+
+    // Did we read in any value bounds?
+    if ( mValueBoundsDirty )
+    {
+        // Set the value bounds.
+        setValueBounds( maxTime, minValue, maxValue, defaultValue );
+    }
 
     // Set the value scale.
     setValueScale( valueScale );

+ 1 - 1
engine/source/2d/assets/ParticleAsset_ScriptBinding.h

@@ -143,7 +143,7 @@ ConsoleMethodWithDocs(ParticleAsset, deselectField, ConsoleVoid, 2, 2, ())
 /*! Gets the selected field name or nothing if no field is selected.
     @return The selected field name or nothing if no fields is selected.
 */
-ConsoleMethodWithDocs(ParticleAsset, getSelectedField, ConsoleBool, 2, 2, ())
+ConsoleMethodWithDocs(ParticleAsset, getSelectedField, ConsoleString, 2, 2, ())
 {
     // Get the selected field.
     const ParticleAssetField* pParticleAssetField = object->getParticleFields().getSelectedField();

+ 12 - 0
engine/source/2d/core/SpriteBatch.cc

@@ -457,6 +457,18 @@ bool SpriteBatch::selectSpriteName( const char* pName )
 
 //------------------------------------------------------------------------------
 
+U32 SpriteBatch::getSpriteId( void ) const
+{
+    // Finish if a sprite is not selected.
+    if ( !checkSpriteSelected() )
+        return 0;
+
+    // Get sprite id.
+    return mSelectedSprite->getBatchId();
+}
+
+//------------------------------------------------------------------------------
+
 void SpriteBatch::setSpriteImage( const char* pAssetId, const U32 imageFrame )
 {
     // Debug Profiling.

+ 1 - 0
engine/source/2d/core/SpriteBatch.h

@@ -120,6 +120,7 @@ public:
     bool selectSpriteName( const char* pName );
     inline void deselectSprite( void ) { mSelectedSprite = NULL; }
     bool isSpriteSelected( void ) const { return mSelectedSprite != NULL; }
+    U32 getSpriteId( void ) const;
 
     void setSpriteImage( const char* pAssetId, const U32 imageFrame );
     void setSpriteImage( const char* pAssetId, const char* namedFrame );

+ 12 - 0
engine/source/2d/core/SpriteBatchItem.cc

@@ -57,6 +57,7 @@ static StringTableEntry spriteImageFrameName        = StringTable->insert("Frame
 static StringTableEntry spriteNamedImageFrameName   = StringTable->insert("NamedFrame");
 static StringTableEntry spriteAnimationName         = StringTable->insert("Animation");
 static StringTableEntry spriteDataObjectName        = StringTable->insert("DataObject");
+static StringTableEntry spriteUserDataName          = StringTable->insert("UserData");
 
 //------------------------------------------------------------------------------
 
@@ -433,6 +434,12 @@ void SpriteBatchItem::onTamlCustomWrite( TamlCustomNode* pParentNode )
     // Write data object.
     if ( getDataObject() != NULL )
         pSpriteNode->addNode( getDataObject() );
+
+    if ( getUserData() != NULL)
+    {   
+        const char* UserDatastr = (const char*) getUserData();
+        pSpriteNode->addField( "UserData", UserDatastr );
+    }
 }
 
 //------------------------------------------------------------------------------
@@ -582,6 +589,11 @@ void SpriteBatchItem::onTamlCustomRead( const TamlCustomNode* pSpriteNode )
             // Set logical position.
             setLogicalPosition( LogicalPosition( pLogicalPositionArgs ) );
         }
+        else if ( fieldName == spriteUserDataName )
+        {
+            StringTableEntry UserDatastr = StringTable->insert(pSpriteField->getFieldValue());
+            setUserData((void *)UserDatastr);
+        }
     }
 
     // Fetch sprite children.

+ 68 - 1
engine/source/2d/core/Utility.cc

@@ -41,7 +41,7 @@ ConsoleGetType( Typeb2AABB )
 
     // Format AABB.
     char* pBuffer = Con::getReturnBuffer(64);
-    dSprintf(pBuffer, 64, "%.5g %.5g", pAABB->lowerBound.x, pAABB->lowerBound.y, pAABB->upperBound.x, pAABB->upperBound.y );
+    dSprintf(pBuffer, 64, "%.5g %.5g %.5g %.5g", pAABB->lowerBound.x, pAABB->lowerBound.y, pAABB->upperBound.x, pAABB->upperBound.y );
     return pBuffer;
 }
 
@@ -327,4 +327,71 @@ U32 mGetStringElementCount( const char* inString )
     return wordCount;
 }
 
+//-----------------------------------------------------------------------------
+
+U32 mConvertStringToMask( const char* string )
+{
+    // Grab the element count of the first parameter.
+    const U32 elementCount = Utility::mGetStringElementCount(string);
+
+    // Make sure we get at least one number.
+    if (elementCount < 1)
+        return MASK_ALL;
+    else if ( elementCount == 1 )
+    {
+        if ( dStricmp( string, "all" ) == 0 )
+            return MASK_ALL;
+        else if ( dStricmp( string, "none" ) == 0 || dStricmp( string, "off" ) == 0 )
+            return 0;
+    }
+
+    // The mask.
+    U32 mask = 0;
+
+    // Convert the string to a mask.
+    for (U32 i = 0; i < elementCount; i++)
+    {
+        S32 bit = dAtoi(Utility::mGetStringElement(string, i));
+         
+        // Make sure the group is valid.
+        if ((bit < 0) || (bit >= MASK_BITCOUNT))
+        {
+            Con::warnf("Utility::mConvertStringToMask() - Invalid group specified (%d); skipped!", bit);
+            continue;
+        }
+         
+        mask |= (1 << bit);
+    }
+
+    return mask;
+}
+
+//-----------------------------------------------------------------------------
+
+const char* mConvertMaskToString( const U32 mask )
+{
+    bool first = true;
+    static char bits[128];
+    bits[0] = '\0';
+
+    if (!mask)
+    {
+        dSprintf(bits, 8, "none");
+        return bits;
+    }
+    
+    for (S32 i = 0; i < MASK_BITCOUNT; i++)
+    {
+        if (mask & BIT(i))
+        {
+            char bit[4];
+            dSprintf(bit, 4, "%s%d", first ? "" : " ", i);
+            first = false;
+            dStrcat(bits, bit);
+        }
+    }
+
+    return bits;
+}
+
 } // Namespace Utility

+ 2 - 0
engine/source/2d/core/Utility.h

@@ -80,6 +80,8 @@ Vector2 mGetStringElementVector( const char* inString, const U32 index = 0 );
 VectorF mGetStringElementVector3D( const char* inString, const U32 index = 0 );
 const char* mGetStringElement( const char* inString, const U32 index, const bool copyBuffer = true );
 U32 mGetStringElementCount( const char *string );
+U32 mConvertStringToMask( const char* string );
+const char* mConvertMaskToString( const U32 mask );
 
 } // Namespace Utility.
 

+ 3 - 1
engine/source/2d/gui/SceneWindow_ScriptBinding.h

@@ -374,9 +374,11 @@ ConsoleMethodWithDocs(SceneWindow, getTargetCameraSize, ConsoleString, 2, 2, ())
 //-----------------------------------------------------------------------------
 
 /*! Set the target camera area.
+    @param x1 / y1 Coordinates of the upper left corner of the target area.
+    @param x2 / y2 Coordinates of the lower right corner of the target area.
     @return No return value.
 */
-ConsoleMethodWithDocs(SceneWindow, setTargetCameraArea, ConsoleVoid, 3, 6, (x / y / width / height))
+ConsoleMethodWithDocs(SceneWindow, setTargetCameraArea, ConsoleVoid, 3, 6, (x1 / y1 / x2 / y2))
 {
    // Upper left bound.
    Vector2 v1;

+ 168 - 36
engine/source/2d/gui/guiSpriteCtrl.cc

@@ -45,11 +45,16 @@ IMPLEMENT_CONOBJECT(GuiSpriteCtrl);
 //-----------------------------------------------------------------------------
 
 GuiSpriteCtrl::GuiSpriteCtrl( void ) :
-    mImageAssetId( StringTable->EmptyString ),
-    mAnimationAssetId( StringTable->EmptyString )
+    mImageAssetId(StringTable->EmptyString),
+    mImageFrameId(0),
+    mNamedImageFrameId(StringTable-> EmptyString),
+    mAnimationAssetId(StringTable->EmptyString)
 {
-	// Set to self ticking.
-	mSelfTick = true;
+    // Set to self ticking.
+    mSelfTick = true;
+    
+    // Default to static provider.
+    mStaticProvider = true;
 }
 
 //-----------------------------------------------------------------------------
@@ -65,9 +70,37 @@ void GuiSpriteCtrl::initPersistFields()
     // Call parent.
     Parent::initPersistFields();
 
-    addProtectedField( "Image", TypeAssetId, Offset(mImageAssetId, GuiSpriteCtrl), &setImage, &getImage, &writeImage, "The image asset Id used for the image." );
-    addProtectedField( "Frame", TypeS32, Offset(mImageFrame, GuiSpriteCtrl), &setImageFrame, &defaultProtectedGetFn, &writeImageFrame, "The image frame used for the image." );
-    addProtectedField( "Animation", TypeAssetId, Offset(mAnimationAssetId, GuiSpriteCtrl), &setAnimation, &getAnimation, &writeAnimation, "The animation to use.");
+    addProtectedField("Image", TypeAssetId, Offset(mImageAssetId, GuiSpriteCtrl), &setImage, &defaultProtectedGetFn, &writeImage, "The image asset Id used for the image.");
+    addProtectedField("Frame", TypeS32, Offset(mImageFrameId, GuiSpriteCtrl), &setImageFrame, &defaultProtectedGetFn, &writeImageFrame, "The image frame used for the image.");
+    addProtectedField("NamedFrame", TypeString, Offset(mNamedImageFrameId, GuiSpriteCtrl), &setNamedImageFrame, &defaultProtectedGetFn, &writeNamedImageFrame, "The named image frame used for the image");
+    addProtectedField("Animation", TypeAssetId, Offset(mAnimationAssetId, GuiSpriteCtrl), &setAnimation, &defaultProtectedGetFn, &writeAnimation, "The animation to use.");
+}
+
+//------------------------------------------------------------------------------
+
+void GuiSpriteCtrl::copyTo(SimObject* object)
+{
+    // Call to parent.
+    Parent::copyTo(object);
+
+    // Cast to control.
+    GuiSpriteCtrl* pGuiSpriteCtrl = static_cast<GuiSpriteCtrl*>(object);
+
+    // Sanity!
+    AssertFatal(pGuiSpriteCtrl != NULL, "GuiSpriteCtrl::copyTo() - Object is not the correct type.");
+
+    // Copy asset fields.
+    if ( mImageAssetId != StringTable->EmptyString )
+    {
+        if ( !isUsingNamedImageFrame() )
+            pGuiSpriteCtrl->setImage( getImage(), getImageFrame() );
+        else
+            pGuiSpriteCtrl->setImage( getImage(), getNamedImageFrame() ); 
+    }
+    else if ( mAnimationAssetId != StringTable->EmptyString )
+    {
+        pGuiSpriteCtrl->setAnimation( getAnimation() );
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -81,13 +114,26 @@ bool GuiSpriteCtrl::onWake()
     // Are we in static mode?
     if ( mImageAssetId != StringTable->EmptyString )
     {
-        // Set image asset.
-		ImageFrameProvider::setImage( mImageAssetId );
+        if ( mNamedImageFrameId != StringTable->EmptyString)
+        {
+            // Set the image asset and named frame
+            ImageFrameProvider::setImage( mImageAssetId, mNamedImageFrameId );
+        }
+        else
+        {
+            // Set image asset and numerical frame.
+            ImageFrameProvider::setImage( mImageAssetId, mImageFrameId );
+        }
     }
     else if ( mAnimationAssetId != StringTable->EmptyString )
     {
         // Play animation asset.
-		ImageFrameProvider::setAnimation( mAnimationAssetId );
+        ImageFrameProvider::setAnimation( mAnimationAssetId );
+    }
+    else
+    {
+        // Not good, so warn.
+        Con::warnf("GuiSpriteCtrl::onWake() - No Image or Animation Asset defined.");
     }
 
     return true;
@@ -98,7 +144,7 @@ bool GuiSpriteCtrl::onWake()
 void GuiSpriteCtrl::onSleep()
 {
     // Clear assets.
-	ImageFrameProvider::clearAssets();
+    ImageFrameProvider::clearAssets();
 
     // Call parent.
     Parent::onSleep();
@@ -106,46 +152,130 @@ void GuiSpriteCtrl::onSleep()
 
 //-----------------------------------------------------------------------------
 
-bool GuiSpriteCtrl::setImage( const char* pImageAssetId )
+bool GuiSpriteCtrl::setImage( const char* pImageAssetId, const U32 frame )
+{
+    // Sanity!
+    AssertFatal( pImageAssetId != NULL, "Cannot use a NULL asset Id." );
+
+    // Reset animation.
+    if ( mAnimationAssetId != StringTable->EmptyString )
+        mAnimationAssetId = StringTable->EmptyString;
+
+    // Fetch the asset Id.
+    if ( mImageAssetId != pImageAssetId )
+        mImageAssetId = StringTable->insert(pImageAssetId);
+
+    // Set the image frame if the image asset was set.
+    if ( mImageAssetId != StringTable->EmptyString )
+        setImageFrame(frame);
+
+    // Finish if not awake.
+    if ( !isAwake() )
+        return true;
+
+    // Call parent.
+    if ( !ImageFrameProvider::setImage(pImageAssetId, frame) )
+        return false;
+
+    // Update control.
+    setUpdate();
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+
+bool GuiSpriteCtrl::setImage( const char* pImageAssetId, const char* pNamedFrame )
 {
     // Sanity!
     AssertFatal( pImageAssetId != NULL, "Cannot use a NULL asset Id." );
 
     // Reset animation.
-    mAnimationAssetId = StringTable->EmptyString;
+    if ( mAnimationAssetId != StringTable->EmptyString )
+        mAnimationAssetId = StringTable->EmptyString;
 
     // Fetch the asset Id.
-    mImageAssetId = StringTable->insert(pImageAssetId);
+    if ( mImageAssetId != pImageAssetId )
+        mImageAssetId = StringTable->insert(pImageAssetId);
 
-    // Reset image frame.
-	mImageFrame = 0;
+    // Set the image frame if the image asset was set.
+    if ( mImageAssetId != StringTable->EmptyString )
+        setNamedImageFrame(pNamedFrame);
 
-	// Finish if not awake.
+    // Finish if not awake.
     if ( !isAwake() )
-		return true;
+        return true;
 
-	// Call parent.
-	if ( !ImageFrameProvider::setImage( pImageAssetId, mImageFrame ) )
-		return false;
+    // Call parent.
+    if ( !ImageFrameProvider::setImage(pImageAssetId, pNamedFrame) )
+        return false;
 
     // Update control.
     setUpdate();
 
-	return true;
+    return true;
 }
 
 //-----------------------------------------------------------------------------
 
 bool GuiSpriteCtrl::setImageFrame( const U32 frame )
 {
-	// Call parent.
-	if ( !ImageFrameProvider::setImageFrame( frame ) )
-		return false;
+    // Check Existing Image.
+    if ( mImageAssetId == StringTable->EmptyString )
+    {
+        // Warn.
+        Con::warnf("GuiSpriteCtrl::setImageFrame() - Cannot set frame without existing asset Id.");
+
+        // Return Here.
+        return false;
+    }
+
+    // Set frame.
+    mImageFrameId = frame;
+
+    // Finish if not awake.
+    if ( !isAwake() )
+        return true;
+
+    // Call parent.
+    if ( !ImageFrameProvider::setImageFrame(frame) )
+        return false;
+
+    // Update control.
+    setUpdate();
+
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+
+bool GuiSpriteCtrl::setNamedImageFrame( const char* pNamedFrame )
+{
+    // Check Existing Image.
+    if ( mImageAssetId == StringTable->EmptyString )
+    {
+        // Warn.
+        Con::warnf("GuiSpriteCtrl::setNamedImageFrame() - Cannot set named frame without existing asset Id.");
+
+        // Return Here.
+        return false;
+    }
+
+    // Set named frame.
+    mNamedImageFrameId = StringTable->insert(pNamedFrame);
+
+    // Finish if not awake.
+    if ( !isAwake() )
+        return true;
+
+    // Call parent.
+    if ( !ImageFrameProvider::setNamedImageFrame(pNamedFrame) )
+        return false;
 
     // Update control.
     setUpdate();
 
-	return true;
+    return true;
 }
 
 //-----------------------------------------------------------------------------
@@ -155,29 +285,31 @@ bool GuiSpriteCtrl::setAnimation( const char* pAnimationAssetId )
     // Sanity!
     AssertFatal( pAnimationAssetId != NULL, "Cannot use a NULL asset Id." );
 
-    // Fetch the asset Id.
-    mAnimationAssetId = StringTable->insert(pAnimationAssetId);
-
     // Reset the image asset Id.
-    mImageAssetId = StringTable->EmptyString;
+    if ( mImageAssetId != StringTable->EmptyString )
+        mImageAssetId = StringTable->EmptyString;
+
+    // Fetch the asset Id.
+    if ( mAnimationAssetId != pAnimationAssetId )
+        mAnimationAssetId = StringTable->insert(pAnimationAssetId);
 
     // Finish if not awake.
     if ( !isAwake() )
-		return true;
+        return true;
 
     // Play animation asset if it's valid.
     if ( mAnimationAssetId != StringTable->EmptyString )
-		ImageFrameProvider::setAnimation( mAnimationAssetId );
+        ImageFrameProvider::setAnimation( mAnimationAssetId );
 
-	return true;
+    return true;
 }
 
 //-----------------------------------------------------------------------------
 
 void GuiSpriteCtrl::onRender( Point2I offset, const RectI &updateRect)
 {
-	// Call parent.
-	ImageFrameProvider::renderGui( *this, offset, updateRect );
+    // Call parent.
+    ImageFrameProvider::renderGui( *this, offset, updateRect );
 }
 
 //------------------------------------------------------------------------------
@@ -185,5 +317,5 @@ void GuiSpriteCtrl::onRender( Point2I offset, const RectI &updateRect)
 void GuiSpriteCtrl::onAnimationEnd( void )
 {
     // Clear assets.
-	ImageFrameProvider::clearAssets();
+    ImageFrameProvider::clearAssets();
 }

+ 18 - 7
engine/source/2d/gui/guiSpriteCtrl.h

@@ -36,6 +36,8 @@ private:
 
 protected:
     StringTableEntry                mImageAssetId;
+    U32                             mImageFrameId;
+    StringTableEntry                mNamedImageFrameId;
     StringTableEntry                mAnimationAssetId;
 
 public:
@@ -46,10 +48,19 @@ public:
     void onRender(Point2I offset, const RectI &updateRect);
     static void initPersistFields();
 
-	/// Static and Animated Assets.
-    virtual bool setImage( const char* pImageAssetId );
+    virtual void copyTo(SimObject* object);
+
+    // Static and Animated Assets.
+    inline bool setImage( const char* pImageAssetId ) { return setImage( pImageAssetId, mImageFrame ); }
+    virtual bool setImage( const char* pImageAssetId, const U32 frame );
+    virtual bool setImage( const char* pImageAssetId, const char* pNamedFrame );
+    inline StringTableEntry getImage( void ) const{ return mImageAssetId; }
     virtual bool setImageFrame( const U32 frame );
+    inline U32 getImageFrame( void ) const { return mImageFrameId; }
+    virtual bool setNamedImageFrame ( const char* namedFrame );
+    inline StringTableEntry getNamedImageFrame( void ) const { return mNamedImageFrameId; }
     virtual bool setAnimation( const char* pAnimationAssetId );
+    inline StringTableEntry getAnimation( void ) const { return mAnimationAssetId; }
 
     // Declare type.
     DECLARE_CONOBJECT(GuiSpriteCtrl);
@@ -59,13 +70,13 @@ protected:
 
 protected:
     static bool setImage(void* obj, const char* data) { static_cast<GuiSpriteCtrl*>(obj)->setImage( data ); return false; }
-    static const char* getImage(void* obj, const char* data) { return DYNAMIC_VOID_CAST_TO(GuiSpriteCtrl, ImageFrameProvider, obj)->getImage(); }
-    static bool writeImage( void* obj, StringTableEntry pFieldName ) { GuiSpriteCtrl* pCastObject = static_cast<GuiSpriteCtrl*>(obj); if ( !pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mImageAssetId != StringTable->EmptyString; }
+    static bool writeImage(void* obj, StringTableEntry pFieldName) { GuiSpriteCtrl* pCastObject = static_cast<GuiSpriteCtrl*>(obj); if ( !pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mImageAssetId != StringTable->EmptyString; }
     static bool setImageFrame(void* obj, const char* data) { static_cast<GuiSpriteCtrl*>(obj)->setImageFrame( dAtoi(data) ); return false; }
-    static bool writeImageFrame( void* obj, StringTableEntry pFieldName ) { GuiSpriteCtrl* pCastObject = static_cast<GuiSpriteCtrl*>(obj); return pCastObject->isStaticFrameProvider() && pCastObject->getImageFrame() > 0; }
+    static bool writeImageFrame(void* obj, StringTableEntry pFieldName) { GuiSpriteCtrl* pCastObject = static_cast<GuiSpriteCtrl*>(obj); if ( !pCastObject->isStaticFrameProvider() || pCastObject->isUsingNamedImageFrame() ) return false; return pCastObject->getImageFrame() > 0; }
+    static bool setNamedImageFrame(void* obj, const char* data) { static_cast<GuiSpriteCtrl*>(obj)->setNamedImageFrame(data); return false; }
+    static bool writeNamedImageFrame(void* obj, StringTableEntry pFieldName) { GuiSpriteCtrl* pCastObject = static_cast<GuiSpriteCtrl*>(obj); if ( !pCastObject->isStaticFrameProvider() || !pCastObject->isUsingNamedImageFrame() ) return false; return pCastObject->mNamedImageFrameId != StringTable->EmptyString; }
     static bool setAnimation(void* obj, const char* data) { static_cast<GuiSpriteCtrl*>(obj)->setAnimation(data); return false; };
-    static const char* getAnimation(void* obj, const char* data) { return DYNAMIC_VOID_CAST_TO(GuiSpriteCtrl, ImageFrameProvider, obj)->getAnimation(); }
-    static bool writeAnimation( void* obj, StringTableEntry pFieldName ) { GuiSpriteCtrl* pCastObject = static_cast<GuiSpriteCtrl*>(obj); if ( pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mAnimationAssetId != StringTable->EmptyString; }
+    static bool writeAnimation(void* obj, StringTableEntry pFieldName) { GuiSpriteCtrl* pCastObject = static_cast<GuiSpriteCtrl*>(obj); if ( pCastObject->isStaticFrameProvider() ) return false; return pCastObject->mAnimationAssetId != StringTable->EmptyString; }
 };
 
 #endif //_GUISPRITECTRL_H_

+ 325 - 21
engine/source/2d/gui/guiSpriteCtrl_ScriptBindings.h

@@ -22,23 +22,55 @@
 
 ConsoleMethodGroupBeginWithDocs(GuiSpriteCtrl, GuiControl)
 
-/*! Gets whether the control is in static or dynamic (animated)mode.
-    @return Returns whether the control is in static or dynamic (animated)mode.
+/*! Gets whether the control is in static or dynamic (animated) mode.
+    @return Returns whether the control is in static or dynamic (animated) mode.
 */
-ConsoleMethodWithDocs( GuiSpriteCtrl, isStaticFrameProvider, ConsoleBool, 2, 2, ())
+ConsoleMethodWithDocs(GuiSpriteCtrl, isStaticFrameProvider, ConsoleBool, 2, 2, ())
 {
     return object->isStaticFrameProvider();
 }
 
+//------------------------------------------------------------------------------
+
+/*! Gets whether the control is using a numerical or named image frame.
+    @return Returns true when using a named frame, false when using a numerical index.
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, isUsingNamedImageFrame, ConsoleBool, 2, 2, ())
+{
+    return object->isUsingNamedImageFrame();
+}
+
 //-----------------------------------------------------------------------------
 
-/*! Sets the image asset Id to use as the image.
-    @param imageAssetId The image asset Id to use as the image.
-    @return No return value.
+/*! Sets the control image and optionally the frame.
+    @param imageAssetId The image asset Id to display
+    @param frame The numerical or named frame of the image to display
+    @return Returns true on success.
 */
-ConsoleMethodWithDocs( GuiSpriteCtrl, setImage, ConsoleVoid, 3, 3, (imageAssetId))
+ConsoleMethodWithDocs(GuiSpriteCtrl, setImage, ConsoleBool, 3, 4, (imageAssetId, [frame]))
 {
-   object->setImage( argv[2] );
+    // Was a frame specified?
+    if (argc >= 4)
+    {
+        // Was it a number or a string?
+        if (!dIsalpha(*argv[3]))
+        {
+            // Fetch the numerical frame and set the image
+            const U32 frame = argc >= 4 ? dAtoi(argv[3]) : 0;
+            return object->setImage( argv[2], frame );
+        }
+        else
+        {
+            // Set the image and pass the named frame string
+            return object->setImage( argv[2], argv[3] );
+        }
+    }
+    else
+    {
+        // Frame was not specified, use default 0 and set the image
+        const U32 frame = 0;
+        return object->setImage( argv[2], frame );
+    }
 }
 
 //------------------------------------------------------------------------------
@@ -46,18 +78,18 @@ ConsoleMethodWithDocs( GuiSpriteCtrl, setImage, ConsoleVoid, 3, 3, (imageAssetId
 /*! Gets current image asset Id.
     @return (string imageAssetId) The image being displayed.
 */
-ConsoleMethodWithDocs( GuiSpriteCtrl, getImage, ConsoleString, 2, 2, ())
+ConsoleMethodWithDocs(GuiSpriteCtrl, getImage, ConsoleString, 2, 2, ())
 {
     // Are we in static mode?
     if ( !object->isStaticFrameProvider() )
     {
         // No, so warn.
-        Con::warnf( "GuiSpriteCtrl::getImage() - Method invalid, not in static mode." );
+        Con::warnf("GuiSpriteCtrl::getImage() - Method invalid, not in static mode.");
         return StringTable->EmptyString;
     }
 
     // Get image.
-    return DYNAMIC_VOID_CAST_TO(GuiSpriteCtrl, ImageFrameProvider, object)->getImage();
+    return object->getImage();
 }
 
 //-----------------------------------------------------------------------------
@@ -66,23 +98,39 @@ ConsoleMethodWithDocs( GuiSpriteCtrl, getImage, ConsoleString, 2, 2, ())
     @param imageFrame The image frame to use as the image.
     @return No return value.
 */
-ConsoleMethodWithDocs( GuiSpriteCtrl, setImageFrame, ConsoleVoid, 3, 3, (int imageFrame))
+ConsoleMethodWithDocs(GuiSpriteCtrl, setImageFrame, ConsoleBool, 3, 3, (int imageFrame))
 {
-   object->setImageFrame( dAtoi(argv[2]) );
+    // Are we in static mode?
+    if ( !object->isStaticFrameProvider() )
+    {
+        // No, so warn.
+        Con::warnf("GuiSpriteCtrl::setImageFrame() - Method invalid, not in static mode.");
+        return false;
+    }
+
+    return object->setImageFrame( dAtoi(argv[2]) );
 }
 
 //------------------------------------------------------------------------------
 
-/*! Gets current image Frame.
-    @return (int frame) The frame currently being displayed.
+/*! Gets current numerical image frame.
+    @return (int frame) The numerical frame currently being displayed.
 */
-ConsoleMethodWithDocs( GuiSpriteCtrl, getImageFrame, ConsoleInt, 2, 2, ())
+ConsoleMethodWithDocs(GuiSpriteCtrl, getImageFrame, ConsoleInt, 2, 2, ())
 {
     // Are we in static mode?
     if ( !object->isStaticFrameProvider() )
     {
         // No, so warn.
-        Con::warnf( "GuiSpriteCtrl::getFrame() - Method invalid, not in static mode." );
+        Con::warnf("GuiSpriteCtrl::getImageFrame() - Method invalid, not in static mode.");
+        return -1;
+    }
+
+    // Are we using a named image frame?
+    if ( object->isUsingNamedImageFrame() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::getImageFrame() - Method invalid, using a named image frame.");
         return -1;
     }
 
@@ -92,11 +140,57 @@ ConsoleMethodWithDocs( GuiSpriteCtrl, getImageFrame, ConsoleInt, 2, 2, ())
 
 //------------------------------------------------------------------------------
 
+/*! Sets the image frame using a named string.
+    @param frame The named frame to display
+    @return Returns true on success.
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, setNamedImageFrame, ConsoleBool, 3, 3, (frame))
+{
+    // Are we in static mode?
+    if ( !object->isStaticFrameProvider() )
+    {
+        // No, so warn.
+        Con::warnf("GuiSpriteCtrl::setNamedImageFrame() - Method invalid, not in static mode.");
+        return false;
+    }
+
+    // Set the numerical frame
+    return object->setNamedImageFrame( argv[2] );
+}
+
+//------------------------------------------------------------------------------
+
+/*! Gets the current named image frame.
+    @return The current named image frame.
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, getNamedImageFrame, ConsoleString, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( !object->isStaticFrameProvider() )
+    {
+        // No, so warn.
+        Con::warnf("GuiSpriteCtrl::getNamedImageFrame() - Method invalid, not in static mode.");
+        return NULL;
+    }
+
+    // Are we using a named image frame?
+    if ( !object->isUsingNamedImageFrame() )
+    {
+        // No, so warn.
+        Con::warnf("GuiSpriteCtrl::getNamedImageFrame() - Method invalid, not using a named image frame.");
+        return NULL;
+    }
+
+    return object->getNamedImageFrame();
+}
+
+//------------------------------------------------------------------------------
+
 /*! Sets the animation asset Id to display.
     @param animationAssetId The animation asset Id to play
     @return No return value.
 */
-ConsoleMethodWithDocs( GuiSpriteCtrl, setAnimation, ConsoleVoid, 3, 3, (string animationAssetId))
+ConsoleMethodWithDocs(GuiSpriteCtrl, setAnimation, ConsoleVoid, 3, 3, (string animationAssetId))
 {
     // Set animation.
     object->setAnimation( argv[2] );
@@ -107,18 +201,228 @@ ConsoleMethodWithDocs( GuiSpriteCtrl, setAnimation, ConsoleVoid, 3, 3, (string a
 /*! Gets the current animation asset Id.
     @return (string ianimationAssetId) The animation being displayed.
 */
-ConsoleMethodWithDocs( GuiSpriteCtrl, getAnimation, ConsoleString, 2, 2, ())
+ConsoleMethodWithDocs(GuiSpriteCtrl, getAnimation, ConsoleString, 2, 2, ())
 {
     // Are we in static mode?
     if ( object->isStaticFrameProvider() )
     {
         // Yes, so warn.
-        Con::warnf( "GuiSpriteCtrl::getAnimation() - Method invalid, in static mode." );
+        Con::warnf("GuiSpriteCtrl::getAnimation() - Method invalid, in static mode.");
         return StringTable->EmptyString;
     }
 
     // Get animation.
-    return DYNAMIC_VOID_CAST_TO(GuiSpriteCtrl, ImageFrameProvider, object)->getAnimation();
+    return object->getAnimation();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Pause the current animation
+    @param enable If true, pause the animation. If false, continue animating
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, pauseAnimation, ConsoleVoid, 3, 3, (bool enable))
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::pauseAnimation() - Method invalid, not in dynamic (animated) mode.");
+        return;
+    }
+
+    return static_cast<ImageFrameProvider*>(object)->pauseAnimation(dAtob(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Stop the current animation
+    @return No return value.
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, stopAnimation, ConsoleVoid, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::stopAnimation() - Method invalid, not in dynamic (animated) mode.");
+        return;
+    }
+
+    object->stopAnimation();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Sets the current animation frame. IMPORTANT: this is not the image frame number used in the animation!
+    @param frame Which frame of the animation to display
+    @return No return value.
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, setAnimationFrame, ConsoleVoid, 3, 3, (int frame))
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::setAnimationFrame() - Method invalid, not in dynamic (animated) mode.");
+        return;
+    }
+
+    // Set Animation Frame
+    object->setAnimationFrame( dAtoi(argv[2]) );
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets current frame index used in the animation. IMPORTANT: this is not the image frame number!
+    @return The current numerical animation frame
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, getAnimationFrame, ConsoleInt, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::getAnimationFrame() - Method invalid, not in dynamic (animated) mode.");
+        return -1;
+    }
+
+    // Get Animation Frame.
+    return object->getAnimationFrame();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets current numerical image frame used in the animation.
+    @return The current numerical animation frame
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, getAnimationImageFrame, ConsoleInt, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::getAnimationImageFrame() - Method invalid, not in dynamic (animated) mode.");
+        return -1;
+    }
+
+    // Get the current animation asset
+    const AnimationAsset* asset = object->getCurrentAnimation();
+    
+    // Are we using named animation frames?
+    if (asset->getNamedCellsMode())
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::getAnimationImageFrame() - Method invalid, animation is in named cells mode.");
+        return -1;
+    }
+
+    // Get Image Frame.
+    return object->getCurrentAnimationFrame();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets current named image frame used in the animation.
+    @return The current named animation frame
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, getAnimationNamedImageFrame, ConsoleString, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::getAnimationNamedImageFrame() - Method invalid, not in dynamic (animated) mode.");
+        return NULL;
+    }
+    
+    // Get the current animation asset
+    const AnimationAsset* asset = object->getCurrentAnimation();
+
+    // Are we using named animation frames?
+    if (!asset->getNamedCellsMode())
+    {
+        // No, so warn.
+        Con::warnf("GuiSpriteCtrl::getAnimationNamedImageFrame() - Method invalid, animation not in named cells mode.");
+        return NULL;
+    }
+
+    // Get Image Frame.
+    return object->getCurrentNamedAnimationFrame();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets current animation time.
+    @return (float time) The current animation time
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, getAnimationTime, ConsoleFloat, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::getAnimationTime() - Method invalid, not in dynamic (animated) mode.");
+        return 0.0f;
+    }
+
+
+    // Get Animation Time.
+    return object->getCurrentAnimationTime();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Checks animation status.
+    @return (bool finished) Whether or not the animation is finished
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, getIsAnimationFinished, ConsoleBool, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::getIsAnimationFinished() - Method invalid, not in dynamic (animated) mode.");
+        return true;
+    }
+
+    // Return Animation Finished Status.
+    return object->isAnimationFinished();
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Change the rate of animation.
+    @param timeScale Value which will scale the frame animation speed. 1 by default.
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, setAnimationTimeScale, ConsoleVoid, 3, 3, (float timeScale))
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::setAnimationTimeScale() - Method invalid, not in dynamic (animated) mode.");
+        return;
+    }
+
+    object->setAnimationTimeScale(dAtof(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Get the animation time scale for this control.
+    @return (float) Returns the animation time scale for this control.
+*/
+ConsoleMethodWithDocs(GuiSpriteCtrl, getAnimationTimeScale, ConsoleFloat, 2, 2, ())
+{
+    // Are we in static mode?
+    if ( object->isStaticFrameProvider() )
+    {
+        // Yes, so warn.
+        Con::warnf("GuiSpriteCtrl::getAnimationTimeScale() - Method invalid, not in dynamic (animated) mode.");
+        return 1.0f;
+    }
+
+    return object->getAnimationTimeScale();
 }
 
 ConsoleMethodGroupEndWithDocs(GuiSpriteCtrl)

+ 33 - 0
engine/source/2d/sceneobject/CompositeSprite_ScriptBinding.h

@@ -1019,6 +1019,29 @@ ConsoleMethodWithDocs(CompositeSprite, getSpriteDataObject, ConsoleString, 2, 2,
 
 //-----------------------------------------------------------------------------
 
+/*! Set the sprite user data field.
+    @param data A space separated string containing the data you wish to store.
+    @return No return Value.
+*/
+ConsoleMethodWithDocs(CompositeSprite, setSpriteUserData, ConsoleVoid, 3, 3, (data))
+{
+    StringTableEntry userData = StringTable->insert(argv[2]);
+    object->setUserData( (void*)userData );
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets the sprite user data.
+    @return The sprite user data.
+*/
+ConsoleMethodWithDocs(CompositeSprite, getSpriteUserData, ConsoleString, 2, 2, ())
+{
+    const char* userData = (const char*) object->getUserData();
+    return userData;
+}
+
+//-----------------------------------------------------------------------------
+
 /*! Set the sprite name.
     This must be unique within this composite sprite instance.  To clear the name you can pass an empty string.
     @return No return Value.
@@ -1040,6 +1063,16 @@ ConsoleMethodWithDocs(CompositeSprite, getSpriteName, ConsoleString, 2, 2, ())
 
 //-----------------------------------------------------------------------------
 
+/*! Gets the SpriteBatchId of the currently selected sprite.
+    @returns The SpriteBatchId
+*/
+ConsoleMethodWithDocs(CompositeSprite, getSpriteId, ConsoleInt, 2, 2, ())
+{
+    return object->getSpriteId();
+}
+
+//-----------------------------------------------------------------------------
+
 /*! Picks sprites intersecting the specified point with optional group/layer masks.
     @param x/y The coordinate of the point as either (\x y\ or (x,y)
     @return Returns list of sprite Ids.

+ 2 - 2
engine/source/2d/sceneobject/ImageFont_ScriptBinding.h

@@ -144,7 +144,7 @@ ConsoleMethodWithDocs(ImageFont, getFontSize, ConsoleString, 2, 2, ())
 ConsoleMethodWithDocs(ImageFont, setFontPadding, ConsoleVoid, 3, 3, (padding))
 {
    // Set character padding.
-   object->setFontPadding( dAtoi(argv[2]) );
+   object->setFontPadding( dAtof(argv[2]) );
 
 }
 
@@ -153,7 +153,7 @@ ConsoleMethodWithDocs(ImageFont, setFontPadding, ConsoleVoid, 3, 3, (padding))
 /*! Gets the font padding.
     @return The font padding.
 */
-ConsoleMethodWithDocs(ImageFont, getFontPadding, ConsoleInt, 2, 2, ())
+ConsoleMethodWithDocs(ImageFont, getFontPadding, ConsoleFloat, 2, 2, ())
 {
     return object->getFontPadding();
 }

+ 2 - 2
engine/source/2d/sceneobject/ParticlePlayer_ScriptBinding.h

@@ -250,7 +250,7 @@ ConsoleMethodWithDocs(ParticlePlayer, setEmitterPaused, ConsoleVoid, 4, 4, (paus
 */
 ConsoleMethodWithDocs(ParticlePlayer, getEmitterPaused, ConsoleBool, 3, 3, (emitterIndex))
 {
-    return object->getEmitterPaused( dAtob(argv[2]) );
+    return object->getEmitterPaused( dAtoi(argv[2]) );
 }
 
 //-----------------------------------------------------------------------------
@@ -273,7 +273,7 @@ ConsoleMethodWithDocs(ParticlePlayer, setEmitterVisible, ConsoleVoid, 4, 4, (vis
 */
 ConsoleMethodWithDocs(ParticlePlayer, getEmitterVisible, ConsoleBool, 3, 3, (emitterIndex))
 {
-    return object->getEmitterVisible( dAtob(argv[2]) );
+    return object->getEmitterVisible( dAtoi(argv[2]) );
 }
 
 ConsoleMethodGroupEndWithDocs(ParticlePlayer)

+ 2 - 2
engine/source/2d/sceneobject/SceneObject.cc

@@ -282,8 +282,8 @@ void SceneObject::initPersistFields()
     addProtectedField("SleepingAllowed", TypeBool, NULL, &setSleepingAllowed, &getSleepingAllowed, &writeSleepingAllowed, "" );
 
     /// Collision control.
-    addProtectedField("CollisionGroups", TypeS32, Offset(mCollisionGroupMask, SceneObject), &setCollisionGroups, &defaultProtectedGetFn, &writeCollisionGroups, "");
-    addProtectedField("CollisionLayers", TypeS32, Offset(mCollisionLayerMask, SceneObject), &setCollisionLayers, &defaultProtectedGetFn, &writeCollisionLayers, "");
+    addProtectedField("CollisionGroups", TypeS32, Offset(mCollisionGroupMask, SceneObject), &setCollisionGroups, &getCollisionGroups, &writeCollisionGroups, "");
+    addProtectedField("CollisionLayers", TypeS32, Offset(mCollisionLayerMask, SceneObject), &setCollisionLayers, &getCollisionLayers, &writeCollisionLayers, "");
     addField("CollisionSuppress", TypeBool, Offset(mCollisionSuppress, SceneObject), &writeCollisionSuppress, "");
     addProtectedField("GatherContacts", TypeBool, NULL, &setGatherContacts, &defaultProtectedGetFn, &writeGatherContacts, "");
     addProtectedField("DefaultDensity", TypeF32, Offset( mDefaultFixture.density, SceneObject), &setDefaultDensity, &defaultProtectedGetFn, &writeDefaultDensity, "");

+ 4 - 2
engine/source/2d/sceneobject/SceneObject.h

@@ -658,9 +658,11 @@ protected:
     static bool             writeDefaultFriction( void* obj, StringTableEntry pFieldName ) {return mNotEqual(static_cast<SceneObject*>(obj)->getDefaultFriction(), 0.2f); }
     static bool             setDefaultRestitution(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setDefaultRestitution(dAtof(data)); return false; }
     static bool             writeDefaultRestitution( void* obj, StringTableEntry pFieldName ) { return mNotEqual(static_cast<SceneObject*>(obj)->getDefaultRestitution(), 0.0f); }
-    static bool             setCollisionGroups(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionGroupMask(dAtoi(data)); return false; }
+    static bool             setCollisionGroups(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionGroupMask(Utility::mConvertStringToMask(data)); return false; }
+    static const char*      getCollisionGroups(void* obj, const char* data) { return Utility::mConvertMaskToString( static_cast<SceneObject*>(obj)->getCollisionGroupMask() ); }
     static bool             writeCollisionGroups( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionGroupMask() != MASK_ALL; }
-    static bool             setCollisionLayers(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionLayerMask(dAtoi(data)); return false; }
+    static bool             setCollisionLayers(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionLayerMask(Utility::mConvertStringToMask(data)); return false; }
+    static const char*      getCollisionLayers(void* obj, const char* data) { return Utility::mConvertMaskToString( static_cast<SceneObject*>(obj)->getCollisionLayerMask() ); }
     static bool             writeCollisionLayers( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionLayerMask() != MASK_ALL; }
     static bool             writeCollisionSuppress( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionSuppress() == true; }
     static bool             setGatherContacts(void* obj, const char* data)  { static_cast<SceneObject*>(obj)->setGatherContacts(dAtoi(data)); return false; }

+ 0 - 2
engine/source/2d/sceneobject/SceneObject_ScriptBinding.h

@@ -1287,8 +1287,6 @@ ConsoleMethodWithDocs(SceneObject, setCollisionLayers, ConsoleVoid, 2, 2 + MASK_
             object->setCollisionLayerMask(0);
             return;
         }
-
-        return;
     }
 
     // The mask.

+ 4 - 4
engine/source/2d/sceneobject/ShapeVector_ScriptBinding.h

@@ -105,7 +105,7 @@ ConsoleMethodWithDocs(ShapeVector, getWorldPoly, ConsoleString, 2, 2, ())
 
 //----------------------------------------------------------------------------
 
-/*! or ( stockColorName ) - Sets the line color.
+/*! RGBA value or ( stockColorName ) - Sets the line color.
     @param red The red value.
     @param green The green value.
     @param blue The blue value.
@@ -130,7 +130,7 @@ ConsoleMethodWithDocs(ShapeVector, setLineColor, ConsoleVoid, 3, 6, (float red,
         if ( elementCount == 1 )
         {
             // Set color.
-            Con::setData( TypeColorF, &const_cast<ColorF&>(object->getBlendColor()), 0, 1, &(argv[2]) );
+            Con::setData( TypeColorF, &const_cast<ColorF&>(object->getLineColor()), 0, 1, &(argv[2]) );
             return;
         }
 
@@ -216,7 +216,7 @@ ConsoleMethodWithDocs(ShapeVector, setLineAlpha, ConsoleVoid, 3, 3, (alpha))
 
 //----------------------------------------------------------------------------
 
-/*! or ( stockColorName ) - Sets the fill color.
+/*! RGBA value or ( stockColorName ) - Sets the fill color.
     @param red The red value.
     @param green The green value.
     @param blue The blue value.
@@ -241,7 +241,7 @@ ConsoleMethodWithDocs(ShapeVector, setFillColor, ConsoleVoid, 3, 3, (float red,
         if ( elementCount == 1 )
         {
             // Set color.
-            Con::setData( TypeColorF, &const_cast<ColorF&>(object->getBlendColor()), 0, 1, &(argv[2]) );
+            Con::setData( TypeColorF, &const_cast<ColorF&>(object->getFillColor()), 0, 1, &(argv[2]) );
             return;
         }
 

+ 1 - 0
engine/source/game/defaultGame.cc

@@ -145,6 +145,7 @@ bool initializeLibraries()
     ResourceManager->registerExtension(".jpeg", constructBitmapJPEG);
     ResourceManager->registerExtension(".png", constructBitmapPNG);
     ResourceManager->registerExtension(".uft", constructNewFont);
+    ResourceManager->registerExtension(".fnt", constructBMFont);
 
 #ifdef TORQUE_OS_IOS
     ResourceManager->registerExtension(".pvr", constructBitmapPVR);

+ 2 - 2
engine/source/game/version.h

@@ -24,8 +24,8 @@
 #define _ENGINE_VERSION_H_
 
 // Engine Version.
-#define T2D_ENGINE_VERSION      		"v2.0"        ///< Engine Version String.
-#define T2D_IPHONETOOLS_VERSION      	"v2.0"          ///< Engine Version String for iPhone tools. Changing this will allow a fresh AppData folder to avoid conflicts with other builds existing on the system.
+#define T2D_ENGINE_VERSION            "v3.1"    ///< Engine Version String.
+#define T2D_IPHONETOOLS_VERSION       "v3.1"    ///< Engine Version String for iPhone tools. Changing this will allow a fresh AppData folder to avoid conflicts with other builds existing on the system.
 
 /// Gets the specified version number.  The version number is specified as a global in version.cc
 U32 getVersionNumber();

+ 230 - 2
engine/source/graphics/gFont.cc

@@ -29,6 +29,7 @@
 #include "graphics/gBitmap.h"
 #include "io/fileStream.h"
 #include "string/findMatch.h"
+#include "string/stringUnit.h"
 #include "graphics/TextureManager.h"
 #include "graphics/gFont.h"
 #include "memory/safeDelete.h"
@@ -101,9 +102,20 @@ void GFont::getFontCacheFilename(const char *faceName, U32 size, U32 buffLen, ch
 Resource<GFont> GFont::create(const char *faceName, U32 size, const char *cacheDirectory, U32 charset /* = TGE_ANSI_CHARSET */)
 {
    char buf[256];
+   Resource<GFont> ret;
+    
+    dSprintf(buf, sizeof(buf), "%s/%s %d (%s).fnt", cacheDirectory, faceName, size, getFontCharSetName(charset));
+    
+    ret = ResourceManager->load(buf);
+    if(bool(ret))
+    {
+        ret->mGFTFile = StringTable->insert(buf);
+        return ret;
+    }
+
    dSprintf(buf, sizeof(buf), "%s/%s %d (%s).uft", cacheDirectory, faceName, size, getFontCharSetName(charset));
 
-   Resource<GFont> ret = ResourceManager->load(buf);
+   ret = ResourceManager->load(buf);
    if(bool(ret))
    {
       ret->mGFTFile = StringTable->insert(buf);
@@ -654,7 +666,7 @@ bool GFont::read(Stream& io_rStream)
        mTextureSheets.increment();
        constructInPlace(&mTextureSheets.last());
        mTextureSheets.last() = TextureHandle(buf, bmp, TextureHandle::BitmapKeepTexture);
-       mTextureSheets.last().setFilter(GL_NEAREST);;
+       mTextureSheets.last().setFilter(GL_NEAREST);
    }
    
    // Read last position info
@@ -1008,3 +1020,219 @@ void GFont::importStrip(const char *fileName, U32 padding, U32 kerning)
    for(S32 i=0; i<sheetSizes.size(); i++)
       mTextureSheets[i].refresh();
 }
+
+// ==================================
+// bmFont support
+// ==================================
+
+ResourceInstance* constructBMFont(Stream& stream)
+{
+
+    GFont *ret = new GFont;
+
+    if(!ret->readBMFont(stream))
+    {
+        SAFE_DELETE(ret);
+        ret = NULL;
+    }
+
+    return ret;
+}
+
+bool GFont::readBMFont(Stream& io_rStream)
+{
+    for (U32 i = 0; i < (sizeof(mRemapTable) / sizeof(S32)); i++)
+        mRemapTable[i] = -1;
+    
+    U32 bmWidth = 0;
+    U32 bmHeight = 0;
+    U32 numSheets = 0;
+    U32 currentPage = 0;
+    StringTableEntry fileName = StringTable->insert("");
+    
+    U32 numBytes = io_rStream.getStreamSize() - io_rStream.getPosition();
+    while((io_rStream.getStatus() != Stream::EOS) && numBytes > 0)
+    {
+        char Read[256];
+        char Token[256];
+        char *buffer = Con::getReturnBuffer(256);
+        io_rStream.readLine((U8 *)buffer, 256);
+        
+        char temp[256];
+        U32 tokenCount = StringUnit::getUnitCount(buffer, "\"");
+        
+        if (tokenCount > 1)
+        {
+            dSprintf(Token, 256, "%s", StringUnit::getUnit(buffer, 1, "\""));
+            dSprintf(temp, 256, "tok1");
+            dSprintf(buffer, 256, "%s", (char*)StringUnit::setUnit(buffer, 1, temp, "\""));
+        }
+        
+        U32 wordCount = StringUnit::getUnitCount(buffer, " \t\n");
+        
+        dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, 0, " \t\n"));
+        if( dStrcmp( Read, "info") == 0 )
+        {
+            U32 currentWordCount = 1;
+            while( currentWordCount < wordCount )
+            {
+                dSprintf(Read, 256, StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+                char temp[256];
+                char Key[256];
+                char Value[256];
+                
+                dSprintf(temp, 256, "%s", Read);
+                dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+                dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+                
+                if (dStrcmp( Value, "\"tok1\"") == 0) {
+                    dSprintf(Value, 256, "%s", Token);
+                }
+                
+                if( dStrcmp( Key, "size" ) == 0 )
+                    mSize = U16(dAtoi(Value));
+                currentWordCount++;
+            }
+        }
+        if( dStrcmp( Read, "common" ) == 0 )
+        {
+            U32 currentWordCount = 1;
+            //this holds common data
+            while( currentWordCount < wordCount )
+            {
+                dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+                char temp[256];
+                char Key[256];
+                char Value[256];
+                
+                dSprintf(temp, 256, "%s", Read);
+                dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+                dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+                
+                if (dStrcmp( Value, "\"tok1\"") == 0) {
+                    dSprintf(Value, 256, "%s", Token);
+                }
+                
+                if( dStrcmp( Key, "lineHeight" ) == 0 )
+                     mHeight = U16(dAtoi(Value));
+                else if( dStrcmp( Key, "base" ) == 0 )
+                    mBaseline = U16(dAtoi(Value));
+                else if( dStrcmp( Key, "scaleW" ) == 0 )
+                    bmWidth = U16(dAtoi(Value));
+                else if( dStrcmp( Key, "scaleH" ) == 0 )
+                    bmHeight = U16(dAtoi(Value));
+                else if( dStrcmp( Key, "pages" ) == 0 )
+                    numSheets = U16(dAtoi(Value));
+                currentWordCount++;
+            }
+            mAscent = mBaseline;
+            mDescent = mHeight - mBaseline;
+        }
+        else if( dStrcmp( Read, "page" ) == 0 )
+        {
+            //this is data for a page
+            U32 currentWordCount = 1;
+            //this holds common data
+            char lineLeft[256];
+            dSprintf ( lineLeft, 256, "%s", StringUnit::getUnit(buffer, 1, " \t\n"));
+            
+            while( currentWordCount < wordCount )
+            {
+                dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+                char temp[256];
+                char Key[256];
+                char Value[256];
+                
+                dSprintf(temp, 256, "%s", Read);
+                dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+                dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+                
+                if (dStrcmp( Value, "\"tok1\"") == 0) {
+                    dSprintf(Value, 256, "%s", Token);
+                }
+                
+                //assign the correct value
+                if( dStrcmp( Key, "id" ) == 0 )
+                    currentPage = U32(dAtoi(Value));
+                else if (dStrcmp( Key, "file" ) == 0 )
+                    fileName = StringTable->insert(Value);
+
+                currentWordCount++;
+            }
+        }
+        
+        else if( dStrcmp( Read, "char" ) == 0 )
+        {
+            PlatformFont::CharInfo ci; //  = &mCharInfoList[charIndex];
+            ci.bitmapData = NULL;
+            ci.bitmapIndex = currentPage;
+            //this is data for a character set
+            U16 CharID = 0;
+            U32 currentWordCount = 1;
+            //this holds common data
+            while( currentWordCount < wordCount )
+            {
+                dSprintf(Read, 256, "%s", StringUnit::getUnit(buffer, currentWordCount, " \t\n"));
+                char temp[256];
+                char Key[256];
+                char Value[256];
+                
+                
+                dSprintf(temp, 256, "%s", Read);
+                dSprintf(Key, 256, "%s", StringUnit::getUnit(temp, 0, "="));
+                dSprintf(Value, 256, "%s", StringUnit::getUnit(temp, 1, "="));
+                
+                if (dStrcmp( Value, "\"tok1\"") == 0) {
+                    dSprintf(Value, 256, "%s", Token);
+                }
+                
+                //assign the correct value
+                if( dStrcmp( Key, "id" ) == 0 )
+                    CharID = U32(dAtoi(Value));
+                if( dStrcmp( Key, "x" ) == 0 )
+                    ci.xOffset = U32(dAtoi(Value));
+                else if( dStrcmp( Key, "y" ) == 0 )
+                    ci.yOffset = U32(dAtoi(Value));
+                else if( dStrcmp( Key, "width" ) == 0 )
+                    ci.width = U32(dAtoi(Value));
+                else if( dStrcmp( Key, "height" ) == 0 )
+                    ci.height = U32(dAtoi(Value));
+                else if( dStrcmp( Key, "xoffset" ) == 0 )
+                    ci.xOrigin = S32(dAtoi(Value));
+                else if( dStrcmp( Key, "yoffset" ) == 0 )
+                    ci.yOrigin = mBaseline - S32(dAtoi(Value));
+                else if( dStrcmp( Key, "xadvance" ) == 0 )
+                    ci.xIncrement = S32(dAtoi(Value));
+                currentWordCount++;
+            }
+            mCharInfoList.push_back(ci);
+            mRemapTable[ CharID ] = mCharInfoList.size()-1;
+        }
+    }
+    
+    for(U32 i = 0; i < numSheets; i++)
+    {
+        char buf[1024];
+        dSprintf(buf, sizeof(buf), "%s/%s", Con::getVariable("$GUI::fontCacheDirectory"), fileName);
+        Con::printf("Platform::makeFullPathName %s", buf);
+        
+        GBitmap *bmp = dynamic_cast<GBitmap*>(ResourceManager->loadInstance(buf));
+        
+        if(bmp == NULL)
+        {
+            return false;
+        }
+        
+        char buff[30];
+        dSprintf(buff, sizeof(buff), "font_%d", smSheetIdCount++);
+        
+        mTextureSheets.increment();
+        constructInPlace(&mTextureSheets.last());
+        mTextureSheets.last() = TextureHandle(buf, bmp, TextureHandle::BitmapKeepTexture);
+        mTextureSheets.last().setFilter(GL_NEAREST);
+    }
+    return (io_rStream.getStatus() == Stream::EOS);
+}
+
+
+

+ 4 - 0
engine/source/graphics/gFont.h

@@ -52,12 +52,14 @@
 
 
 extern ResourceInstance* constructNewFont(Stream& stream);
+extern ResourceInstance* constructBMFont(Stream& stream);
 
 class TextureHandle;
 
 class GFont : public ResourceInstance
 {
    friend ResourceInstance* constructNewFont(Stream& stream);
+   friend ResourceInstance* constructBMFont(Stream& stream);
 
    static const U32 csm_fileVersion;
    static S32 smSheetIdCount;
@@ -174,6 +176,8 @@ public:
    /// Get the face name of the font.
    StringTableEntry getFontFaceName() const { return mFaceName; };
 
+   bool readBMFont(Stream& io_rStream);
+
    bool read(Stream& io_rStream);
    bool write(Stream& io_rStream);
 

+ 53 - 1
engine/source/input/actionMap.cc

@@ -1607,7 +1607,59 @@ bool ActionMap::processMove(const InputEvent* pEvent)
 
         return true;
     }
-    else if ( pEvent->deviceType == JoystickDeviceType || pEvent->deviceType == GamepadDeviceType )
+    else if ( pEvent->deviceType == JoystickDeviceType )
+    {
+        // Joystick events...
+        const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier,   pEvent->objType );
+
+        if( pNode == NULL )
+            return false;
+
+        // "Do nothing" bind:
+        if ( !pNode->consoleFunction[0] )
+            return( true );
+
+        // Whadda ya know, we have this bound.  Set up, and call the console
+        //  function associated with it.  Joystick move events are the same as mouse
+        //  move events except that they don't ignore dead zone.
+        //
+        F32 value = pEvent->fValues[0];
+        if ( pNode->flags & Node::Inverted )
+            value *= -1.0f;
+
+        if ( pNode->flags & Node::HasScale )
+            value *= pNode->scaleFactor;
+
+        if ( pNode->flags & Node::HasDeadZone )
+        {
+            if ( value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd )
+            {
+                value = 0.0f;
+            }
+            else
+            {
+                if( value > 0 )
+                    value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
+                else
+                    value = ( value + pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
+            }
+        }
+
+        if( pNode->flags & Node::NonLinear )
+            value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
+
+        // Ok, we're all set up, call the function.
+        argv[0] = pNode->consoleFunction;
+        argv[1] = Con::getFloatArg( value );
+            
+        if (pNode->object)
+            Con::executef(pNode->object, 2, argv[0], argv[1]);
+        else
+            Con::execute(2, argv);
+
+        return true;
+    }
+    else if ( pEvent->deviceType == GamepadDeviceType )
     {
         // Joystick events...
         const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier,   pEvent->objInst );

+ 1 - 1
engine/source/io/stream.h

@@ -169,7 +169,7 @@ class Stream {
    }
    DECLARE_OVERLOADED_WRITE(S8)
    DECLARE_OVERLOADED_WRITE(U8)
-   DECLARE_OVERLOADED_WRITE(char)
+   DECLARE_OVERLOADED_WRITE(UTF8)
 
    DECLARE_ENDIAN_OVERLOADED_WRITE(S16)
    DECLARE_ENDIAN_OVERLOADED_WRITE(S32)

+ 2 - 1
engine/source/persistence/taml/json/tamlJSONReader.cc

@@ -45,6 +45,7 @@ SimObject* TamlJSONReader::read( FileStream& stream )
         Con::warnf("TamlJSONReader::read() -  Could not load Taml JSON file from stream.");
         return NULL;
     }
+    jsonText[streamSize] = NULL;
 
     // Create JSON document.
     rapidjson::Document document;
@@ -662,7 +663,7 @@ inline const char* TamlJSONReader::getTamlObjectName( const rapidjson::Value& va
         StringTableEntry attributeName = StringTable->insert( memberItr->name.GetString() );
 
         // Skip if not the correct attribute.
-        if ( attributeName != tamlRefToIdName )
+        if ( attributeName != tamlNamedObjectName )
             continue;
 
         // Is the value an integer?

+ 3 - 0
engine/source/persistence/taml/taml.cc

@@ -680,6 +680,9 @@ void Taml::compileStaticFields( TamlWriteNode* pTamlWriteNode )
             // Fetch object field value.
             const char* pFieldValue = pSimObject->getPrefixedDataField( fieldName, indexBuffer );
 
+            if(pField->type == TypeBool)
+               pFieldValue = dAtob(pFieldValue) ? "true" : "false";
+
             U32 nBufferSize = dStrlen( pFieldValue ) + 1;
             FrameTemp<char> valueCopy( nBufferSize );
             dStrcpy( (char *)valueCopy, pFieldValue );

+ 4 - 2
engine/source/platformWin32/winDInputDevice.cc

@@ -1482,5 +1482,7 @@ bool DInputDevice::joystickDetected()
    return( smJoystickCount > 0  );
 }
 
-
-
+U8 DInputDevice::getJoystickCount()
+{  
+   return(smJoystickCount);
+}

+ 1 - 1
engine/source/platformWin32/winDInputDevice.h

@@ -135,7 +135,7 @@ class DInputDevice : public InputDevice
       // Console interface functions:
       const char* getJoystickAxesString();
       static bool joystickDetected();
-      //
+      static U8 getJoystickCount();
 
       bool process();
 };

+ 25 - 14
engine/source/platformWin32/winDirectInput.cc

@@ -49,6 +49,7 @@ DInputManager::DInputManager()
    mDInputInterface  = NULL;
    mKeyboardActive   = mMouseActive = mJoystickActive = false;
    mXInputActive = true;
+   mXInputLib = NULL;
 
    for(S32 i=0; i<4; i++)
 	   mLastDisconnectTime[i] = -1;
@@ -521,11 +522,23 @@ bool DInputManager::isXInputEnabled()
 //------------------------------------------------------------------------------
 bool DInputManager::isXInputConnected(int controllerID)
 {
+    if (controllerID >= XINPUT_MAX_CONTROLLERS || controllerID < 0)
+    {
+        Con::warnf("Invalid device index: %d. Index should be between 0 and %d.", controllerID, XINPUT_MAX_CONTROLLERS - 1);
+        return false;
+    }
+	
 	return( mXInputStateNew[controllerID].bConnected );
 }
 
 int DInputManager::getXInputState(int controllerID, int property, bool current)
 {
+   if (controllerID >= XINPUT_MAX_CONTROLLERS || controllerID < 0)
+   {
+      Con::warnf("Invalid device index: %d. Index should be between 0 and %d.", controllerID, XINPUT_MAX_CONTROLLERS - 1);
+      return -1;
+   }
+	
    int retVal;
 
    switch(property)
@@ -732,7 +745,7 @@ inline void DInputManager::fireXInputButtonEvent( int controllerID, bool forceFi
 	  Con::printf("%s", objName);
 	  */
 
-      buildXInputEvent( controllerID, XI_BUTTON, objInst, action, ( action == XI_MAKE ? 1 : 0 ) );
+      buildXInputEvent( controllerID, XI_BUTTON, objInst, action, ( action == XI_MAKE ? 1.0f : 0.0f ) );
    }
 }
 
@@ -786,19 +799,17 @@ void DInputManager::processXInput( void )
          if( mXInputDeadZoneOn )
          {
             // Zero value if thumbsticks are within the dead zone 
-            if( (mXInputStateNew[i].state.Gamepad.sThumbLX < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbLX > -XINPUT_DEADZONE) && 
-                (mXInputStateNew[i].state.Gamepad.sThumbLY < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbLY > -XINPUT_DEADZONE) ) 
-            {
-               mXInputStateNew[i].state.Gamepad.sThumbLX = 0;
-               mXInputStateNew[i].state.Gamepad.sThumbLY = 0;
-            }
+            if(mXInputStateNew[i].state.Gamepad.sThumbLX < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbLX > -XINPUT_DEADZONE)
+            mXInputStateNew[i].state.Gamepad.sThumbLX = 0;
 
-            if( (mXInputStateNew[i].state.Gamepad.sThumbRX < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbRX > -XINPUT_DEADZONE) && 
-                (mXInputStateNew[i].state.Gamepad.sThumbRY < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbRY > -XINPUT_DEADZONE) ) 
-            {
-               mXInputStateNew[i].state.Gamepad.sThumbRX = 0;
-               mXInputStateNew[i].state.Gamepad.sThumbRY = 0;
-            }
+            if(mXInputStateNew[i].state.Gamepad.sThumbLY < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbLY > -XINPUT_DEADZONE)  
+            mXInputStateNew[i].state.Gamepad.sThumbLY = 0;
+            
+            if(mXInputStateNew[i].state.Gamepad.sThumbRX < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbRX > -XINPUT_DEADZONE)
+            mXInputStateNew[i].state.Gamepad.sThumbRX = 0;
+
+            if(mXInputStateNew[i].state.Gamepad.sThumbRY < XINPUT_DEADZONE && mXInputStateNew[i].state.Gamepad.sThumbRY > -XINPUT_DEADZONE)
+            mXInputStateNew[i].state.Gamepad.sThumbRY = 0;
          }
 
          // this controller was connected or disconnected
@@ -849,4 +860,4 @@ void DInputManager::processXInput( void )
       if ( mXInputStateReset ) 
          mXInputStateReset = false;
    }
-}
+}

BIN
engine/source/platformWin32/winInput_ScriptBinding.h