Browse Source

Fixes #868 by smoothing scroll-wheel scrolling. Makes scroll-wheel speed and scrolling friction into adjustable Properties.
Prevents mouse events from triggering twice on forms that don't consume them, when they come back as simulated touch events.
Some minor cleanup and refactoring (spelling errors, comments, etc.).
Keeping the lua bindings up-to-date.

ablake 12 years ago
parent
commit
a44fa576f9

+ 1 - 0
gameplay/gameplay.vcxproj

@@ -1026,6 +1026,7 @@
       <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DebugInformationFormat>
       </DebugInformationFormat>
+      <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>

+ 1 - 1
gameplay/src/AnimationClip.cpp

@@ -93,7 +93,7 @@ unsigned long AnimationClip::getEndTime() const
     return _endTime;
 }
 
-float AnimationClip::getElaspedTime() const
+float AnimationClip::getElapsedTime() const
 {
     return _elapsedTime;
 }

+ 1 - 1
gameplay/src/AnimationClip.h

@@ -109,7 +109,7 @@ public:
      *
      * @return The elapsed time of the AnimationClip (in milliseconds).
      */
-    float getElaspedTime() const;
+    float getElapsedTime() const;
 
     /**
      * Sets the AnimationClip's repeat count. Overrides repeat duration.

+ 30 - 3
gameplay/src/Container.cpp

@@ -46,7 +46,7 @@ Container::Container()
       _scrollBarsAutoHide(false), _scrollBarOpacity(1.0f), _scrolling(false),
       _scrollingVeryFirstX(0), _scrollingVeryFirstY(0), _scrollingFirstX(0), _scrollingFirstY(0), _scrollingLastX(0), _scrollingLastY(0),
       _scrollingStartTimeX(0), _scrollingStartTimeY(0), _scrollingLastTime(0),
-      _scrollingVelocity(Vector2::zero()), _scrollingFriction(1.0f),
+      _scrollingVelocity(Vector2::zero()), _scrollingFriction(1.0f), _scrollWheelSpeed(400.0f),
       _scrollingRight(false), _scrollingDown(false),
       _scrollingMouseVertically(false), _scrollingMouseHorizontally(false),
       _scrollBarOpacityClip(NULL), _zIndexDefault(0), _focusIndexDefault(0), _focusIndexMax(0),
@@ -504,7 +504,7 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
 
         spriteBatch->start();
 
-        if (_scrollBarBounds.height > 0 &&((_scroll & SCROLL_VERTICAL) == SCROLL_VERTICAL))
+        if (_scrollBarBounds.height > 0 && ((_scroll & SCROLL_VERTICAL) == SCROLL_VERTICAL))
         {
             const Rectangle& topRegion = _scrollBarTopCap->getRegion();
             const Theme::UVs& topUVs = _scrollBarTopCap->getUVs();
@@ -1521,7 +1521,14 @@ bool Container::mouseEventScroll(Mouse::MouseEvent evt, int x, int y, int wheelD
             return touchEventScroll(Touch::TOUCH_RELEASE, x, y, 0);
 
         case Mouse::MOUSE_WHEEL:
-            _scrollPosition.y += (_totalHeight / 10.0f) * wheelDelta;
+            if (_scrollingVelocity.isZero())
+            {
+                _lastFrameTime = Game::getGameTime();
+            }
+            _scrolling = _scrollingMouseVertically = _scrollingMouseHorizontally = false;
+
+            _scrollingVelocity.y += _scrollWheelSpeed * wheelDelta;
+
             if (_scrollBarOpacityClip && _scrollBarOpacityClip->isPlaying())
             {
                 _scrollBarOpacityClip->stop();
@@ -1675,6 +1682,26 @@ Container::Scroll Container::getScroll(const char* scroll)
     return Container::SCROLL_NONE;
 }
 
+float Container::getScrollingFriction() const
+{
+    return _scrollingFriction;
+}
+
+void Container::setScrollingFriction(float friction)
+{
+    _scrollingFriction = friction;
+}
+
+float Container::getScrollWheelSpeed() const
+{
+    return _scrollWheelSpeed;
+}
+
+void Container::setScrollWheelSpeed(float speed)
+{
+    _scrollWheelSpeed = speed;
+}
+
 static bool sortControlsByZOrder(Control* c1, Control* c2)
 {
     if (c1->getZIndex() < c2->getZIndex())

+ 37 - 14
gameplay/src/Container.h

@@ -183,6 +183,27 @@ public:
      */
     bool isScrolling() const;
 
