Просмотр исходного кода

Merge branch 'next' of https://github.com/blackberry/GamePlay into next

Steve Grenier 13 лет назад
Родитель
Сommit
71805de82e

+ 11 - 11
gameplay/src/Form.cpp

@@ -233,7 +233,7 @@ void Form::setSize(float width, float height)
         _u2 = width / (float)w;
         _v1 = height / (float)h;
 
-        // Create framebuffer if necessary.
+        // Create framebuffer if necessary. TODO: Use pool to cache.
         if (_frameBuffer)
             SAFE_RELEASE(_frameBuffer)
         
@@ -250,16 +250,17 @@ void Form::setSize(float width, float height)
 
         // Clear the framebuffer black
         Game* game = Game::getInstance();
-        _frameBuffer->bind();
-        Rectangle prevViewport = game->getViewport();
+        FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
+        Rectangle previousViewport = game->getViewport();
+
         game->setViewport(Rectangle(0, 0, width, height));
         _theme->setProjectionMatrix(_projectionMatrix);
         game->clear(Game::CLEAR_COLOR, Vector4::zero(), 1.0, 0);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
-        FrameBuffer::bindDefault();
-        game->setViewport(prevViewport);
+
+        previousFrameBuffer->bind();
+        game->setViewport(previousViewport);
     }
-    
     _bounds.width = width;
     _bounds.height = height;
     _dirty = true;
@@ -535,7 +536,7 @@ void Form::draw()
     if (isDirty())
     {
         GP_ASSERT(_frameBuffer);
-        _frameBuffer->bind();
+        FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
 
         Game* game = Game::getInstance();
         Rectangle prevViewport = game->getViewport();
@@ -543,12 +544,11 @@ void Form::draw()
 
         GP_ASSERT(_theme);
         _theme->setProjectionMatrix(_projectionMatrix);
-        Container::draw(_theme->getSpriteBatch(), Rectangle(0, 0, _bounds.width, _bounds.height),
-                        true/*WAS _skin!=NULL*/, false, _bounds.height);
+        Container::draw(_theme->getSpriteBatch(), Rectangle(0, 0, _bounds.width, _bounds.height),  true/*WAS _skin!=NULL*/, false, _bounds.height);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
 
-        // Rebind the default framebuffer and game viewport.
-        FrameBuffer::bindDefault();
+        // Rebind the previous framebuffer and game viewport.
+        previousFrameBuffer->bind();
 
         // restore the previous game viewport
         game->setViewport(prevViewport);

+ 22 - 24
gameplay/src/FrameBuffer.cpp

@@ -4,17 +4,19 @@
 
 #include "Base.h"
 #include "FrameBuffer.h"
+#include "Game.h"
+
+#define FRAMEBUFFER_ID_DEFAULT "org.gameplay3d.framebuffer.default"
 
 namespace gameplay
 {
-
 static unsigned int __maxRenderTargets = 0;
 static std::vector<FrameBuffer*> __frameBuffers;
-static FrameBufferHandle __defaultHandle = 0;
-static FrameBufferHandle __currentHandle = 0;
+static FrameBuffer* __defaultFrameBuffer = NULL;
+static FrameBuffer* __currentFrameBuffer = NULL;
 
-FrameBuffer::FrameBuffer(const char* id, unsigned int width, unsigned int height) :
-    _id(id ? id : ""), _width(width), _height(height), _handle(0), 
+FrameBuffer::FrameBuffer(const char* id, unsigned int width, unsigned int height, FrameBufferHandle handle) :
+    _id(id ? id : ""), _width(width), _height(height), _handle(handle), 
     _renderTargets(NULL), _depthStencilTarget(NULL)
 {
 }
@@ -57,8 +59,8 @@ void FrameBuffer::initialize()
     // On many platforms this will simply be the zero (0) handle, but this is not always the case.
     GLint fbo;
     glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
-    __defaultHandle = (FrameBufferHandle)fbo;
-    __currentHandle = __defaultHandle;
+    __defaultFrameBuffer = new FrameBuffer(FRAMEBUFFER_ID_DEFAULT, 0, 0, (FrameBufferHandle)fbo);
+    __currentFrameBuffer = __defaultFrameBuffer;
 
     // Query the max supported color attachments. This glGet operation is not supported
     // on GL ES 2.x, so if the define does not exist, assume a value of 1.
@@ -96,8 +98,7 @@ FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned in
     // Create the frame buffer
     GLuint handle = 0;
     GL_ASSERT( glGenFramebuffers(1, &handle) );
-    FrameBuffer* frameBuffer = new FrameBuffer(id, width, height);
-    frameBuffer->_handle = handle;
+    FrameBuffer* frameBuffer = new FrameBuffer(id, width, height, handle);
     
     // Create the render target array for the new frame buffer
     frameBuffer->_renderTargets = new RenderTarget*[__maxRenderTargets];
@@ -157,11 +158,9 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
     GP_ASSERT(index < __maxRenderTargets);
     GP_ASSERT(_renderTargets);
 
+    // No change
     if (_renderTargets[index] == target)
-    {
-        // No change.
         return;
-    }
 
     // Release our reference to the current RenderTarget at this index.
     SAFE_RELEASE(_renderTargets[index]);
@@ -186,8 +185,9 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
         }
 
         // Restore the FBO binding
-        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentHandle) );
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentFrameBuffer->_handle) );
     }