+    /**
+     * Get the friction applied to scrolling velocity for this container.
+     */
+    float getScrollingFriction() const;
+
+    /**
+     * Get the friction applied to scrolling velocity for this container.
+     * A higher value will bring the viewport to a stop sooner.
+     */
+    void setScrollingFriction(float friction);
+
+    /**
+     * Get the speed added to scrolling velocity on a scroll-wheel event.
+     */
+    float getScrollWheelSpeed() const;
+
+    /**
+     * Set the speed added to scrolling velocity on a scroll-wheel event.
+     */
+    void setScrollWheelSpeed(float speed);
+
     /**
      * @see AnimationTarget::getAnimation
      */
@@ -422,7 +443,7 @@ protected:
      */
     Theme::ThemeImage* _scrollBarTopCap;
     /**
-     * Scrollbar vertical image.
+     * Scrollbar vertical track image.
      */
     Theme::ThemeImage* _scrollBarVertical;
     /**
@@ -434,7 +455,7 @@ protected:
      */
     Theme::ThemeImage* _scrollBarLeftCap;
     /**
-     * Scrollbar horizontal image.
+     * Scrollbar horizontal track image.
      */
     Theme::ThemeImage* _scrollBarHorizontal;
     /**
@@ -446,7 +467,7 @@ protected:
      */
     Scroll _scroll;
     /** 
-     * Scroll bar bounds
+     * Scroll bar bounds.
      */
     Rectangle _scrollBarBounds;
     /** 
@@ -454,7 +475,7 @@ protected:
      */
     Vector2 _scrollPosition;
     /** 
-     * Should the scrollbars auto hide. Default is false.
+     * Whether the scrollbars should auto-hide. Default is false.
      */
     bool _scrollBarsAutoHide;
     /** 
@@ -466,11 +487,11 @@ protected:
      */
     bool _scrolling;
     /** 
-     * First scrolling touch x position
+     * First scrolling touch x position.
      */
     int _scrollingVeryFirstX;
     /**
-     * First scrolling touch y position
+     * First scrolling touch y position.
      */
     int _scrollingVeryFirstY;
     /**
@@ -482,33 +503,37 @@ protected:
      */ 
     int _scrollingFirstY;
     /** 
-     * The last y position when scrolling
+     * The last y position when scrolling.
      */ 
     int _scrollingLastX;
     /** 
-     * The last x position when scrolling
+     * The last x position when scrolling.
      */ 
     int _scrollingLastY;
     /** 
-     * Time we started scrolling in the x
+     * Time we started scrolling horizontally.
      */ 
     double _scrollingStartTimeX;
     /** 
-     * Time we started scrolling in the y
+     * Time we started scrolling vertically.
      */ 
     double _scrollingStartTimeY;
     /** 
-     * The last time we were scrolling
+     * The last time we were scrolling.
      */
     double _scrollingLastTime;
     /** 
-     * Speed to continue scrolling at after touch release.
+     * Speed to continue scrolling at after touch release or a scroll-wheel event.
      */ 
     Vector2 _scrollingVelocity;
     /** 
      * Friction dampens velocity.
      */ 
     float _scrollingFriction;
+    /**
+     * Amount to add to scrolling velocity on a scroll-wheel event;
+     */
+    float _scrollWheelSpeed;
     /** 
      * Are we scrolling to the right?
      */ 
@@ -517,12 +542,10 @@ protected:
      * Are we scrolling down?
      */ 
     bool _scrollingDown;
-
     /**
      * Locked to scrolling vertically by grabbing the scrollbar with the mouse.
      */
     bool _scrollingMouseVertically;
-
     /**
      * Locked to scrolling horizontally by grabbing the scrollbar with the mouse.
      */

+ 27 - 30
gameplay/src/Form.cpp

@@ -601,6 +601,16 @@ void Form::updateInternal(float elapsedTime)
     }
 }
 