+
 }
 
 RenderTarget* FrameBuffer::getRenderTarget(unsigned int index) const
@@ -234,7 +234,7 @@ void FrameBuffer::setDepthStencilTarget(DepthStencilTarget* target)
         }
 
         // Restore the FBO binding
-        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentHandle) );
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentFrameBuffer->_handle) );
     }
 }
 
@@ -243,21 +243,19 @@ DepthStencilTarget* FrameBuffer::getDepthStencilTarget() const
     return _depthStencilTarget;
 }
 
-void FrameBuffer::bind()
+FrameBuffer* FrameBuffer::bind()
 {
-    // Bind this FrameBuffer for rendering.
     GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
-
-    // Update the current FBO handle
-    __currentHandle = _handle;
+    FrameBuffer* previousFrameBuffer = __currentFrameBuffer;
+    __currentFrameBuffer = this;
+    return previousFrameBuffer;
 }
 
-void FrameBuffer::bindDefault()
+FrameBuffer* FrameBuffer::bindDefault()
 {
-    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __defaultHandle) );
-
-    // Update the current FBO handle
-    __currentHandle = __defaultHandle;
+    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __defaultFrameBuffer->_handle) );
+    __currentFrameBuffer = __defaultFrameBuffer;
+    return __defaultFrameBuffer;
 }
 
 

+ 10 - 5
gameplay/src/FrameBuffer.h

@@ -125,22 +125,27 @@ public:
     DepthStencilTarget* getDepthStencilTarget() const;
  
     /**
-     * Binds this FrameBuffer for off-screen rendering.
+     * Binds this FrameBuffer for off-screen rendering and return you the curently bound one.
+     *
+     * You should keep the return FrameBuffer and store it and call bind() when you rendering is complete.
+     *
+     * @ return The currently bound framebuffer.
      */
-    void bind();
+    FrameBuffer* bind();
 
     /**
      * Binds the default FrameBuffer for rendering to the display.
+     *
+     * @ return The default framebuffer.
      */
-    static void bindDefault(); 
+    static FrameBuffer* bindDefault(); 
      
 private:
 
-
     /**
      * Constructor.
      */