+static bool shouldPropagateTouchEvent(Control::State state, Touch::TouchEvent evt, const Rectangle& bounds, int x, int y)
+{
+    return (state == Control::FOCUS ||
+            (evt == Touch::TOUCH_PRESS &&
+             x >= bounds.x &&
+             x <= bounds.x + bounds.width &&
+             y >= bounds.y &&
+             y <= bounds.y + bounds.height));
+}
+
 bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
 {
     // Check for a collision with each Form in __forms.
@@ -619,12 +629,7 @@ bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int
                 if (form->projectPoint(x, y, &point))
                 {
                     const Rectangle& bounds = form->getBounds();
-                    if (form->getState() == Control::FOCUS ||
-                        (evt == Touch::TOUCH_PRESS &&
-                         point.x >= bounds.x &&
-                         point.x <= bounds.x + bounds.width &&
-                         point.y >= bounds.y &&
-                         point.y <= bounds.y + bounds.height))
+                    if (shouldPropagateTouchEvent(form->getState(), evt, bounds, point.x, point.y))
                     {
                         if (form->touchEvent(evt, point.x - bounds.x, bounds.height - point.y - bounds.y, contactIndex))
                             return true;
@@ -635,12 +640,7 @@ bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int
             {
                 // Simply compare with the form's bounds.
                 const Rectangle& bounds = form->getBounds();
-                if (form->getState() == Control::FOCUS ||
-                    (evt == Touch::TOUCH_PRESS &&
-                        x >= bounds.x &&
-                        x <= bounds.x + bounds.width &&
-                        y >= bounds.y &&
-                        y <= bounds.y + bounds.height))
+                if (shouldPropagateTouchEvent(form->getState(), evt, bounds, x, y))
                 {
                     // Pass on the event's position relative to the form.
                     if (form->touchEvent(evt, x - bounds.x, y - bounds.y, contactIndex))
@@ -668,6 +668,19 @@ bool Form::keyEventInternal(Keyboard::KeyEvent evt, int key)
     return false;
 }
 
+static bool shouldPropagateMouseEvent(Control::State state, Mouse::MouseEvent evt, const Rectangle& bounds, int x, int y)
+{
+    return (state == Control::FOCUS ||
+            ((evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
+              evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
+              evt == Mouse::MOUSE_PRESS_RIGHT_BUTTON ||
+              evt == Mouse::MOUSE_WHEEL) &&
+                x >= bounds.x &&
+                x <= bounds.x + bounds.width &&
+                y >= bounds.y &&
+                y <= bounds.y + bounds.height));
+}
+
 bool Form::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
 {
     for (size_t i = 0; i < __forms.size(); ++i)
@@ -683,15 +696,7 @@ bool Form::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelt
                 if (form->projectPoint(x, y, &point))
                 {
                     const Rectangle& bounds = form->getBounds();
-                    if (form->getState() == Control::FOCUS ||
-                        ((evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
-                          evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
-                          evt == Mouse::MOUSE_PRESS_RIGHT_BUTTON ||
-                          evt == Mouse::MOUSE_WHEEL) &&
-                         point.x >= bounds.x &&
-                         point.x <= bounds.x + bounds.width &&
-                         point.y >= bounds.y &&
-                         point.y <= bounds.y + bounds.height))
+                    if (shouldPropagateMouseEvent(form->getState(), evt, bounds, point.x, point.y))
                     {
                         if (form->mouseEvent(evt, point.x - bounds.x, bounds.height - point.y - bounds.y, wheelDelta))
                             return true;
@@ -702,15 +707,7 @@ bool Form::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelt
             {
                 // Simply compare with the form's bounds.
                 const Rectangle& bounds = form->getBounds();
-                if (form->getState() == Control::FOCUS ||
-                    ((evt == Mouse::MOUSE_PRESS_LEFT_BUTTON ||
-                      evt == Mouse::MOUSE_PRESS_MIDDLE_BUTTON ||
-                      evt == Mouse::MOUSE_PRESS_RIGHT_BUTTON ||
-                      evt == Mouse::MOUSE_WHEEL) &&
-                        x >= bounds.x &&
-                        x <= bounds.x + bounds.width &&
-                        y >= bounds.y &&
-                        y <= bounds.y + bounds.height))
+                if (shouldPropagateMouseEvent(form->getState(), evt, bounds, x, y))
                 {
                     // Pass on the event's position relative to the form.
                     if (form->mouseEvent(evt, x - bounds.x, y - bounds.y, wheelDelta))

+ 1 - 1
gameplay/src/Form.h

@@ -255,7 +255,7 @@ private:
     float _u2;
     float _v1;
     Matrix _projectionMatrix;           // Orthographic projection matrix to be set on SpriteBatch objects when rendering into the FBO.
-    Matrix _defaultProjectionMatrix;   
+    Matrix _defaultProjectionMatrix;
 };
 
 }

+ 2 - 2
gameplay/src/Platform.cpp

@@ -8,9 +8,9 @@
 namespace gameplay
 {
 
-void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
+void Platform::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex, bool actuallyMouse)
 {
-    if (!Form::touchEventInternal(evt, x, y, contactIndex))
+    if (actuallyMouse || !Form::touchEventInternal(evt, x, y, contactIndex))
     {
         Game::getInstance()->touchEvent(evt, x, y, contactIndex);
         Game::getInstance()->getScriptController()->touchEvent(evt, x, y, contactIndex);

+ 1 - 1
gameplay/src/Platform.h

@@ -277,7 +277,7 @@ public:
      *
      * @script{ignore}
      */
-    static void touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
+    static void touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex, bool actuallyMouse = false);
 
    /**
      * Internal method used only from static code in various platform implementation.

+ 1 - 1
gameplay/src/PlatformBlackBerry.cpp

@@ -1037,7 +1037,7 @@ void mouseOrTouchEvent(Mouse::MouseEvent mouseEvent, Touch::TouchEvent touchEven
 {
     if (!gameplay::Platform::mouseEventInternal(mouseEvent, x, y, 0))
     {
-        Platform::touchEventInternal(touchEvent, x, y, 0);
+        Platform::touchEventInternal(touchEvent, x, y, 0, true);
     }
 }
 

+ 3 - 3
gameplay/src/PlatformLinux.cpp

@@ -1243,7 +1243,7 @@ namespace gameplay
                             }
                             if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
                             {
-                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, evt.xbutton.x, evt.xbutton.y, 0);
+                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, evt.xbutton.x, evt.xbutton.y, 0, true);
                             }
                         }
                         break;
@@ -1267,7 +1267,7 @@ namespace gameplay
                             }
                             if (!gameplay::Platform::mouseEventInternal(mouseEvt, evt.xbutton.x, evt.xbutton.y, 0))
                             {
-                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, evt.xbutton.x, evt.xbutton.y, 0);
+                                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, evt.xbutton.x, evt.xbutton.y, 0, true);
                             }
                         }
                         break;
@@ -1298,7 +1298,7 @@ namespace gameplay
                             {
                                 if (evt.xmotion.state & Button1Mask)
                                 {
-                                    gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0);
+                                    gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0, true);
                                 }
                                 else if (evt.xmotion.state & Button3Mask)
                                 {

+ 3 - 3
gameplay/src/PlatformWindows.cpp

@@ -365,7 +365,7 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         UpdateCapture(wParam);
         if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON, x, y, 0))
         {
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, x, y, 0);
+            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_PRESS, x, y, 0, true);
         }
         return 0;
     }
@@ -376,7 +376,7 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
         if (!gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON, x, y, 0))
         {
-            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, x, y, 0);
+            gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_RELEASE, x, y, 0, true);
         }
         UpdateCapture(wParam);
         return 0;
@@ -429,7 +429,7 @@ LRESULT CALLBACK __WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
             if ((wParam & MK_LBUTTON) == MK_LBUTTON)
             {
                 // Mouse move events should be interpreted as touch move only if left mouse is held and the game did not consume the mouse event.
-                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0);
+                gameplay::Platform::touchEventInternal(gameplay::Touch::TOUCH_MOVE, x, y, 0, true);
                 return 0;
             }
             else if ((wParam & MK_RBUTTON) == MK_RBUTTON)

+ 2 - 0
gameplay/src/Properties.h

@@ -387,6 +387,8 @@ public:
      * @param path The string to copy the path to if the file exists.
      * 
      * @return True if the property exists and the file exists, false otherwise.
+     *
+     * @script{ignore}
      */
     bool getPath(const char* name, std::string* path) const;
 

+ 1 - 1
gameplay/src/ScriptController.cpp

@@ -692,7 +692,7 @@ static const char* lua_dofile_function =
     "    end\n"
     "end\n";
 
-void appendLuaPath(lua_State* state, const char* path)
+static void appendLuaPath(lua_State* state, const char* path)
 {
     lua_getglobal(state, "package");
 

+ 4 - 4
gameplay/src/lua/lua_AnimationClip.cpp

@@ -27,7 +27,7 @@ void luaRegister_AnimationClip()
         {"getAnimation", lua_AnimationClip_getAnimation},
         {"getBlendWeight", lua_AnimationClip_getBlendWeight},
         {"getDuration", lua_AnimationClip_getDuration},
-        {"getElaspedTime", lua_AnimationClip_getElaspedTime},
+        {"getElapsedTime", lua_AnimationClip_getElapsedTime},
         {"getEndTime", lua_AnimationClip_getEndTime},
         {"getId", lua_AnimationClip_getId},
         {"getLoopBlendTime", lua_AnimationClip_getLoopBlendTime},
@@ -508,7 +508,7 @@ int lua_AnimationClip_getDuration(lua_State* state)
     return 0;
 }
 
-int lua_AnimationClip_getElaspedTime(lua_State* state)
+int lua_AnimationClip_getElapsedTime(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -521,7 +521,7 @@ int lua_AnimationClip_getElaspedTime(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 AnimationClip* instance = getInstance(state);
-                float result = instance->getElaspedTime();
+                float result = instance->getElapsedTime();
 
                 // Push the return value onto the stack.
                 lua_pushnumber(state, result);
@@ -529,7 +529,7 @@ int lua_AnimationClip_getElaspedTime(lua_State* state)
                 return 1;
             }
 
-            lua_pushstring(state, "lua_AnimationClip_getElaspedTime - Failed to match the given parameters to a valid function signature.");
+            lua_pushstring(state, "lua_AnimationClip_getElapsedTime - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             break;
         }

+ 1 - 1
gameplay/src/lua/lua_AnimationClip.h

@@ -15,7 +15,7 @@ int lua_AnimationClip_getActiveDuration(lua_State* state);
 int lua_AnimationClip_getAnimation(lua_State* state);
 int lua_AnimationClip_getBlendWeight(lua_State* state);
 int lua_AnimationClip_getDuration(lua_State* state);
-int lua_AnimationClip_getElaspedTime(lua_State* state);
+int lua_AnimationClip_getElapsedTime(lua_State* state);
 int lua_AnimationClip_getEndTime(lua_State* state);
 int lua_AnimationClip_getId(lua_State* state);
 int lua_AnimationClip_getLoopBlendTime(lua_State* state);

+ 146 - 0
gameplay/src/lua/lua_Container.cpp

@@ -76,6 +76,8 @@ void luaRegister_Container()
         {"getPadding", lua_Container_getPadding},
         {"getRefCount", lua_Container_getRefCount},
         {"getScroll", lua_Container_getScroll},
+        {"getScrollWheelSpeed", lua_Container_getScrollWheelSpeed},
+        {"getScrollingFriction", lua_Container_getScrollingFriction},
         {"getSkinColor", lua_Container_getSkinColor},
         {"getSkinRegion", lua_Container_getSkinRegion},
         {"getState", lua_Container_getState},
@@ -120,6 +122,8 @@ void luaRegister_Container()
         {"setPosition", lua_Container_setPosition},
         {"setScroll", lua_Container_setScroll},
         {"setScrollBarsAutoHide", lua_Container_setScrollBarsAutoHide},
+        {"setScrollWheelSpeed", lua_Container_setScrollWheelSpeed},
+        {"setScrollingFriction", lua_Container_setScrollingFriction},
         {"setSize", lua_Container_setSize},
         {"setSkinColor", lua_Container_setSkinColor},
         {"setSkinRegion", lua_Container_setSkinRegion},
@@ -2168,6 +2172,76 @@ int lua_Container_getScroll(lua_State* state)
     return 0;
 }
 
+int lua_Container_getScrollWheelSpeed(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                float result = instance->getScrollWheelSpeed();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_getScrollWheelSpeed - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_getScrollingFriction(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                float result = instance->getScrollingFriction();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_getScrollingFriction - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Container_getSkinColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -4259,6 +4333,78 @@ int lua_Container_setScrollBarsAutoHide(lua_State* state)
     return 0;
 }
 
+int lua_Container_setScrollWheelSpeed(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Container* instance = getInstance(state);
+                instance->setScrollWheelSpeed(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setScrollWheelSpeed - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_setScrollingFriction(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Container* instance = getInstance(state);
+                instance->setScrollingFriction(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setScrollingFriction - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Container_setSize(lua_State* state)
 {
     // Get the number of parameters.

+ 4 - 0
gameplay/src/lua/lua_Container.h

@@ -44,6 +44,8 @@ int lua_Container_getOpacity(lua_State* state);
 int lua_Container_getPadding(lua_State* state);
 int lua_Container_getRefCount(lua_State* state);
 int lua_Container_getScroll(lua_State* state);
+int lua_Container_getScrollWheelSpeed(lua_State* state);
+int lua_Container_getScrollingFriction(lua_State* state);
 int lua_Container_getSkinColor(lua_State* state);
 int lua_Container_getSkinRegion(lua_State* state);
 int lua_Container_getState(lua_State* state);
@@ -88,6 +90,8 @@ int lua_Container_setPadding(lua_State* state);
 int lua_Container_setPosition(lua_State* state);
 int lua_Container_setScroll(lua_State* state);
 int lua_Container_setScrollBarsAutoHide(lua_State* state);
+int lua_Container_setScrollWheelSpeed(lua_State* state);
+int lua_Container_setScrollingFriction(lua_State* state);
 int lua_Container_setSize(lua_State* state);
 int lua_Container_setSkinColor(lua_State* state);
 int lua_Container_setSkinRegion(lua_State* state);

+ 38 - 0
gameplay/src/lua/lua_FileSystem.cpp

@@ -19,6 +19,7 @@ void luaRegister_FileSystem()
     {
         {"createFileFromAsset", lua_FileSystem_static_createFileFromAsset},
         {"fileExists", lua_FileSystem_static_fileExists},
+        {"getDirectoryName", lua_FileSystem_static_getDirectoryName},
         {"getExtension", lua_FileSystem_static_getExtension},
         {"getResourcePath", lua_FileSystem_static_getResourcePath},
         {"isAbsolutePath", lua_FileSystem_static_isAbsolutePath},
@@ -149,6 +150,43 @@ int lua_FileSystem_static_fileExists(lua_State* state)
     return 0;
 }
 
+int lua_FileSystem_static_getDirectoryName(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                std::string result = FileSystem::getDirectoryName(param1);
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, result.c_str());
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FileSystem_static_getDirectoryName - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_FileSystem_static_getExtension(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 0
gameplay/src/lua/lua_FileSystem.h

@@ -8,6 +8,7 @@ namespace gameplay
 int lua_FileSystem__gc(lua_State* state);
 int lua_FileSystem_static_createFileFromAsset(lua_State* state);
 int lua_FileSystem_static_fileExists(lua_State* state);
+int lua_FileSystem_static_getDirectoryName(lua_State* state);
 int lua_FileSystem_static_getExtension(lua_State* state);
 int lua_FileSystem_static_getResourcePath(lua_State* state);
 int lua_FileSystem_static_isAbsolutePath(lua_State* state);

+ 146 - 0
gameplay/src/lua/lua_Form.cpp

@@ -80,6 +80,8 @@ void luaRegister_Form()
         {"getPadding", lua_Form_getPadding},
         {"getRefCount", lua_Form_getRefCount},
         {"getScroll", lua_Form_getScroll},
+        {"getScrollWheelSpeed", lua_Form_getScrollWheelSpeed},
+        {"getScrollingFriction", lua_Form_getScrollingFriction},
         {"getSkinColor", lua_Form_getSkinColor},
         {"getSkinRegion", lua_Form_getSkinRegion},
         {"getState", lua_Form_getState},
@@ -126,6 +128,8 @@ void luaRegister_Form()
         {"setPosition", lua_Form_setPosition},
         {"setScroll", lua_Form_setScroll},
         {"setScrollBarsAutoHide", lua_Form_setScrollBarsAutoHide},
+        {"setScrollWheelSpeed", lua_Form_setScrollWheelSpeed},
+        {"setScrollingFriction", lua_Form_setScrollingFriction},
         {"setSize", lua_Form_setSize},
         {"setSkinColor", lua_Form_setSkinColor},
         {"setSkinRegion", lua_Form_setSkinRegion},
@@ -2208,6 +2212,76 @@ int lua_Form_getScroll(lua_State* state)
     return 0;
 }
 
+int lua_Form_getScrollWheelSpeed(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                float result = instance->getScrollWheelSpeed();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_getScrollWheelSpeed - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_getScrollingFriction(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                float result = instance->getScrollingFriction();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_getScrollingFriction - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Form_getSkinColor(lua_State* state)
 {
     // Get the number of parameters.
@@ -4385,6 +4459,78 @@ int lua_Form_setScrollBarsAutoHide(lua_State* state)
     return 0;
 }
 
+int lua_Form_setScrollWheelSpeed(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Form* instance = getInstance(state);
+                instance->setScrollWheelSpeed(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setScrollWheelSpeed - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_setScrollingFriction(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Form* instance = getInstance(state);
+                instance->setScrollingFriction(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setScrollingFriction - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Form_setSize(lua_State* state)
 {
     // Get the number of parameters.

+ 4 - 0
gameplay/src/lua/lua_Form.h

@@ -45,6 +45,8 @@ int lua_Form_getOpacity(lua_State* state);
 int lua_Form_getPadding(lua_State* state);
 int lua_Form_getRefCount(lua_State* state);
 int lua_Form_getScroll(lua_State* state);
+int lua_Form_getScrollWheelSpeed(lua_State* state);
+int lua_Form_getScrollingFriction(lua_State* state);
 int lua_Form_getSkinColor(lua_State* state);
 int lua_Form_getSkinRegion(lua_State* state);
 int lua_Form_getState(lua_State* state);
@@ -91,6 +93,8 @@ int lua_Form_setPadding(lua_State* state);
 int lua_Form_setPosition(lua_State* state);
 int lua_Form_setScroll(lua_State* state);
 int lua_Form_setScrollBarsAutoHide(lua_State* state);
+int lua_Form_setScrollWheelSpeed(lua_State* state);
+int lua_Form_setScrollingFriction(lua_State* state);
 int lua_Form_setSize(lua_State* state);
 int lua_Form_setSkinColor(lua_State* state);
 int lua_Form_setSkinRegion(lua_State* state);

+ 30 - 1
gameplay/src/lua/lua_Platform.cpp

@@ -17,7 +17,11 @@ void luaRegister_Platform()
         {"enterMessagePump", lua_Platform_enterMessagePump},
         {NULL, NULL}
     };
-    const luaL_Reg* lua_statics = NULL;
+    const luaL_Reg lua_statics[] = 
+    {
+        {"swapBuffers", lua_Platform_static_swapBuffers},
+        {NULL, NULL}
+    };
     std::vector<std::string> scopePath;
 
     gameplay::ScriptUtil::registerClass("Platform", lua_members, NULL, lua_Platform__gc, lua_statics, scopePath);
@@ -103,4 +107,29 @@ int lua_Platform_enterMessagePump(lua_State* state)
     return 0;
 }
 
+int lua_Platform_static_swapBuffers(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 0:
+        {
+            Platform::swapBuffers();
+            
+            return 0;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 }

+ 1 - 0
gameplay/src/lua/lua_Platform.h

@@ -7,6 +7,7 @@ namespace gameplay
 // Lua bindings for Platform.
 int lua_Platform__gc(lua_State* state);
 int lua_Platform_enterMessagePump(lua_State* state);
+int lua_Platform_static_swapBuffers(lua_State* state);
 
 void luaRegister_Platform();