-    FrameBuffer(const char* id, unsigned int width, unsigned int height);
+    FrameBuffer(const char* id, unsigned int width, unsigned int height, FrameBufferHandle handle);
 
     /**
      * Destructor.

+ 1 - 1
gameplay/src/Gamepad.cpp

@@ -9,7 +9,7 @@ namespace gameplay
 static std::vector<Gamepad*> __gamepads;
 
 Gamepad::Gamepad(const char* formPath)
-    : _handle(INT_MAX), _vendorId(0), _productId(0), _buttonCount(0), _joystickCount(0), _triggerCount(0), _form(NULL), _buttons(0)
+    : _handle((GamepadHandle)INT_MAX), _vendorId(0), _productId(0), _buttonCount(0), _joystickCount(0), _triggerCount(0), _form(NULL), _buttons(0)
 {
     GP_ASSERT(formPath);
     _form = Form::create(formPath);

+ 45 - 40
gameplay/src/PhysicsCollisionObject.h

@@ -21,6 +21,8 @@ class PhysicsCollisionObject
 {
     friend class PhysicsController;
     friend class PhysicsConstraint;
+    friend class PhysicsRigidBody;
+    friend class PhysicsGhostObject;
 
 public:
 
@@ -289,6 +291,7 @@ public:
     PhysicsVehicleWheel* asVehicleWheel();
 
 protected:
+
     /**
      * Handles collision event callbacks to Lua script functions.
      */
@@ -311,6 +314,40 @@ protected:
         std::string function;
     };
 
+    /**
+     * Constructor.
+     */
+    PhysicsCollisionObject(Node* node);
+
+    /**
+     * Returns the Bullet Physics collision object.
+     *
+     * @return The Bullet collision object.
+     */
+    virtual btCollisionObject* getCollisionObject() const = 0;
+
+    /**
+     * Pointer to Node contained by this collision object.
+     */ 
+    Node* _node;
+    
+    /**
+     * The PhysicsCollisionObject's collision shape.
+     */
+    PhysicsCollisionShape* _collisionShape;
+
+    /**
+     * If the collision object is enabled or not.
+     */
+    bool _enabled;
+
+    /**
+     * The list of script listeners.
+     */
+    std::vector<ScriptListener*>* _scriptListeners;
+
+private:
+
     /**
      * Interface between GamePlay and Bullet to keep object transforms synchronized properly.
      * 
@@ -321,7 +358,7 @@ protected:
         friend class PhysicsConstraint;
         
     public:
-
+        
         /**
          * Creates a physics motion state for a rigid body.
          * 
@@ -330,76 +367,44 @@ protected:
          * @param centerOfMassOffset The translation offset to the center of mass of the rigid body.
          */
         PhysicsMotionState(Node* node, PhysicsCollisionObject* collisionObject, const Vector3* centerOfMassOffset = NULL);
-
+        
         /**
          * Destructor.
          */
         virtual ~PhysicsMotionState();
-
+        
         /**
          * @see btMotionState::getWorldTransform
          */
         virtual void getWorldTransform(btTransform &transform) const;
-
+        
         /**
          * @see btMotionState::setWorldTransform
          */
         virtual void setWorldTransform(const btTransform &transform);
-
+        
         /**
          * Updates the motion state's world transform from the GamePlay Node object's world transform.
          */
         void updateTransformFromNode() const;
-
+        
         /**
          * Sets the center of mass offset for the associated collision shape.
          */
         void setCenterOfMassOffset(const Vector3& centerOfMassOffset);
-
+        
     private:
-
+        
         Node* _node;
         PhysicsCollisionObject* _collisionObject;
         btTransform _centerOfMassOffset;
         mutable btTransform _worldTransform;
     };
 
-    /**
-     * Constructor.
-     */
-    PhysicsCollisionObject(Node* node);
-
-    /**
-     * Returns the Bullet Physics collision object.
-     *
-     * @return The Bullet collision object.
-     */
-    virtual btCollisionObject* getCollisionObject() const = 0;
-
-    /**
-     * Pointer to Node contained by this collision object.
-     */ 
-    Node* _node;
-
     /** 
      * The PhysicsCollisionObject's motion state.
      */
     PhysicsMotionState* _motionState;
-    
-    /**
-     * The PhysicsCollisionObject's collision shape.
-     */
-    PhysicsCollisionShape* _collisionShape;
-
-    /**
-     * If the collision object is enabled or not.
-     */
-    bool _enabled;
-
-    /**
-     * The list of script listeners.
-     */
-    std::vector<ScriptListener*>* _scriptListeners;
 };
 
 }

+ 0 - 2
gameplay/src/PhysicsGhostObject.h

@@ -8,8 +8,6 @@
 namespace gameplay
 {
 
-class PhysicsMotionState;
-
 /**
  * Defines a class for physics ghost objects.
  */

+ 80 - 60
gameplay/src/PlatformMacOSX.mm

@@ -23,7 +23,7 @@ using namespace std;
 using namespace gameplay;
 
 @class View;
-@class OSXGamepad;
+@class HIDGamepad;
 
 // Default to 720p
 static int __width = 1280;
@@ -58,9 +58,9 @@ static NSMutableArray *__gamepads = NULL;
 static IOHIDManagerRef __hidManagerRef = NULL;
 
 // Gamepad Helper Function
-OSXGamepad *gamepadForLocationID(NSNumber *locationID);
-OSXGamepad *gamepadForLocationIDValue(unsigned int locationIDValue);
-OSXGamepad *gamepadForGameHandle(int gameHandle);
+HIDGamepad *gamepadForLocationID(NSNumber *locationID);
+HIDGamepad *gamepadForLocationIDValue(unsigned int locationIDValue);
+HIDGamepad *gamepadForGameHandle(int gameHandle);
 
 
 // IOHid Helper Functions
@@ -89,7 +89,7 @@ double getMachTimeInMilliseconds()
 }
 
 
-@interface OSXGamepadAxis : NSObject
+@interface HIDGamepadAxis : NSObject
 {
     IOHIDElementRef e;
     CFIndex v;
@@ -109,7 +109,7 @@ double getMachTimeInMilliseconds()
 - (CFIndex)value;
 - (void)setValue:(CFIndex)value;
 @end
-@implementation OSXGamepadAxis
+@implementation HIDGamepadAxis
 + gamepadAxisWithAxisElement:(IOHIDElementRef)element
 {
     return [[[[self class] alloc] initWithAxisElement:element] autorelease];
@@ -170,7 +170,7 @@ double getMachTimeInMilliseconds()
 }
 @end
 
-@interface OSXGamepadButton : NSObject
+@interface HIDGamepadButton : NSObject
 {
     IOHIDElementRef e;
     IOHIDElementRef te;
@@ -194,7 +194,7 @@ double getMachTimeInMilliseconds()
 - (bool)state;
 - (void)setState:(bool)state;
 @end
-@implementation OSXGamepadButton
+@implementation HIDGamepadButton
 + gamepadButtonWithButtonElement:(IOHIDElementRef)element
 {
     return [[[[self class] alloc] initWithButtonElement:element] autorelease];
@@ -263,7 +263,7 @@ double getMachTimeInMilliseconds()
 }
 - (float)calibratedStateValue
 {
-    return (float)triggerValue; // TODO: Need to figure out expected range
+    return (float)triggerValue / 255.0f;
 }
 - (bool)state
 {
@@ -275,7 +275,7 @@ double getMachTimeInMilliseconds()
 }
 @end
 
-@interface OSXGamepad : NSObject
+@interface HIDGamepad : NSObject
 {
     IOHIDDeviceRef hidDeviceRef;
     IOHIDQueueRef queueRef;
@@ -294,7 +294,7 @@ double getMachTimeInMilliseconds()
 - (NSNumber*)locationID;
 
 - (void)initializeGamepadElements;
-- (OSXGamepadButton*)buttonWithCookie:(IOHIDElementCookie)cookie;
+- (HIDGamepadButton*)buttonWithCookie:(IOHIDElementCookie)cookie;
 
 - (bool)startListening;
 - (void)stopListening;
@@ -310,12 +310,12 @@ double getMachTimeInMilliseconds()
 - (NSUInteger)numberOfSticks;
 - (NSUInteger)numberOfButtons;
 - (NSUInteger)numberOfTriggerButtons;
-- (OSXGamepadAxis*)axisAtIndex:(NSUInteger)index;
-- (OSXGamepadButton*)buttonAtIndex:(NSUInteger)index;
-- (OSXGamepadButton*)triggerButtonAtIndex:(NSUInteger)index;
+- (HIDGamepadAxis*)axisAtIndex:(NSUInteger)index;
+- (HIDGamepadButton*)buttonAtIndex:(NSUInteger)index;
+- (HIDGamepadButton*)triggerButtonAtIndex:(NSUInteger)index;
 @end
 
-@implementation OSXGamepad
+@implementation HIDGamepad
 
 @synthesize hidDeviceRef;
 @synthesize queueRef;
@@ -386,7 +386,7 @@ double getMachTimeInMilliseconds()
                 case kHIDUsage_GD_Ry:
                 case kHIDUsage_GD_Rz:
                 {
-                    OSXGamepadAxis *axis = [OSXGamepadAxis gamepadAxisWithAxisElement:hidElement];
+                    HIDGamepadAxis *axis = [HIDGamepadAxis gamepadAxisWithAxisElement:hidElement];
                     [[self axes] addObject:axis];
                 }
                     break;
@@ -400,7 +400,7 @@ double getMachTimeInMilliseconds()
         }
         if(type == kIOHIDElementTypeInput_Button)
         {
-            OSXGamepadButton *button = [OSXGamepadButton gamepadButtonWithButtonElement:hidElement];
+            HIDGamepadButton *button = [HIDGamepadButton gamepadButtonWithButtonElement:hidElement];
             [[self buttons] addObject:button];
         }
     }
@@ -420,32 +420,35 @@ double getMachTimeInMilliseconds()
         {
             if((unsigned long)cookie == 39)
             {
-                OSXGamepadButton *leftTriggerButton = [self buttonWithCookie:(IOHIDElementCookie)9];
+                //[self buttonAtIndex:8]; 
+                HIDGamepadButton *leftTriggerButton = [self buttonWithCookie:(IOHIDElementCookie)9];
                 if(leftTriggerButton)
                 {
                     [leftTriggerButton setTriggerElement:hidElement];
                     [[self triggerButtons] addObject:leftTriggerButton];
-                    [[self buttons] removeObject:leftTriggerButton]; // Defer to gamepad team on this line..  not sure how they intend to tackle
+                    // I would have thought this would work but it seems to mess things up, even after re-mapping the buttons.
+                    //[[self buttons] removeObject:leftTriggerButton];
                 }
             }
             if((unsigned long)cookie == 40)
             {
-                OSXGamepadButton *rightTriggerButton = [self buttonWithCookie:(IOHIDElementCookie)10];
+                //[self buttonAtIndex:9];
+                HIDGamepadButton *rightTriggerButton = [self buttonWithCookie:(IOHIDElementCookie)10];
                 if(rightTriggerButton)
                 {
                     [rightTriggerButton setTriggerElement:hidElement];
                     [[self triggerButtons] addObject:rightTriggerButton];
-                    [[self buttons] removeObject:rightTriggerButton];
+                    //[[self buttons] removeObject:rightTriggerButton];
                 }
             }
         }
     }
-    
 }
 
-- (OSXGamepadButton*)buttonWithCookie:(IOHIDElementCookie)cookie {
-    for(OSXGamepadButton *b in [self buttons]) {
-        if([b cookie] == cookie) return b;
+- (HIDGamepadButton*)buttonWithCookie:(IOHIDElementCookie)cookie {
+    for(HIDGamepadButton *b in [self buttons]) {
+        if([b cookie] == cookie)
+            return b;
     }
     return NULL;
 }
@@ -541,9 +544,9 @@ double getMachTimeInMilliseconds()
     return [[self triggerButtons] count];
 }
 
-- (OSXGamepadButton*)triggerButtonAtIndex:(NSUInteger)index
+- (HIDGamepadButton*)triggerButtonAtIndex:(NSUInteger)index
 {
-    OSXGamepadButton *b = NULL;
+    HIDGamepadButton *b = NULL;
     if(index < [[self triggerButtons] count])
     {
         b = [[self triggerButtons] objectAtIndex:index];
@@ -551,18 +554,18 @@ double getMachTimeInMilliseconds()
     return b;
 }
 
-- (OSXGamepadAxis*)axisAtIndex:(NSUInteger)index
+- (HIDGamepadAxis*)axisAtIndex:(NSUInteger)index
 {
-    OSXGamepadAxis *a = NULL;
+    HIDGamepadAxis *a = NULL;
     if(index < [[self axes] count])
     {
         a = [[self axes] objectAtIndex:index];
     }
     return a;
 }
-- (OSXGamepadButton*)buttonAtIndex:(NSUInteger)index
+- (HIDGamepadButton*)buttonAtIndex:(NSUInteger)index
 {
-    OSXGamepadButton *b = NULL;
+    HIDGamepadButton *b = NULL;
     if(index < [[self buttons] count])
     {
         b = [[self buttons] objectAtIndex:index];
@@ -572,20 +575,21 @@ double getMachTimeInMilliseconds()
 - (NSArray*)watchedElements
 {
     NSMutableArray *r = [NSMutableArray array];
-    for(OSXGamepadButton *b in [self buttons])
+    for(HIDGamepadButton *b in [self buttons])
     {
         [r addObject:(id)[b element]];
     }
-    for(OSXGamepadAxis *a in [self axes])
+    for(HIDGamepadAxis *a in [self axes])
     {
         [r addObject:(id)[a element]];
     }
-    for(OSXGamepadButton* t in [self triggerButtons])
+    for(HIDGamepadButton* t in [self triggerButtons])
     {
-        [r addObject:(id)[t element]];
+        [r addObject:(id)[t triggerElement]];
     }
     return [NSArray arrayWithArray:r];
 }
+
 - (void)hidValueAvailable:(IOHIDValueRef)value
 {
     IOHIDElementRef element = IOHIDValueGetElement(value);
@@ -594,7 +598,7 @@ double getMachTimeInMilliseconds()
     if(IOHIDValueGetLength(value) > 4) return; // saftey precaution for PS3 cotroller
     CFIndex integerValue = IOHIDValueGetIntegerValue(value);
     
-    for(OSXGamepadAxis *a in [self axes])
+    for(HIDGamepadAxis *a in [self axes])
     {
         if([a cookie] == cookie)
         {
@@ -602,7 +606,7 @@ double getMachTimeInMilliseconds()
         }
     }
     
-    for(OSXGamepadButton *b in [self buttons])
+    for(HIDGamepadButton *b in [self buttons])
     {
         if([b cookie] == cookie)
         {
@@ -611,7 +615,7 @@ double getMachTimeInMilliseconds()
         }
     }
     
-    for(OSXGamepadButton *b in [self triggerButtons])
+    for(HIDGamepadButton *b in [self triggerButtons])
     {
         if([b triggerCookie] == cookie)
         {
@@ -667,7 +671,7 @@ double getMachTimeInMilliseconds()
 - (void) detectGamepads: (Game*) game
 {
     // Locate any newly connected devices
-    for(OSXGamepad* gamepad in __gamepads)
+    for(HIDGamepad* gamepad in __gamepads)
     {
         NSNumber* locationID = [gamepad locationID];
         if([__activeGamepads objectForKey:locationID] == NULL)
@@ -676,7 +680,7 @@ double getMachTimeInMilliseconds()
             Platform::gamepadEventConnectedInternal((unsigned int)[locationID intValue],
                                                     [gamepad numberOfButtons],
                                                     [gamepad numberOfSticks],
-                                                    0, //[gamepad numberOfTriggerButtons], PS3 triggers are not working yet
+                                                    [gamepad numberOfTriggerButtons],
                                                     [gamepad vendorID],
                                                     [gamepad productID],
                                                     [[gamepad manufacturerName] cStringUsingEncoding:NSASCIIStringEncoding],
@@ -690,7 +694,7 @@ double getMachTimeInMilliseconds()
     NSMutableArray* deadGamepads = [NSMutableArray array];
     for(NSNumber* locationID in __activeGamepads)
     {
-        OSXGamepad* gamepad = gamepadForLocationID(locationID);
+        HIDGamepad* gamepad = gamepadForLocationID(locationID);
         if(gamepad == NULL)
         {
             NSNumber* gameHandle = [__activeGamepads objectForKey:locationID];
@@ -1810,11 +1814,13 @@ bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
 
 void Platform::pollGamepadState(Gamepad* gamepad)
 {
-    OSXGamepad* gp = gamepadForGameHandle(gamepad->_handle);
+    HIDGamepad* gp = gamepadForGameHandle(gamepad->_handle);
     
     if (gp)
     {
-        static const unsigned int PS3Mapping[17] = {
+        // Haven't figured out how to have the triggers not also show up in the buttons array.
+        // So for now a value of -1 means "Don't map this button."
+        static const int PS3Mapping[17] = {
             Gamepad::BUTTON_MENU1,  // 0x0001
             Gamepad::BUTTON_L3,     // 0x0002
             Gamepad::BUTTON_R3,     // 0x0004
@@ -1823,8 +1829,8 @@ void Platform::pollGamepadState(Gamepad* gamepad)
             Gamepad::BUTTON_RIGHT,  // 0x0020
             Gamepad::BUTTON_DOWN,   // 0x0040
             Gamepad::BUTTON_LEFT,   // 0x0080
-            Gamepad::BUTTON_L2,     // 0x0100
-            Gamepad::BUTTON_R2,     // 0x0200
+            -1,                     // Gamepad::BUTTON_L2,     // 0x0100
+            -1,                     // Gamepad::BUTTON_R2,     // 0x0200
             Gamepad::BUTTON_L1,     // 0x0400
             Gamepad::BUTTON_R1,     // 0x0800
             Gamepad::BUTTON_Y,      // 0x1000
@@ -1834,7 +1840,7 @@ void Platform::pollGamepadState(Gamepad* gamepad)
             Gamepad::BUTTON_MENU3   // 0x10000
         };
         
-        const unsigned int* mapping = NULL;
+        const int* mapping = NULL;
         if (gamepad->_vendorId == SONY_USB_VENDOR_ID &&
             gamepad->_productId == SONY_USB_PS3_PRODUCT_ID)
         {
@@ -1842,21 +1848,35 @@ void Platform::pollGamepadState(Gamepad* gamepad)
         }
         
         gamepad->_buttons = 0;
-        //for (OSXGamepadButton *b in [gp buttons])
+        
         for (int i = 0; i < [gp numberOfButtons]; ++i)
         {
-            OSXGamepadButton* b = [gp buttonAtIndex: i];
+            HIDGamepadButton* b = [gp buttonAtIndex: i];
             if ([b state])
             {
                 // This button is down.
-                gamepad->_buttons |= (1 << mapping[i]);
+                if (mapping)
+                {
+                    if (mapping[i] >= 0)
+                        gamepad->_buttons |= (1 << mapping[i]);
+                }
+                else
+                {
+                    gamepad->_buttons |= (1 << i);
+                }
             }
         }
 
         for (unsigned int i = 0; i < [gp numberOfSticks]; ++i)
         {
-            gamepad->_joysticks[i].x = [[gp axisAtIndex: i*2] calibratedValue];
-            gamepad->_joysticks[i].y = [[gp axisAtIndex: i*2 + 1] calibratedValue];
+            float rawX = [[gp axisAtIndex: i*2] calibratedValue];
+            float rawY = -[[gp axisAtIndex: i*2 + 1] calibratedValue];
+            if (std::fabs(rawX) <= 0.07f)
+                rawX = 0;
+            if (std::fabs(rawY) <= 0.07f)
+                rawY = 0;
+            gamepad->_joysticks[i].x = rawX;
+            gamepad->_joysticks[i].y = rawY;
         }
         
         for (unsigned int i = 0; i < [gp numberOfTriggerButtons]; ++i)
@@ -1868,10 +1888,10 @@ void Platform::pollGamepadState(Gamepad* gamepad)
 
 }
 
-OSXGamepad* gamepadForLocationID(NSNumber* locationID)
+HIDGamepad* gamepadForLocationID(NSNumber* locationID)
 {
-    OSXGamepad* fgamepad = NULL;
-    for(OSXGamepad* gamepad in __gamepads)
+    HIDGamepad* fgamepad = NULL;
+    for(HIDGamepad* gamepad in __gamepads)
     {
         if([[gamepad locationID] isEqual:locationID])
         {
@@ -1882,14 +1902,14 @@ OSXGamepad* gamepadForLocationID(NSNumber* locationID)
     return fgamepad;
 }
 
-OSXGamepad* gamepadForLocationIDValue(unsigned int locationIDValue)
+HIDGamepad* gamepadForLocationIDValue(unsigned int locationIDValue)
 {
     return gamepadForLocationID([NSNumber numberWithUnsignedInt:locationIDValue]);
 }
 
-OSXGamepad* gamepadForGameHandle(int gameHandle)
+HIDGamepad* gamepadForGameHandle(int gameHandle)
 {
-    OSXGamepad* gamepad = NULL;
+    HIDGamepad* gamepad = NULL;
     for(NSNumber* locationID in __activeGamepads)
     {
         NSNumber* handleID = [__activeGamepads objectForKey:locationID];
@@ -1972,7 +1992,7 @@ static void hidDeviceDiscoveredCallback(void* inContext, IOReturn inResult, void
     CFNumberRef locID = (CFNumberRef)IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDLocationIDKey));
     if(locID)
     {
-        OSXGamepad* gamepad = [[OSXGamepad alloc] initWithDevice:inIOHIDDeviceRef];
+        HIDGamepad* gamepad = [[HIDGamepad alloc] initWithDevice:inIOHIDDeviceRef];
         [__gamepads addObject:gamepad];
     }
     
@@ -1986,7 +2006,7 @@ static void hidDeviceRemovalCallback(void* inContext, IOReturn inResult, void* i
     {
         for(int i = 0; i < [__gamepads count]; i++)
         {
-            OSXGamepad* gamepad = [__gamepads objectAtIndex:i];
+            HIDGamepad* gamepad = [__gamepads objectAtIndex:i];
             if([[gamepad locationID] isEqual:locID])
             {
                 removeIndex = i;
@@ -2002,7 +2022,7 @@ static void hidDeviceRemovalCallback(void* inContext, IOReturn inResult, void* i
 
 static void hidDeviceValueAvailableCallback(void* inContext, IOReturn inResult,  void* inSender)
 {
-    OSXGamepad* d = (OSXGamepad*)inContext;
+    HIDGamepad* d = (HIDGamepad*)inContext;
     do
     {
         IOHIDValueRef valueRef = IOHIDQueueCopyNextValueWithTimeout( ( IOHIDQueueRef ) inSender, 0. );

+ 6 - 6
gameplay/src/PlatformWindows.cpp

@@ -982,6 +982,12 @@ int Platform::enterMessagePump()
                     Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, 0, 0, "Microsoft", "XBox360 Controller");
                     __connectedXInput[i] = true;
                 }
+                else if (XInputGetState(i, &__xInputState) != NO_ERROR && __connectedXInput[i])
+                {
+                    // Gamepad was just disconnected.
+                    __connectedXInput[i] = false;
+                    Platform::gamepadEventDisconnectedInternal(i);
+                }
             }
 #endif
 
@@ -1232,12 +1238,6 @@ void Platform::pollGamepadState(Gamepad* gamepad)
             }
         }
     }
-    else
-    {
-        // Gamepad was disconnected.
-        __connectedXInput[gamepad->_handle] = false;
-        Platform::gamepadEventDisconnectedInternal(gamepad->_handle);
-    }
 }
 #else
 void Platform::pollGamepadState(Gamepad* gamepad)

+ 30 - 6
gameplay/src/lua/lua_FrameBuffer.cpp

@@ -129,9 +129,21 @@ int lua_FrameBuffer_bind(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 FrameBuffer* instance = getInstance(state);
-                instance->bind();
-                
-                return 0;
+                void* returnPtr = (void*)instance->bind();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "FrameBuffer");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
             }
 
             lua_pushstring(state, "lua_FrameBuffer_bind - Failed to match the given parameters to a valid function signature.");
@@ -560,9 +572,21 @@ int lua_FrameBuffer_static_bindDefault(lua_State* state)
     {
         case 0:
         {
-            FrameBuffer::bindDefault();
-            
-            return 0;
+            void* returnPtr = (void*)FrameBuffer::bindDefault();
+            if (returnPtr)
+            {
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                object->instance = returnPtr;
+                object->owns = false;
+                luaL_getmetatable(state, "FrameBuffer");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
             break;
         }
         default: