Explorar o código

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

Conflicts:
	gameplay/src/AbsoluteLayout.cpp
	gameplay/src/Container.cpp
	gameplay/src/Control.cpp
	gameplay/src/FlowLayout.cpp
	gameplay/src/Form.cpp
	gameplay/src/Frustum.cpp
	gameplay/src/Label.cpp
	gameplay/src/Layout.cpp
	gameplay/src/TextBox.cpp
	gameplay/src/Theme.cpp
	gameplay/src/VerticalLayout.cpp
Adam Blake %!s(int64=13) %!d(string=hai) anos
pai
achega
35c269ccf2
Modificáronse 91 ficheiros con 1242 adicións e 863 borrados
  1. 3 2
      README.md
  2. 131 80
      gameplay-encoder/src/DAESceneEncoder.cpp
  3. 3 1
      gameplay-encoder/src/DAESceneEncoder.h
  4. 77 14
      gameplay-encoder/src/DAEUtil.cpp
  5. 18 0
      gameplay-encoder/src/DAEUtil.h
  6. 2 2
      gameplay-encoder/src/GPBDecoder.cpp
  7. 1 0
      gameplay-encoder/src/Scene.cpp
  8. 3 9
      gameplay-encoder/src/TTFFontEncoder.cpp
  9. 0 8
      gameplay-encoder/src/TTFFontEncoder.h
  10. 1 1
      gameplay-encoder/src/main.cpp
  11. 2 0
      gameplay-template/gameplay-template.vcxproj
  12. BIN=BIN
      gameplay-template/res/box.gpb
  13. 5 5
      gameplay/src/AbsoluteLayout.cpp
  14. 11 11
      gameplay/src/Animation.cpp
  15. 5 5
      gameplay/src/AnimationClip.cpp
  16. 4 0
      gameplay/src/AnimationController.cpp
  17. 16 16
      gameplay/src/AnimationTarget.cpp
  18. 0 1
      gameplay/src/AnimationTarget.h
  19. 4 4
      gameplay/src/AnimationValue.cpp
  20. 14 14
      gameplay/src/AudioBuffer.cpp
  21. 3 3
      gameplay/src/AudioController.cpp
  22. 10 10
      gameplay/src/AudioSource.cpp
  23. 32 68
      gameplay/src/Base.h
  24. 1 1
      gameplay/src/BoundingBox.cpp
  25. 66 66
      gameplay/src/Bundle.cpp
  26. 7 7
      gameplay/src/Camera.cpp
  27. 6 1
      gameplay/src/CheckBox.cpp
  28. 26 50
      gameplay/src/Container.cpp
  29. 1 1
      gameplay/src/Container.h
  30. 85 20
      gameplay/src/Control.cpp
  31. 5 5
      gameplay/src/Effect.cpp
  32. 6 5
      gameplay/src/FileSystem.cpp
  33. 2 0
      gameplay/src/FlowLayout.cpp
  34. 6 2
      gameplay/src/Font.cpp
  35. 44 18
      gameplay/src/Form.cpp
  36. 1 1
      gameplay/src/FrameBuffer.cpp
  37. 1 3
      gameplay/src/Frustum.cpp
  38. 3 2
      gameplay/src/Game.cpp
  39. 2 2
      gameplay/src/Image.cpp
  40. 4 5
      gameplay/src/Label.cpp
  41. 5 2
      gameplay/src/Layout.cpp
  42. 14 14
      gameplay/src/Light.cpp
  43. 6 6
      gameplay/src/Material.cpp
  44. 10 10
      gameplay/src/MaterialParameter.cpp
  45. 29 29
      gameplay/src/Matrix.cpp
  46. 4 4
      gameplay/src/MeshBatch.cpp
  47. 1 1
      gameplay/src/MeshBatch.inl
  48. 6 6
      gameplay/src/MeshSkin.cpp
  49. 2 2
      gameplay/src/Model.cpp
  50. 19 8
      gameplay/src/Node.cpp
  51. 9 9
      gameplay/src/ParticleEmitter.cpp
  52. 2 2
      gameplay/src/Pass.cpp
  53. 3 3
      gameplay/src/PhysicsCharacter.cpp
  54. 9 9
      gameplay/src/PhysicsCollisionShape.cpp
  55. 1 1
      gameplay/src/PhysicsConstraint.cpp
  56. 10 10
      gameplay/src/PhysicsController.cpp
  57. 3 3
      gameplay/src/PhysicsGhostObject.cpp
  58. 5 5
      gameplay/src/PhysicsRigidBody.cpp
  59. 0 1
      gameplay/src/PlatformMacOSX.mm
  60. 81 63
      gameplay/src/PlatformQNX.cpp
  61. 2 4
      gameplay/src/PlatformWin32.cpp
  62. 37 38
      gameplay/src/PlatformiOS.mm
  63. 24 24
      gameplay/src/Properties.cpp
  64. 3 3
      gameplay/src/Properties.h
  65. 11 11
      gameplay/src/Quaternion.cpp
  66. 1 0
      gameplay/src/Quaternion.h
  67. 7 2
      gameplay/src/RadioButton.cpp
  68. 4 4
      gameplay/src/RenderState.cpp
  69. 4 4
      gameplay/src/Scene.cpp
  70. 44 44
      gameplay/src/SceneLoader.cpp
  71. 9 0
      gameplay/src/ScreenDisplayer.h
  72. 9 2
      gameplay/src/Slider.cpp
  73. 3 3
      gameplay/src/SpriteBatch.cpp
  74. 2 2
      gameplay/src/Technique.cpp
  75. 9 2
      gameplay/src/TextBox.cpp
  76. 9 9
      gameplay/src/Texture.cpp
  77. 68 27
      gameplay/src/Theme.cpp
  78. 17 6
      gameplay/src/ThemeStyle.cpp
  79. 76 12
      gameplay/src/Transform.cpp
  80. 37 0
      gameplay/src/Transform.h
  81. 7 7
      gameplay/src/Vector2.cpp
  82. 8 8
      gameplay/src/Vector3.cpp
  83. 7 7
      gameplay/src/Vector4.cpp
  84. 3 3
      gameplay/src/VertexAttributeBinding.cpp
  85. 1 1
      gameplay/src/VertexFormat.cpp
  86. 5 5
      gameplay/src/VerticalLayout.cpp
  87. 1 0
      gameplay/src/gameplay-main-android.cpp
  88. 1 1
      gameplay/src/gameplay-main-ios.mm
  89. 1 1
      gameplay/src/gameplay-main-macosx.mm
  90. 1 1
      gameplay/src/gameplay-main-qnx.cpp
  91. 1 1
      gameplay/src/gameplay-main-win32.cpp

+ 3 - 2
README.md

@@ -2,8 +2,8 @@
 An open-source, cross-platform 3D native C++ game framework making it easy to learn and write mobile and desktop games. 
 
 ## Supported Mobile Platforms
-- BlackBerry PlayBook 2 (using BlackBerry Native SDK 2)
-- Google Android 2.3 (using Google Android NDK 7)
+- BlackBerry PlayBook 2.0 (using BlackBerry Native SDK 2)
+- Google Android 2.3 (using Google Android NDK r7, SDK API level 9 and up)
 - Apple iOS 5.1 (using Apple XCode 4.3.2)
 
 ## Supported Desktop Platforms
@@ -14,6 +14,7 @@ An open-source, cross-platform 3D native C++ game framework making it easy to le
 - Shadows
 - Lua Script Bindings
 - Terrain
+- AI
 - Editor
 - Performance/Optimizations
 

+ 131 - 80
gameplay-encoder/src/DAESceneEncoder.cpp

@@ -261,13 +261,7 @@ void DAESceneEncoder::write(const std::string& filepath, const EncoderArguments&
     daeElement* scene = NULL;
     if (domScene && domScene->getInstance_visual_scene())
     {
-        scene = domScene->getInstance_visual_scene()->getUrl().getElement();
-        if (scene->getElementType() != COLLADA_TYPE::VISUAL_SCENE)
-        {
-            // This occured once where Maya exported a Node and Scene element with the same ID.
-            fprintf(stderr,"Error: instance_visual_scene does not reference visual_scene for file:%s\n", filepath.c_str());
-            return;
-        }
+        scene = getVisualScene(domScene);
         if (scene)
         {
             if (nodeId == NULL)
@@ -366,89 +360,114 @@ void DAESceneEncoder::loadAnimations(const domCOLLADA* dom)
     }
 }
 
-void DAESceneEncoder::loadAnimation(const domAnimationRef animationRef)
+void DAESceneEncoder::loadAnimation(const domAnimationRef animationRef, const char* altId)
 {
-    // <channel> points to one <sampler>
-    // <sampler> points to multiple <input> elements
-
-    Animation* animation = new Animation();
-    const char* str = animationRef->getId();
-    if (str)
+    // Animations can contain other animations.
+    const domAnimation_Array& animationArray = animationRef->getAnimation_array();
+    unsigned int animationCount = animationArray.getCount();
+    
+    if (animationCount == 1)
     {
-        animation->setId(str);
+        // DAE_FBX nests 1 animation within another animation for some reason.
+        loadAnimation(animationArray.get(0), animationRef->getId());
+    }
+    else if ( animationCount > 1)
+    {
+        loadAnimation(animationArray.get(0));
     }
 
+    // <channel> points to one <sampler>
+    // <sampler> points to multiple <input> elements
+
     // <channel>
     const domChannel_Array& channelArray = animationRef->getChannel_array();
     size_t channelArrayCount = channelArray.getCount();
-    for (size_t i = 0; i < channelArrayCount; ++i)
+    if (channelArrayCount > 0)
     {
-        AnimationChannel* animationChannel = new AnimationChannel();
-
-        const domChannelRef& channelRef = channelArray.get(i);
-
-        // <sampler>
-        const domSamplerRef sampler = getSampler(channelRef);
-        assert(sampler);
+        Animation* animation = new Animation();
+        const char* str = animationRef->getId();
+        if (str)
+        {
+            animation->setId(str);
+        }
+        else if (altId)
+        {
+            animation->setId(altId);
+        }
 
-        // <input>
-        const domInputLocal_Array& inputArray = sampler->getInput_array();
-        size_t inputArrayCount = inputArray.getCount();
-        for (size_t j = 0; j < inputArrayCount; ++j)
+        for (size_t i = 0; i < channelArrayCount; ++i)
         {
-            const domInputLocalRef& inputLocal = inputArray.get(j);
+            AnimationChannel* animationChannel = new AnimationChannel();
 
-            // <source>
-            const domSourceRef source = getSource(inputLocal, animationRef);
+            const domChannelRef& channelRef = channelArray.get(i);
 
-            std::string semantic = inputLocal->getSemantic();
-            if (equals(semantic, "INTERPOLATION"))
-            {
-                // Interpolation source is a list of strings
-                loadInterpolation(source, animationChannel);
-            }
-            else
+            // <sampler>
+            const domSamplerRef sampler = getSampler(channelRef);
+            assert(sampler);
+
+            // <input>
+            const domInputLocal_Array& inputArray = sampler->getInput_array();
+            size_t inputArrayCount = inputArray.getCount();
+            for (size_t j = 0; j < inputArrayCount; ++j)
             {
-                // The other sources are lists of floats.
-                std::vector<float> floats;
-                copyFloats(source->getFloat_array(), &floats);
-                if (equals(semantic, "INPUT"))
-                {
-                    // TODO: Ensure param name is TIME?
-                    for (std::vector<float>::iterator k = floats.begin(); k != floats.end(); ++k)
-                    {
-                        // Convert seconds to milliseconds
-                        *k = *k * 1000.0f;
-                    }
-                    animationChannel->setKeyTimes(floats);
-                }
-                else if (equals(semantic, "OUTPUT"))
+                const domInputLocalRef& inputLocal = inputArray.get(j);
+
+                // <source>
+                const domSourceRef source = getSource(inputLocal, animationRef);
+
+                std::string semantic = inputLocal->getSemantic();
+                if (equals(semantic, "INTERPOLATION"))
                 {
-                    animationChannel->setKeyValues(floats);
+                    // Interpolation source is a list of strings
+                    loadInterpolation(source, animationChannel);
                 }
-                else if (equals(semantic, "IN_TANGENT"))
+                else
                 {
-                    animationChannel->setTangentsIn(floats);
+                    // The other sources are lists of floats.
+                    std::vector<float> floats;
+                    copyFloats(source->getFloat_array(), &floats);
+                    if (equals(semantic, "INPUT"))
+                    {
+                        // TODO: Ensure param name is TIME?
+                        for (std::vector<float>::iterator k = floats.begin(); k != floats.end(); ++k)
+                        {
+                            // Convert seconds to milliseconds
+                            *k = *k * 1000.0f;
+                        }
+                        animationChannel->setKeyTimes(floats);
+                    }
+                    else if (equals(semantic, "OUTPUT"))
+                    {
+                        animationChannel->setKeyValues(floats);
+                    }
+                    else if (equals(semantic, "IN_TANGENT"))
+                    {
+                        animationChannel->setTangentsIn(floats);
+                    }
+                    else if (equals(semantic, "OUT_TANGENT"))
+                    {
+                        animationChannel->setTangentsOut(floats);
+                    }
                 }
-                else if (equals(semantic, "OUT_TANGENT"))
+            }
+            
+            // get target attribute enum value
+            if (loadTarget(channelRef, animationChannel))
+            {
+                if (animationChannel->getKeyTimes().size() > 0)
                 {
-                    animationChannel->setTangentsOut(floats);
+                    animation->add(animationChannel);
                 }
             }
         }
-        // get target attribute enum value
-        if (loadTarget(channelRef, animationChannel))
+        if (animation->getAnimationChannelCount() > 0)
         {
-            animation->add(animationChannel);
+            _gamePlayFile.addAnimation(animation);
+        }
+        else
+        {
+            delete animation;
         }
-    }
-    if (animation->getAnimationChannelCount() > 0)
-    {
-        _gamePlayFile.addAnimation(animation);
-    }
-    else
-    {
-        delete animation;
     }
 }
 
@@ -685,6 +704,11 @@ void DAESceneEncoder::loadScene(const domVisual_scene* visualScene)
 
     const domNode_Array& nodes = visualScene->getNode_array();
     scene->setId(visualScene->getId());
+    if (scene->getId().length() == 0)
+    {
+        scene->setId("__SCENE__");
+    }
+
     size_t childCount = nodes.getCount();
     for (size_t i = 0; i < childCount; ++i)
     {
@@ -989,16 +1013,21 @@ void DAESceneEncoder::loadControllerInstance(const domNode* n, Node* node)
                     domInstance_controller::domSkeleton_Array& skeletons = instanceControllerRef->getSkeleton_array();
                     if (skeletons.getCount() == 0)
                     {
-                        warning("No skeletons found for instance controller: ");
-                        delete model;
-                        continue;
+                        domNode* rootJoint = getRootJointNode(skinElement);
+                        if (rootJoint)
+                        {
+                            loadSkeleton(rootJoint, model->getSkin());
+                            node->setModel(model);
+                        }
+                    }
+                    else
+                    {
+                        // Load the skeleton for this skin
+                        domInstance_controller::domSkeletonRef skeleton = getSkeleton(instanceControllerRef);
+                        assert(skeleton);
+                        loadSkeleton(skeleton, model->getSkin());
+                        node->setModel(model);
                     }
-                    // Load the skeleton for this skin
-                    domInstance_controller::domSkeletonRef skeleton = getSkeleton(instanceControllerRef);
-                    assert(skeleton);
-                    loadSkeleton(skeleton, model->getSkin());
-
-                    node->setModel(model);
                 }
             }
         }
@@ -1182,21 +1211,33 @@ Light* DAESceneEncoder::loadLight(const domLight* lightRef)
             {
                 light->setQuadraticAttenuation((float)quadAtt->getValue());
             }
+
+            // When Maya exports DAE_FBX, the ambient lights are converted into point lights but with not attenuation elements.
+            // If this point light has no attenuation then assume it is ambient.
+            if (!(constAtt.cast() && linearAtt.cast() && quadAtt.cast()))
+            {
+                light->setAmbientLight();
+            }
         }
     }
     _gamePlayFile.addLight(light);
     return light;
 }
 
+
 void DAESceneEncoder::loadSkeleton(domInstance_controller::domSkeleton* skeletonElement, MeshSkin* skin)
 {
     xsAnyURI skeletonUri = skeletonElement->getValue();
     daeString skeletonId = skeletonUri.getID();
     daeSIDResolver resolver(skeletonUri.getElement(), skeletonId);
     domNode* rootNode = daeSafeCast<domNode>(resolver.getElement());
-    
+    loadSkeleton(rootNode, skin);
+}
+
+void DAESceneEncoder::loadSkeleton(domNode* rootNode, MeshSkin* skin)
+{
     // Get the lookup scene id (sid) and joint index.
-    std::string id = std::string(skeletonId);
+    std::string id = std::string(rootNode->getId());
 
     // Has the skeleton (root joint) been loaded yet?
     Node* skeleton = (Node*)_gamePlayFile.getFromRefTable(id);
@@ -1674,6 +1715,7 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
             {
                 maxOffset = offset;
             }
+            int polyIndexInt = (int) polyInts.get(poly + offset);
             unsigned int polyIndex = (unsigned int) polyInts.get(poly + offset);
 
             switch (polygonInputs[k]->type)
@@ -1774,8 +1816,17 @@ Mesh* DAESceneEncoder::loadMesh(const domMesh* meshElement, const std::string& g
                 {
                     // TODO: This assumes (s, t) are first
                     unsigned int stride = (unsigned int)polygonInputs[k]->accessor->getStride();
-                    vertex.texCoord.x = (float)source.get(polyIndex * stride);
-                    vertex.texCoord.y = (float)source.get(polyIndex * stride + 1);
+                    if (polyIndexInt < 0)
+                    {
+                        unsigned int i = (unsigned int)((int)polygonInputs[k]->accessor->getCount()) + polyIndexInt;
+                        vertex.texCoord.x = (float)source.get(i * stride);
+                        vertex.texCoord.y = (float)source.get(i * stride + 1);
+                    }
+                    else
+                    {
+                        vertex.texCoord.x = (float)source.get(polyIndex * stride);
+                        vertex.texCoord.y = (float)source.get(polyIndex * stride + 1);
+                    }
                 }
                 else
                 {

+ 3 - 1
gameplay-encoder/src/DAESceneEncoder.h

@@ -111,14 +111,16 @@ private:
      * Loads a COLLADA animation element.
      * 
      * @param animationRef The animation dom element to load from.
+     * @param altId   The id string to use if the animation doesn't have an id.
      */
-    void loadAnimation(const domAnimationRef animationRef);
+    void loadAnimation(const domAnimationRef animationRef, const char* altId = NULL);
 
     Camera* loadCamera(const domCamera* cameraRef);
     Light* loadLight(const domLight* lightRef);
     Model* loadSkin(const domSkin* skinElement);
     Model* loadGeometry(const domGeometry* geometry, const domBind_materialRef bindMaterial);
 
+    void loadSkeleton(domNode* rootNode, MeshSkin* skin);
     void loadSkeleton(domInstance_controller::domSkeleton* skeletonElement, MeshSkin* skin);
     
     /**

+ 77 - 14
gameplay-encoder/src/DAEUtil.cpp

@@ -13,7 +13,16 @@ namespace gameplay
  * 
  * @return The index in skeletonArray or -1 if not found.
  */
-int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, const domNodeRef& node);
+static int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, const domNodeRef& node);
+
+/**
+ * Gets all of the animation channels that target the given node and appends them to the list.
+ * 
+ * @param animationRef The animation to search in.
+ * @param nodeIdSlash The node's id with a forward slash appended to it.
+ * @param channels The list of channels to append to.
+ */
+static void getAnimationChannels(const domAnimationRef& animationRef, const std::string& nodeIdSlash, std::list<domChannelRef>& channels);
 
 void getAnimationChannels(const domNodeRef& node, std::list<domChannelRef>& channels)
 {
@@ -33,19 +42,7 @@ void getAnimationChannels(const domNodeRef& node, std::list<domChannelRef>& chan
         for (size_t j = 0; j < animationCount; ++j)
         {
             domAnimationRef& animationRef = animationArray.get(j);
-            domChannel_Array& channelArray = animationRef->getChannel_array();
-            size_t channelArrayCount = channelArray.getCount();
-            for (size_t k = 0; k < channelArrayCount; ++k)
-            {
-                domChannelRef& channel = channelArray.get(k);
-                const char* target = channel->getTarget();
-
-                // TODO: Assumes only one target per channel?
-                if (startsWith(target, nodeIdSlash.c_str()))
-                {
-                    channels.push_back(channel);
-                }
-            }
+            getAnimationChannels(animationRef, nodeIdSlash, channels);
         }
     }
 
@@ -262,6 +259,20 @@ const domInstance_controller::domSkeletonRef getSkeleton(const domInstance_contr
     return NULL;
 }
 
+domNode* getRootJointNode(const domSkin* skin)
+{
+    std::vector<std::string> names;
+    getJointNames(skin, names);
+    daeSIDResolver resolver(const_cast<domSkin*>(skin)->getDocument()->getDomRoot(), names[0].c_str());
+    daeElement* element = resolver.getElement();
+    if (element && element->getElementType() == COLLADA_TYPE::NODE)
+    {
+        domNode* node = daeSafeCast<domNode>(resolver.getElement());
+        return node;
+    }
+    return NULL;
+}
+
 bool equalKeyTimes(const domSource* s1, const domSource* s2)
 {
     // TODO: shouldn't assume that the source has a float array.
@@ -355,4 +366,56 @@ int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, con
     return -1;
 }
 
+void getAnimationChannels(const domAnimationRef& animationRef, const std::string& nodeIdSlash, std::list<domChannelRef>& channels)
+{
+    domChannel_Array& channelArray = animationRef->getChannel_array();
+    size_t channelArrayCount = channelArray.getCount();
+    for (size_t k = 0; k < channelArrayCount; ++k)
+    {
+        domChannelRef& channel = channelArray.get(k);
+        const char* target = channel->getTarget();
+
+        // TODO: Assumes only one target per channel?
+        if (startsWith(target, nodeIdSlash.c_str()))
+        {
+            channels.push_back(channel);
+        }
+    }
+
+    // This animation could have child animations.
+    const domAnimation_Array& animationArray = animationRef->getAnimation_array();
+    unsigned int animationCount = animationArray.getCount();
+    for (size_t i = 0; i < animationCount; ++i)
+    {
+        getAnimationChannels(animationArray[i], nodeIdSlash, channels);
+    }
+}
+
+domVisual_scene* getVisualScene(const domCOLLADA::domSceneRef& domScene)
+{
+    daeElement* scene = domScene->getInstance_visual_scene()->getUrl().getElement();
+    if (scene->getElementType() == COLLADA_TYPE::VISUAL_SCENE)
+    {
+        return static_cast<domVisual_scene*>(scene);
+    }
+
+    // DAE_FBX sometimes doesn't export an ID. In that case, see if there is only one visual scene and use that.
+    // Most of the time there is only one visual scene.
+    domCOLLADA* root = (domCOLLADA*)domScene->getDocument()->getDomRoot();
+    domLibrary_visual_scenes_Array& visualSceneLibrary = root->getLibrary_visual_scenes_array();
+    size_t visualSceneLibraryCount = visualSceneLibrary.getCount();
+    for (size_t i = 0; i < visualSceneLibraryCount; ++i)
+    {
+        domLibrary_visual_scenesRef scenesRef = visualSceneLibrary.get(i);
+        domVisual_scene_Array visualScenes = scenesRef->getVisual_scene_array();
+        size_t visualSceneCount = visualScenes.getCount();
+        for (size_t j = 0; j < visualSceneCount; ++j)
+        {
+            domVisual_sceneRef visualScene = visualScenes.get(j);
+            return visualScene.cast();
+        }
+    }
+    return NULL;
+}
+
 }

+ 18 - 0
gameplay-encoder/src/DAEUtil.h

@@ -77,6 +77,15 @@ const domName_arrayRef getSourceNameArray(const domSourceRef& source);
  */
 const domInstance_controller::domSkeletonRef getSkeleton(const domInstance_controllerRef& instanceController);
 
+/**
+ * Returns the root joint node of the given skin.
+ * 
+ * @param skin The COLLADA skin to get the root joint for.
+ * 
+ * @return The COLLADA node or NULL if not found.
+ */
+domNode* getRootJointNode(const domSkin* skin);
+
 /**
  * Returns true if the two given animation channels have equal key time input source.
  * 
@@ -114,6 +123,15 @@ void moveChannelAndSouresToAnimation(domChannelRef& channel, domAnimationRef& an
  */
 bool isEmptyAnimation(domAnimationRef& animation);
 
+/**
+ * Gets the visual scene from the given COLLADA dom scene.
+ * 
+ * @param COLLADA dom scene.
+ * 
+ * @return The visual scene or NULL if not found.
+ */
+domVisual_scene* getVisualScene(const domCOLLADA::domSceneRef& domScene);
+
 }
 
 #endif

+ 2 - 2
gameplay-encoder/src/GPBDecoder.cpp

@@ -62,7 +62,7 @@ void GPBDecoder::readRefs()
 {
     fprintf(_outFile, "<RefTable>\n");
     // read number of refs
-    unsigned int refCount;
+    unsigned int refCount = 0;
     assert(read(&refCount));
     for (size_t i = 0; i < refCount; ++i)
     {
@@ -74,7 +74,7 @@ void GPBDecoder::readRefs()
 void GPBDecoder::readRef()
 {
     std::string xref = readString(_file);
-    unsigned int type, offset;
+    unsigned int type = 0, offset = 0;
     assert(read(&type));
     assert(read(&offset));
     

+ 1 - 0
gameplay-encoder/src/Scene.cpp

@@ -9,6 +9,7 @@ Scene::Scene(void) : _cameraNode(NULL)
     _ambientColor[0] = 0.0f;
     _ambientColor[1] = 0.0f;
     _ambientColor[2] = 0.0f;
+    setId("scene");
 }
 
 Scene::~Scene(void)

+ 3 - 9
gameplay-encoder/src/TTFFontEncoder.cpp

@@ -5,7 +5,7 @@
 namespace gameplay
 {
 
-void drawBitmap(unsigned char* dstBitmap, int x, int y, int dstWidth, unsigned char* srcBitmap, int srcWidth, int srcHeight)
+static void drawBitmap(unsigned char* dstBitmap, int x, int y, int dstWidth, unsigned char* srcBitmap, int srcWidth, int srcHeight)
 {
     // offset dst bitmap by x,y.
     dstBitmap +=  (x + (y * dstWidth));
@@ -18,17 +18,12 @@ void drawBitmap(unsigned char* dstBitmap, int x, int y, int dstWidth, unsigned c
     }
 }
 
-void writeUint(FILE* fp, unsigned int i)
+static void writeUint(FILE* fp, unsigned int i)
 {
     fwrite(&i, sizeof(unsigned int), 1, fp);
 }
 
-void writeFloat(FILE* fp, float f)
-{
-    fwrite(&f, sizeof(float), 1, fp);
-}
-
-void writeString(FILE* fp, const char* str)
+static void writeString(FILE* fp, const char* str)
 {
     unsigned int len = strlen(str);
     fwrite(&len, sizeof(unsigned int), 1, fp);
@@ -40,7 +35,6 @@ void writeString(FILE* fp, const char* str)
 
 int writeFont(const char* filename, unsigned int fontSize, const char* id, bool fontpreview = false)
 {
- 
     Glyph glyphArray[END_INDEX - START_INDEX];
     
     // Initialize freetype library.

+ 0 - 8
gameplay-encoder/src/TTFFontEncoder.h

@@ -18,14 +18,6 @@ public:
     float uvCoords[4];
 };
 
-void drawBitmap(unsigned char* dstBitmap, int x, int y, int dstWidth, unsigned char* srcBitmap, int srcWidth, int srcHeight);
-
-void writeUint(FILE* fp, unsigned int i);
-
-void writeFloat(FILE* fp, float f);
-
-void writeString(FILE* fp, const char* str);
-
 int writeFont(const char* filename, unsigned int fontSize, const char* id, bool fontpreview);
 
 }

+ 1 - 1
gameplay-encoder/src/main.cpp

@@ -7,7 +7,7 @@
 
 using namespace gameplay;
 
-std::string getFileName(const std::string& filepath)
+static std::string getFileName(const std::string& filepath)
 {
     size_t index1 = filepath.find_last_of('\\');
     size_t index2 = filepath.find_last_of('/');

+ 2 - 0
gameplay-template/gameplay-template.vcxproj

@@ -76,6 +76,7 @@
       <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>GAMEPLAY_PATH/external-deps/bullet/include;GAMEPLAY_PATH/gameplay/src;GAMEPLAY_PATH/external-deps/openal/include/AL;GAMEPLAY_PATH/external-deps/oggvorbis/include;GAMEPLAY_PATH/external-deps/libpng/include;GAMEPLAY_PATH/external-deps/zlib/include;GAMEPLAY_PATH/external-deps/glew/include</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
@@ -107,6 +108,7 @@
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <ShowIncludes>false</ShowIncludes>
       <PreprocessToFile>false</PreprocessToFile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>

BIN=BIN
gameplay-template/res/box.gpb


+ 5 - 5
gameplay/src/AbsoluteLayout.cpp

@@ -42,18 +42,18 @@ Layout::Type AbsoluteLayout::getType()
 
 void AbsoluteLayout::update(const Container* container)
 {
+    GP_ASSERT(container);
+
     // An AbsoluteLayout does nothing to modify the layout of Controls.
     std::vector<Control*> controls = container->getControls();
     unsigned int controlsCount = controls.size();
     for (unsigned int i = 0; i < controlsCount; i++)
     {
         Control* control = controls[i];
+        GP_ASSERT(control);
 
-        if (control->isDirty() || control->isContainer())
-        {
-            align(control, container);
-            control->update(container->getClip(), Vector2::zero());
-        }
+        align(control, container);
+        control->update(container->getClip(), Vector2::zero());
     }
 }
 

+ 11 - 11
gameplay/src/Animation.cpp

@@ -21,7 +21,7 @@ Animation::Animation(const char* id, AnimationTarget* target, int propertyId, un
     createChannel(target, propertyId, keyCount, keyTimes, keyValues, type);
     // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
     release();
-    assert(getRefCount() == 1);
+    GP_ASSERT(getRefCount() == 1);
 }
 
 Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
@@ -30,7 +30,7 @@ Animation::Animation(const char* id, AnimationTarget* target, int propertyId, un
     createChannel(target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
     // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
     release();
-    assert(getRefCount() == 1);
+    GP_ASSERT(getRefCount() == 1);
 }
 
 Animation::Animation(const char* id)
@@ -70,7 +70,7 @@ Animation::Channel::Channel(Animation* animation, AnimationTarget* target, int p
     : _animation(animation), _target(target), _propertyId(propertyId), _curve(curve), _duration(duration)
 {
     // get property component count, and ensure the property exists on the AnimationTarget by getting the property component count.
-    assert(_target->getAnimationPropertyComponentCount(propertyId));
+    GP_ASSERT(_target->getAnimationPropertyComponentCount(propertyId));
     _curve->addRef();
     _target->addChannel(this);
     _animation->addRef();
@@ -107,16 +107,16 @@ unsigned long Animation::getDuration() const
 
 void Animation::createClips(const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
 
     Properties* properties = Properties::create(url);
-    assert(properties);
+    GP_ASSERT(properties);
 
     Properties* pAnimation = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
-    assert(pAnimation);
+    GP_ASSERT(pAnimation);
     
     int frameCount = pAnimation->getInt("frameCount");
-    assert(frameCount > 0);
+    GP_ASSERT(frameCount > 0);
 
     createClips(pAnimation, (unsigned int)frameCount);
 
@@ -229,7 +229,7 @@ void Animation::createDefaultClip()
 
 void Animation::createClips(Properties* animationProperties, unsigned int frameCount)
 {
-    assert(animationProperties);
+    GP_ASSERT(animationProperties);
     
     Properties* pClip = animationProperties->getNextNamespace();
     
@@ -296,7 +296,7 @@ AnimationClip* Animation::findClip(const char* id) const
 Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, unsigned int type)
 {
     unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
-    assert(propertyComponentCount > 0);
+    GP_ASSERT(propertyComponentCount > 0);
 
     Curve* curve = Curve::create(keyCount, propertyComponentCount);
     if (target->_targetType == AnimationTarget::TRANSFORM)
@@ -333,7 +333,7 @@ Animation::Channel* Animation::createChannel(AnimationTarget* target, int proper
 Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
 {
     unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
-    assert(propertyComponentCount > 0);
+    GP_ASSERT(propertyComponentCount > 0);
 
     Curve* curve = Curve::create(keyCount, propertyComponentCount);
     if (target->_targetType == AnimationTarget::TRANSFORM)
@@ -417,7 +417,7 @@ Animation* Animation::clone(Channel* channel, AnimationTarget* target)
     animation->addChannel(channelCopy);
     // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
     animation->release();
-    assert(animation->getRefCount() == 1);
+    GP_ASSERT(animation->getRefCount() == 1);
     return animation;
 }
 

+ 5 - 5
gameplay/src/AnimationClip.cpp

@@ -14,7 +14,7 @@ AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long
       _elapsedTime(0), _crossFadeToClip(NULL), _crossFadeOutElapsed(0), _crossFadeOutDuration(0), _blendWeight(1.0f), 
       _beginListeners(NULL), _endListeners(NULL), _listeners(NULL), _listenerItr(NULL)
 {
-    assert(0 <= startTime && startTime <= animation->_duration && 0 <= endTime && endTime <= animation->_duration);
+    GP_ASSERT(0 <= startTime && startTime <= animation->_duration && 0 <= endTime && endTime <= animation->_duration);
     
     unsigned int channelCount = _animation->_channels.size();    
     for (unsigned int i = 0; i < channelCount; i++)
@@ -88,7 +88,7 @@ unsigned long AnimationClip::getElaspedTime() const
 
 void AnimationClip::setRepeatCount(float repeatCount)
 {
-    assert(repeatCount == REPEAT_INDEFINITE || repeatCount > 0.0f);
+    GP_ASSERT(repeatCount == REPEAT_INDEFINITE || repeatCount > 0.0f);
 
     _repeatCount = repeatCount;
 
@@ -209,7 +209,7 @@ void AnimationClip::pause()
 
 void AnimationClip::crossFade(AnimationClip* clip, unsigned long duration)
 {
-    assert(clip);
+    GP_ASSERT(clip);
 
     // Check if the given clip is fading into this clip.
     // We should reset the clip from fading out, and this one from fading in 
@@ -250,8 +250,8 @@ void AnimationClip::crossFade(AnimationClip* clip, unsigned long duration)
 
 void AnimationClip::addListener(AnimationClip::Listener* listener, unsigned long eventTime)
 {
-    assert(listener);
-    assert(eventTime < _activeDuration);
+    GP_ASSERT(listener);
+    GP_ASSERT(eventTime < _activeDuration);
 
     ListenerEvent* listenerEvent = new ListenerEvent(listener, eventTime);
 

+ 4 - 0
gameplay/src/AnimationController.cpp

@@ -96,6 +96,8 @@ void AnimationController::update(long elapsedTime)
     if (_state != RUNNING)
         return;
 
+    Transform::suspendTransformChanged();
+
     // Loop through running clips and call update() on them.
     std::list<AnimationClip*>::iterator clipIter = _runningClips.begin();
     while (clipIter != _runningClips.end())
@@ -120,6 +122,8 @@ void AnimationController::update(long elapsedTime)
         }
     }
 
+    Transform::resumeTransformChanged();
+
     if (_runningClips.empty())
         _state = IDLE;
 }

+ 16 - 16
gameplay/src/AnimationTarget.cpp

@@ -31,8 +31,8 @@ AnimationTarget::~AnimationTarget()
 
 Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, Curve::InterpolationType type)
 {
-    assert(type != Curve::BEZIER && type != Curve::HERMITE);
-    assert(keyCount >= 1 && keyTimes && keyValues);
+    GP_ASSERT(type != Curve::BEZIER && type != Curve::HERMITE);
+    GP_ASSERT(keyCount >= 1 && keyTimes && keyValues);
 
     Animation* animation = new Animation(id, this, propertyId, keyCount, keyTimes, keyValues, type);
 
@@ -41,7 +41,7 @@ Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsi
 
 Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, Curve::InterpolationType type)
 {
-    assert(keyCount >= 1 && keyTimes && keyValues && keyInValue && keyOutValue);
+    GP_ASSERT(keyCount >= 1 && keyTimes && keyValues && keyInValue && keyOutValue);
     Animation* animation = new Animation(id, this, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
 
     return animation;
@@ -49,10 +49,10 @@ Animation* AnimationTarget::createAnimation(const char* id, int propertyId, unsi
 
 Animation* AnimationTarget::createAnimation(const char* id, const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
     
     Properties* p = Properties::create(url);
-    assert(p);
+    GP_ASSERT(p);
 
     Animation* animation = createAnimation(id, (strlen(p->getNamespace()) > 0) ? p : p->getNextNamespace());
 
@@ -103,27 +103,27 @@ Animation* AnimationTarget::createAnimationFromBy(const char* id, int propertyId
 
 Animation* AnimationTarget::createAnimation(const char* id, Properties* animationProperties)
 {
-    assert(animationProperties);
-    assert(std::strcmp(animationProperties->getNamespace(), "animation") == 0);
+    GP_ASSERT(animationProperties);
+    GP_ASSERT(std::strcmp(animationProperties->getNamespace(), "animation") == 0);
     
     const char* propertyIdStr = animationProperties->getString("property");
-    assert(propertyIdStr);
+    GP_ASSERT(propertyIdStr);
     
     // Get animation target property id
     int propertyId = AnimationTarget::getPropertyId(_targetType, propertyIdStr);
-    assert(propertyId != -1);
+    GP_ASSERT(propertyId != -1);
     
     unsigned int keyCount = animationProperties->getInt("keyCount");
-    assert(keyCount > 0);
+    GP_ASSERT(keyCount > 0);
 
     const char* keyTimesStr = animationProperties->getString("keyTimes");
-    assert(keyTimesStr);
+    GP_ASSERT(keyTimesStr);
     
     const char* keyValuesStr = animationProperties->getString("keyValues");
-    assert(keyValuesStr);
+    GP_ASSERT(keyValuesStr);
     
     const char* curveStr = animationProperties->getString("curve");
-    assert(curveStr);
+    GP_ASSERT(curveStr);
     
     char delimeter = ' ';
     unsigned int startOffset = 0;
@@ -148,7 +148,7 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
     endOffset = (unsigned int)std::string::npos;
     
     int componentCount = getAnimationPropertyComponentCount(propertyId);
-    assert(componentCount > 0);
+    GP_ASSERT(componentCount > 0);
     
     unsigned int components = keyCount * componentCount;
     
@@ -232,7 +232,7 @@ Animation* AnimationTarget::createAnimation(const char* id, Properties* animatio
     if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0)
     {
         int frameCount = animationProperties->getInt("frameCount");
-        assert(frameCount > 0);
+        GP_ASSERT(frameCount > 0);
         animation->createClips(animationProperties, (unsigned int) frameCount);
     }
 
@@ -395,7 +395,7 @@ void AnimationTarget::cloneInto(AnimationTarget* target, NodeCloneContext &conte
         for (std::vector<Animation::Channel*>::const_iterator it = _animationChannels->begin(); it != _animationChannels->end(); ++it)
         {
             Animation::Channel* channel = *it;
-            assert(channel->_animation);
+            GP_ASSERT(channel->_animation);
 
             Animation* animation = context.findClonedAnimation(channel->_animation);
             if (animation != NULL)

+ 0 - 1
gameplay/src/AnimationTarget.h

@@ -19,7 +19,6 @@ class AnimationTarget
 {
     friend class Animation;
     friend class AnimationClip;
-    friend class AnimationController;
 
 public:
 

+ 4 - 4
gameplay/src/AnimationValue.cpp

@@ -17,28 +17,28 @@ AnimationValue::~AnimationValue()
 
 float AnimationValue::getFloat(unsigned int index) const
 {
-    assert(index < _componentCount);
+    GP_ASSERT(index < _componentCount);
 
     return _value[index];
 }
 
 void AnimationValue::setFloat(unsigned int index, float value)
 {
-    assert(index < _componentCount);
+    GP_ASSERT(index < _componentCount);
 
     _value[index] = value;
 }
 
 void AnimationValue::getFloat(float* value, unsigned int offset, unsigned int length) const
 {
-    assert(value && offset < _componentCount && (offset + length) <= _componentCount);
+    GP_ASSERT(value && offset < _componentCount && (offset + length) <= _componentCount);
 
     memcpy(value + offset, _value, length * sizeof(float));
 }
 
 void AnimationValue::setFloat(float* value, unsigned int offset, unsigned int length)
 {
-    assert(value && offset < _componentCount && (offset + length) <= _componentCount);
+    GP_ASSERT(value && offset < _componentCount && (offset + length) <= _componentCount);
 
     memcpy(_value, value + offset, length * sizeof(float));
 }

+ 14 - 14
gameplay/src/AudioBuffer.cpp

@@ -35,7 +35,7 @@ AudioBuffer::~AudioBuffer()
 
 AudioBuffer* AudioBuffer::create(const char* path)
 {
-    assert(path);
+    GP_ASSERT(path);
 
     // Search the cache for a stream from this file.
     unsigned int bufferCount = (unsigned int)__buffers.size();
@@ -58,7 +58,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     al_error = alGetError();
     if (al_error != AL_NO_ERROR)
     {
-        LOG_ERROR_VARG("AudioBuffer alGenBuffers AL error: %d", al_error);
+        GP_ERROR("AudioBuffer alGenBuffers AL error: %d", al_error);
         alDeleteBuffers(1, &alBuffer);
         return NULL;
     }
@@ -67,7 +67,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     FILE* file = FileSystem::openFile(path, "rb");
     if (!file)
     {
-        LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
+        GP_ERROR("Invalid audio buffer file: %s", path);
         goto cleanup;
     }
     
@@ -75,7 +75,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     char header[12];
     if (fread(header, 1, 12, file) != 12)
     {
-        LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
+        GP_ERROR("Invalid audio buffer file: %s", path);
         goto cleanup;
     }
     
@@ -84,7 +84,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     {
         if (!AudioBuffer::loadWav(file, alBuffer))
         {
-            LOG_ERROR_VARG("Invalid wave file: %s", path);
+            GP_ERROR("Invalid wave file: %s", path);
             goto cleanup;
         }
     }
@@ -92,13 +92,13 @@ AudioBuffer* AudioBuffer::create(const char* path)
     {
         if (!AudioBuffer::loadOgg(file, alBuffer))
         {
-            LOG_ERROR_VARG("Invalid ogg file: %s", path);
+            GP_ERROR("Invalid ogg file: %s", path);
             goto cleanup;
         }
     }
     else
     {
-        LOG_ERROR_VARG("Unsupported audio file: %s", path);
+        GP_ERROR("Unsupported audio file: %s", path);
     }
     
     fclose(file);
@@ -136,7 +136,7 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
     // Check for a valid pcm format.
     if (fread(stream, 1, 2, file) != 2 || stream[1] != 0 || stream[0] != 1)
     {
-        LOG_ERROR("Unsupported audio file, not PCM format.");
+        GP_ERROR("Unsupported audio file, not PCM format.");
         return false;
     }
     
@@ -188,7 +188,7 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
     }
     else
     {
-        LOG_ERROR_VARG("Incompatible format: (%d, %d)", channels, bits);
+        GP_ERROR("Incompatible format: (%d, %d)", channels, bits);
         return false;
     }
     
@@ -227,7 +227,7 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
     // should now be the data section which holds the decoded sample data
     if (memcmp(stream, "data", 4) != 0)
     {
-        LOG_ERROR("WAV file has no data.");
+        GP_ERROR("WAV file has no data.");
         return false;
     }
 
@@ -238,7 +238,7 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
     char* data = new char[dataSize];
     if (fread(data, sizeof(char), dataSize, file) != dataSize)
     {
-        LOG_ERROR("WAV file missing data.");
+        GP_ERROR("WAV file missing data.");
         SAFE_DELETE_ARRAY(data);
         return false;
     }
@@ -262,7 +262,7 @@ bool AudioBuffer::loadOgg(FILE* file, ALuint buffer)
     if ((result = ov_open(file, &ogg_file, NULL, 0)) < 0)
     {
         fclose(file);
-        LOG_ERROR("Could not open Ogg stream.");
+        GP_ERROR("Could not open Ogg stream.");
         return false;
     }
 
@@ -287,7 +287,7 @@ bool AudioBuffer::loadOgg(FILE* file, ALuint buffer)
         else if (result < 0)
         {
             SAFE_DELETE_ARRAY(data);
-            LOG_ERROR("OGG file missing data.");
+            GP_ERROR("OGG file missing data.");
             return false;
         }
         else
@@ -299,7 +299,7 @@ bool AudioBuffer::loadOgg(FILE* file, ALuint buffer)
     if (size == 0)
     {
         SAFE_DELETE_ARRAY(data);
-        LOG_ERROR("Unable to read OGG data.");
+        GP_ERROR("Unable to read OGG data.");
         return false;
     }
 

+ 3 - 3
gameplay/src/AudioController.cpp

@@ -21,7 +21,7 @@ void AudioController::initialize()
     _alcDevice = alcOpenDevice (NULL);
     if (!_alcDevice)
     {
-        LOG_ERROR("AudioController::initialize() error. Unable to open OpenAL device.\n");
+        GP_ERROR("Unable to open OpenAL device.\n");
         return;  
     }
         
@@ -30,7 +30,7 @@ void AudioController::initialize()
     if (!_alcContext || alcErr != ALC_NO_ERROR)
     {
         alcCloseDevice (_alcDevice);
-        LOG_ERROR_VARG("AudioController::initialize() error. Unable to create OpenAL context. Error: %d\n", alcErr);
+        GP_ERROR("Unable to create OpenAL context. Error: %d\n", alcErr);
         return;
     }
     
@@ -38,7 +38,7 @@ void AudioController::initialize()
     alcErr = alcGetError(_alcDevice);
     if (alcErr != ALC_NO_ERROR)
     {
-        LOG_ERROR_VARG("AudioController::initialize() error. Unable to make OpenAL context current. Error: %d\n", alcErr);
+        GP_ERROR("Unable to make OpenAL context current. Error: %d\n", alcErr);
     }
 }
 

+ 10 - 10
gameplay/src/AudioSource.cpp

@@ -31,14 +31,14 @@ AudioSource::~AudioSource()
 
 AudioSource* AudioSource::create(const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
 
     // Load from a .audio file.
     std::string pathStr = url;
     if (pathStr.find(".audio") != pathStr.npos)
     {
         Properties* properties = Properties::create(url);
-        assert(properties);
+        GP_ASSERT(properties);
         if (properties == NULL)
         {
             return NULL;
@@ -61,7 +61,7 @@ AudioSource* AudioSource::create(const char* url)
     if (alGetError() != AL_NO_ERROR)
     {
         SAFE_RELEASE(buffer);
-        LOG_ERROR("AudioSource::createAudioSource - Error generating audio source.");
+        GP_ERROR("AudioSource::createAudioSource - Error generating audio source.");
         return NULL;
     }
     
@@ -71,17 +71,17 @@ AudioSource* AudioSource::create(const char* url)
 AudioSource* AudioSource::create(Properties* properties)
 {
     // Check if the properties is valid and has a valid namespace.
-    assert(properties);
+    GP_ASSERT(properties);
     if (!properties || !(strcmp(properties->getNamespace(), "audio") == 0))
     {
-        WARN("Failed to load audio source from properties object: must be non-null object and have namespace equal to \'audio\'.");
+        GP_WARN("Failed to load audio source from properties object: must be non-null object and have namespace equal to \'audio\'.");
         return NULL;
     }
 
     const char* path = properties->getString("path");
     if (path == NULL)
     {
-        WARN("Audio file failed to load; the file path was not specified.");
+        GP_WARN("Audio file failed to load; the file path was not specified.");
         return NULL;
     }
 
@@ -89,7 +89,7 @@ AudioSource* AudioSource::create(Properties* properties)
     AudioSource* audio = AudioSource::create(path);
     if (audio == NULL)
     {
-        WARN_VARG("Audio file '%s' failed to load properly.", path);
+        GP_WARN("Audio file '%s' failed to load properly.", path);
         return NULL;
     }
 
@@ -156,7 +156,7 @@ void AudioSource::pause()
         std::set<AudioSource*>::iterator iter = audioController->_playingSources.find(this);
         if (iter != audioController->_playingSources.end())
         {
-            WARN("\n\nRemoving an audio source from the list of playing sources...\n\n\n");
+            GP_WARN("\n\nRemoving an audio source from the list of playing sources...\n\n\n");
             audioController->_playingSources.erase(iter);
         }
     }
@@ -199,7 +199,7 @@ void AudioSource::setLooped(bool looped)
     ALCenum error = alGetError();
     if (error != AL_NO_ERROR)
     {
-        LOG_ERROR_VARG("AudioSource::setLooped Error: %d", error);
+        GP_ERROR("AudioSource::setLooped Error: %d", error);
     }
     _looped = looped;
 }
@@ -279,7 +279,7 @@ AudioSource* AudioSource::clone(NodeCloneContext &context) const
     alGenSources(1, &alSource);
     if (alGetError() != AL_NO_ERROR)
     {
-        LOG_ERROR("AudioSource::createAudioSource - Error generating audio source.");
+        GP_ERROR("AudioSource::createAudioSource - Error generating audio source.");
         return NULL;
     }
     AudioSource* audioClone = new AudioSource(_buffer, alSource);

+ 32 - 68
gameplay/src/Base.h

@@ -51,50 +51,42 @@ namespace gameplay
 extern void printError(const char* format, ...);
 }
 
-#ifdef __ANDROID__
-#include <android/log.h>
-#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
-
-// System Errors
-#define LOG_ERROR(x) \
-    { \
-        LOGI(x); \
-        assert(#x == 0); \
-    }
-#define LOG_ERROR_VARG(x, ...) \
-    { \
-        LOGI(x, __VA_ARGS__); \
-        assert(#x == 0); \
-    }
-
-// Warning macro
-#ifdef WARN
-#undef WARN
+// Assert macros.
+#ifdef _DEBUG
+#ifdef WIN32
+#define GP_FORCE_ASSERTION_FAILURE do { __debugbreak(); } while (0)
+#else
+#define GP_FORCE_ASSERTION_FAILURE do { assert(0); } while (0)
 #endif
-#define WARN(x) LOGI(x)
-#define WARN_VARG(x, ...) LOGI(x, __VA_ARGS__)
 
+#define GP_ASSERT(expression) do { \
+    if (!(expression)) \
+    { \
+        printError("%s -- Assertion \'" #expression "\' failed.\n", __FUNCTION__); \
+        GP_FORCE_ASSERTION_FAILURE; \
+    } } while (0)
 #else
+#define GP_FORCE_ASSERTION_FAILURE do { (void)sizeof(int); } while (0)
+#define GP_ASSERT(expression) do { (void)sizeof(expression); } while (0)
+#endif
 
-// System Errors
-#define LOG_ERROR(x) \
+// Error macro.
+#define GP_ERROR(...) do \
     { \
-        printError(x); \
-        assert(#x == 0); \
-    }
-#define LOG_ERROR_VARG(x, ...) \
+        printError("%s -- ", __FUNCTION__); \
+        printError(__VA_ARGS__); \
+        printError("\n"); \
+        GP_FORCE_ASSERTION_FAILURE; \
+        std::exit(-1); \
+    } while (0)
+
+// Warning macro.
+#define GP_WARN(...) do \
     { \
-        printError(x, __VA_ARGS__); \
-        assert(#x == 0); \
-    }
-
-// Warning macro
-#ifdef WARN
-#undef WARN
-#endif
-#define WARN(x) printError(x)
-#define WARN_VARG(x, ...) printError(x, __VA_ARGS__)
-#endif
+        printError("%s -- ", __FUNCTION__); \
+        printError(__VA_ARGS__); \
+        printError("\n"); \
+    } while (0)
 
 // Bullet Physics
 #include <btBulletDynamicsCommon.h>
@@ -256,11 +248,7 @@ typedef GLuint RenderBufferHandle;
     { \
         gl_code; \
         __gl_error_code = glGetError(); \
-        if (__gl_error_code != GL_NO_ERROR) \
-        { \
-            LOG_ERROR_VARG(#gl_code ": %d", (int)__gl_error_code); \
-        } \
-        assert(__gl_error_code == GL_NO_ERROR); \
+        GP_ASSERT(__gl_error_code == GL_NO_ERROR); \
     }
 #endif
 
@@ -280,7 +268,7 @@ typedef GLuint RenderBufferHandle;
         __gl_error_code = glGetError(); \
         if (__gl_error_code != GL_NO_ERROR) \
         { \
-            LOG_ERROR_VARG(#gl_code ": %d", (int)__gl_error_code); \
+            GP_ERROR(#gl_code ": %d", (int)__gl_error_code); \
         } \
     }
 
@@ -302,28 +290,4 @@ extern GLenum __gl_error_code;
     #pragma warning( disable : 4996 )
 #endif
 
-#ifdef __ANDROID__
-#include <android_native_app_glue.h>
-extern void amain(struct android_app* state);
-#endif
-
-
-// Assert has special behavior on Windows (for Visual Studio).
-#ifdef WIN32
-#ifdef assert
-#undef assert
-#endif
-#ifdef _DEBUG
-#define assert(expression) do { \
-    if (!(expression)) \
-    { \
-        printError("Assertion \'" #expression "\' failed."); \
-        __debugbreak(); \
-    } } while (0)
-
-#else
-#define assert(expression) do { (void)sizeof(expression); } while (0)
-#endif
-#endif
-
 #endif

+ 1 - 1
gameplay/src/BoundingBox.cpp

@@ -32,7 +32,7 @@ const BoundingBox& BoundingBox::empty()
 
 void BoundingBox::getCorners(Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     // Near face, specified counter-clockwise looking towards the origin from the positive z-axis.
     // Left-top-front.

+ 66 - 66
gameplay/src/Bundle.cpp

@@ -96,7 +96,7 @@ bool Bundle::readArray(unsigned int* length, std::vector<T>* values)
 template <class T>
 bool Bundle::readArray(unsigned int* length, std::vector<T>* values, unsigned int readSize)
 {
-    assert(sizeof(T) >= readSize);
+    GP_ASSERT(sizeof(T) >= readSize);
 
     if (!read(length))
     {
@@ -122,7 +122,7 @@ std::string readString(FILE* fp)
     }
 
     // Sanity check to detect if string length is far too big
-    assert(length < BUNDLE_MAX_STRING_LENGTH);
+    GP_ASSERT(length < BUNDLE_MAX_STRING_LENGTH);
 
     std::string str;
     if (length > 0)
@@ -154,7 +154,7 @@ Bundle* Bundle::create(const char* path)
     FILE* fp = FileSystem::openFile(path, "rb");
     if (!fp)
     {
-        WARN_VARG("Failed to open file: '%s'.", path);
+        GP_WARN("Failed to open file: '%s'.", path);
         return NULL;
     }
 
@@ -162,7 +162,7 @@ Bundle* Bundle::create(const char* path)
     char sig[9];
     if (fread(sig, 1, 9, fp) != 9 || memcmp(sig, "«GPB»\r\n\x1A\n", 9) != 0)
     {
-        LOG_ERROR_VARG("Invalid bundle header: %s", path);
+        GP_ERROR("Invalid bundle header: %s", path);
         fclose(fp);
         return NULL;
     }
@@ -171,7 +171,7 @@ Bundle* Bundle::create(const char* path)
     unsigned char ver[2];
     if (fread(ver, 1, 2, fp) != 2 || ver[0] != BUNDLE_VERSION_MAJOR || ver[1] != BUNDLE_VERSION_MINOR)
     {
-        LOG_ERROR_VARG("Unsupported version (%d.%d) for bundle: %s (expected %d.%d)", (int)ver[0], (int)ver[1], path, BUNDLE_VERSION_MAJOR, BUNDLE_VERSION_MINOR);
+        GP_ERROR("Unsupported version (%d.%d) for bundle: %s (expected %d.%d)", (int)ver[0], (int)ver[1], path, BUNDLE_VERSION_MAJOR, BUNDLE_VERSION_MINOR);
         fclose(fp);
         return NULL;
     }
@@ -257,20 +257,20 @@ Bundle::Reference* Bundle::seekTo(const char* id, unsigned int type)
     Reference* ref = find(id);
     if (ref == NULL)
     {
-        LOG_ERROR_VARG("No object with name '%s' in bundle '%s'.", id, _path.c_str());
+        GP_ERROR("No object with name '%s' in bundle '%s'.", id, _path.c_str());
         return NULL;
     }
 
     if (ref->type != type)
     {
-        LOG_ERROR_VARG("Object '%s' in bundle '%s' has type %d (expected type %d).", id, _path.c_str(), (int)ref->type, (int)type);
+        GP_ERROR("Object '%s' in bundle '%s' has type %d (expected type %d).", id, _path.c_str(), (int)ref->type, (int)type);
         return NULL;
     }
 
     // Seek to the offset of this object
     if (fseek(_file, ref->offset, SEEK_SET) != 0)
     {
-        LOG_ERROR_VARG("Failed to seek to object '%s' in bundle '%s'.", id, _path.c_str());
+        GP_ERROR("Failed to seek to object '%s' in bundle '%s'.", id, _path.c_str());
         return NULL;
     }
 
@@ -288,7 +288,7 @@ Bundle::Reference* Bundle::seekToFirstType(unsigned int type)
             // Found a match
             if (fseek(_file, ref->offset, SEEK_SET) != 0)
             {
-                LOG_ERROR_VARG("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
+                GP_ERROR("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
                 return NULL;
             }
             return ref;
@@ -363,7 +363,7 @@ Scene* Bundle::loadScene(const char* id)
     {
         Node* node = scene->findNode(xref.c_str() + 1, true);
         Camera* camera = node->getCamera();
-        assert(camera);
+        GP_ASSERT(camera);
         scene->setActiveCamera(camera);
     }
 
@@ -372,19 +372,19 @@ Scene* Bundle::loadScene(const char* id)
     if (!read(&red))
     {
         SAFE_RELEASE(scene);
-        LOG_ERROR_VARG("Failed to read scene ambient %s color in pakcage %s", "red", _path.c_str());
+        GP_ERROR("Failed to read scene ambient %s color in pakcage %s", "red", _path.c_str());
         return NULL;
     }
     if (!read(&green))
     {
         SAFE_RELEASE(scene);
-        LOG_ERROR_VARG("Failed to read scene ambient %s color in pakcage %s", "green", _path.c_str());
+        GP_ERROR("Failed to read scene ambient %s color in pakcage %s", "green", _path.c_str());
         return NULL;
     }
     if (!read(&blue))
     {
         SAFE_RELEASE(scene);
-        LOG_ERROR_VARG("Failed to read scene ambient %s color in pakcage %s", "blue", _path.c_str());
+        GP_ERROR("Failed to read scene ambient %s color in pakcage %s", "blue", _path.c_str());
         return NULL;
     }
     scene->setAmbientColor(red, green, blue);
@@ -398,7 +398,7 @@ Scene* Bundle::loadScene(const char* id)
             // Found a match
             if (fseek(_file, ref->offset, SEEK_SET) != 0)
             {
-                LOG_ERROR_VARG("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
+                GP_ERROR("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
                 return NULL;
             }
             readAnimations(scene);
@@ -417,7 +417,7 @@ Node* Bundle::loadNode(const char* id)
 
 Node* Bundle::loadNode(const char* id, Scene* sceneContext)
 {
-    assert(id);
+    GP_ASSERT(id);
 
     clearLoadSession();
 
@@ -435,7 +435,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
         {
             if (fseek(_file, ref->offset, SEEK_SET) != 0)
             {
-                LOG_ERROR_VARG("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
+                GP_ERROR("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
                 SAFE_DELETE(_trackedNodes);
                 return NULL;
             }
@@ -444,7 +444,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
             unsigned int animationCount;
             if (!read(&animationCount))
             {
-                LOG_ERROR_VARG("Failed to read %s for %s: %s", "animationCount", "Animations");
+                GP_ERROR("Failed to read %s for %s: %s", "animationCount", "Animations");
                 SAFE_DELETE(_trackedNodes);
                 return NULL;
             }
@@ -457,7 +457,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
                 unsigned int animationChannelCount;
                 if (!read(&animationChannelCount))
                 {
-                    LOG_ERROR_VARG("Failed to read %s for %s: %s", "animationChannelCount", "animation", id.c_str());
+                    GP_ERROR("Failed to read %s for %s: %s", "animationChannelCount", "animation", id.c_str());
                     SAFE_DELETE(_trackedNodes);
                     return NULL;
                 }
@@ -469,7 +469,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
                     std::string targetId = readString(_file);
                     if (targetId.empty())
                     {
-                        LOG_ERROR_VARG("Failed to read %s for %s: %s", "targetId", "animation", id.c_str());
+                        GP_ERROR("Failed to read %s for %s: %s", "targetId", "animation", id.c_str());
                         SAFE_DELETE(_trackedNodes);
                         return NULL;
                     }
@@ -482,7 +482,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
                         unsigned int targetAttribute;
                         if (!read(&targetAttribute))
                         {
-                            LOG_ERROR_VARG("Failed to read %s for %s: %s", "targetAttribute", "animation", id.c_str());
+                            GP_ERROR("Failed to read %s for %s: %s", "targetAttribute", "animation", id.c_str());
                             SAFE_DELETE(_trackedNodes);
                             return NULL;
                         }
@@ -490,7 +490,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
                         AnimationTarget* target = iter->second;
                         if (!target)
                         {
-                            LOG_ERROR_VARG("Failed to read %s for %s: %s", "animation target", targetId.c_str(), id.c_str());
+                            GP_ERROR("Failed to read %s for %s: %s", "animation target", targetId.c_str(), id.c_str());
                             SAFE_DELETE(_trackedNodes);
                             return NULL;
                         }
@@ -516,7 +516,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
 
 Node* Bundle::loadNode(const char* id, Scene* sceneContext, Node* nodeContext)
 {
-    assert(id);
+    GP_ASSERT(id);
 
     Node* node = NULL;
 
@@ -734,7 +734,7 @@ Camera* Bundle::readCamera()
     unsigned char cameraType;
     if (!read(&cameraType))
     {
-        LOG_ERROR_VARG("Failed to load camera type in bundle '%s'.", _path.c_str());
+        GP_ERROR("Failed to load camera type in bundle '%s'.", _path.c_str());
     }
 
     if (cameraType == 0)
@@ -746,21 +746,21 @@ Camera* Bundle::readCamera()
     float aspectRatio;
     if (!read(&aspectRatio))
     {
-        LOG_ERROR_VARG("Failed to load camera aspectRatio in bundle '%s'.", _path.c_str());
+        GP_ERROR("Failed to load camera aspectRatio in bundle '%s'.", _path.c_str());
     }
 
     // near plane
     float nearPlane;
     if (!read(&nearPlane))
     {
-        LOG_ERROR_VARG("Failed to load camera near plane in bundle '%s'.", _path.c_str());
+        GP_ERROR("Failed to load camera near plane in bundle '%s'.", _path.c_str());
     }
 
     // far plane
     float farPlane;
     if (!read(&farPlane))
     {
-        LOG_ERROR_VARG("Failed to load camera far plane in bundle '%s'.", _path.c_str());
+        GP_ERROR("Failed to load camera far plane in bundle '%s'.", _path.c_str());
     }
 
     Camera* camera = NULL;
@@ -770,7 +770,7 @@ Camera* Bundle::readCamera()
         float fieldOfView;
         if (!read(&fieldOfView))
         {
-            LOG_ERROR_VARG("Failed to load camera field of view in bundle '%s'.", _path.c_str());
+            GP_ERROR("Failed to load camera field of view in bundle '%s'.", _path.c_str());
         }
 
         camera = Camera::createPerspective(fieldOfView, aspectRatio, nearPlane, farPlane);
@@ -781,20 +781,20 @@ Camera* Bundle::readCamera()
         float zoomX;
         if (!read(&zoomX))
         {
-            LOG_ERROR_VARG("Failed to load camera zoomX in bundle '%s'.", _path.c_str());
+            GP_ERROR("Failed to load camera zoomX in bundle '%s'.", _path.c_str());
         }
 
         float zoomY;
         if (!read(&zoomY))
         {
-            LOG_ERROR_VARG("Failed to load camera zoomY in bundle '%s'.", _path.c_str());
+            GP_ERROR("Failed to load camera zoomY in bundle '%s'.", _path.c_str());
         }
 
         camera = Camera::createOrthographic(zoomX, zoomY, aspectRatio, nearPlane, farPlane);
     }
     else
     {
-        LOG_ERROR_VARG("Failed to load camera type in bundle '%s'. Invalid camera type.", _path.c_str());
+        GP_ERROR("Failed to load camera type in bundle '%s'. Invalid camera type.", _path.c_str());
     }
     return camera;
 }
@@ -804,7 +804,7 @@ Light* Bundle::readLight()
     unsigned char type;
     if (!read(&type))
     {
-        LOG_ERROR_VARG("Failed to load light %s in bundle '%s'.", "type", _path.c_str());
+        GP_ERROR("Failed to load light %s in bundle '%s'.", "type", _path.c_str());
     }
 
     if (type == 0)
@@ -816,7 +816,7 @@ Light* Bundle::readLight()
     float red, blue, green;
     if (!read(&red) || !read(&blue) || !read(&green))
     {
-        LOG_ERROR_VARG("Failed to load light %s in bundle '%s'.", "color", _path.c_str());
+        GP_ERROR("Failed to load light %s in bundle '%s'.", "color", _path.c_str());
     }
     Vector3 color(red, blue, green);
 
@@ -830,7 +830,7 @@ Light* Bundle::readLight()
         float range;
         if (!read(&range))
         {
-            LOG_ERROR_VARG("Failed to load point light %s in bundle '%s'.", "point", _path.c_str());
+            GP_ERROR("Failed to load point light %s in bundle '%s'.", "point", _path.c_str());
         }
         light = Light::createPoint(color, range);
     }
@@ -839,13 +839,13 @@ Light* Bundle::readLight()
         float range, innerAngle, outerAngle;
         if (!read(&range) || !read(&innerAngle) || !read(&outerAngle))
         {
-            LOG_ERROR_VARG("Failed to load spot light %s in bundle '%s'.", "spot", _path.c_str());
+            GP_ERROR("Failed to load spot light %s in bundle '%s'.", "spot", _path.c_str());
         }
         light = Light::createSpot(color, range, innerAngle, outerAngle);
     }
     else
     {
-        LOG_ERROR_VARG("Failed to load light %s in bundle '%s'.", "type", _path.c_str());
+        GP_ERROR("Failed to load light %s in bundle '%s'.", "type", _path.c_str());
     }
     return light;
 }
@@ -867,7 +867,7 @@ Model* Bundle::readModel(const char* nodeId)
             unsigned char hasSkin;
             if (!read(&hasSkin))
             {
-                LOG_ERROR_VARG("Failed to load hasSkin in bundle '%s'.", _path.c_str());
+                GP_ERROR("Failed to load hasSkin in bundle '%s'.", _path.c_str());
                 return NULL;
             }
             if (hasSkin)
@@ -882,7 +882,7 @@ Model* Bundle::readModel(const char* nodeId)
             unsigned int materialCount;
             if (!read(&materialCount))
             {
-                LOG_ERROR_VARG("Failed to load materialCount in bundle '%s'.", _path.c_str());
+                GP_ERROR("Failed to load materialCount in bundle '%s'.", _path.c_str());
                 return NULL;
             }
             if (materialCount > 0)
@@ -904,7 +904,7 @@ MeshSkin* Bundle::readMeshSkin()
     float bindShape[16];
     if (!readMatrix(bindShape))
     {
-        LOG_ERROR_VARG("Failed to load MeshSkin in bundle '%s'.", _path.c_str());
+        GP_ERROR("Failed to load MeshSkin in bundle '%s'.", _path.c_str());
         SAFE_DELETE(meshSkin);
         return NULL;
     }
@@ -917,7 +917,7 @@ MeshSkin* Bundle::readMeshSkin()
     unsigned int jointCount;
     if (!read(&jointCount))
     {
-        LOG_ERROR_VARG("Failed to load MeshSkin in bundle '%s'.", _path.c_str());
+        GP_ERROR("Failed to load MeshSkin in bundle '%s'.", _path.c_str());
         SAFE_DELETE(meshSkin);
         SAFE_DELETE(skinData);
         return NULL;
@@ -940,20 +940,20 @@ MeshSkin* Bundle::readMeshSkin()
     unsigned int jointsBindPosesCount;
     if (!read(&jointsBindPosesCount))
     {
-        LOG_ERROR_VARG("Failed to load MeshSkin in bundle '%s'.", _path.c_str());
+        GP_ERROR("Failed to load MeshSkin in bundle '%s'.", _path.c_str());
         SAFE_DELETE(meshSkin);
         SAFE_DELETE(skinData);
         return NULL;
     }
     if (jointsBindPosesCount > 0)
     {
-        assert(jointCount * 16 == jointsBindPosesCount);
+        GP_ASSERT(jointCount * 16 == jointsBindPosesCount);
         float m[16];
         for (unsigned int i = 0; i < jointCount; i++)
         {
             if (!readMatrix(m))
             {
-                LOG_ERROR_VARG("Failed to load MeshSkin in bundle '%s'.", _path.c_str());
+                GP_ERROR("Failed to load MeshSkin in bundle '%s'.", _path.c_str());
                 SAFE_DELETE(meshSkin);
                 SAFE_DELETE(skinData);
                 return NULL;
@@ -1025,7 +1025,7 @@ void Bundle::resolveJointReferences(Scene* sceneContext, Node* nodeContext)
                         Reference* ref = find(nodeID.c_str());
                         if (ref == NULL)
                         {
-                            LOG_ERROR_VARG("No object with name '%s' in bundle '%s'.", nodeID.c_str(), _path.c_str());
+                            GP_ERROR("No object with name '%s' in bundle '%s'.", nodeID.c_str(), _path.c_str());
                             break;
                         }
 
@@ -1070,7 +1070,7 @@ void Bundle::readAnimation(Scene* scene)
     unsigned int animationChannelCount;
     if (!read(&animationChannelCount))
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "animationChannelCount", "animation", animationId.c_str());
+        GP_ERROR("Failed to read %s for %s: %s", "animationChannelCount", "animation", animationId.c_str());
         return;
     }
 
@@ -1088,7 +1088,7 @@ void Bundle::readAnimations(Scene* scene)
     unsigned int animationCount;
     if (!read(&animationCount))
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "animationCount", "Animations");
+        GP_ERROR("Failed to read %s for %s: %s", "animationCount", "Animations");
         return;
     }
 
@@ -1106,7 +1106,7 @@ Animation* Bundle::readAnimationChannel(Scene* scene, Animation* animation, cons
     std::string targetId = readString(_file);
     if (targetId.empty())
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "targetId", "animation", id);
+        GP_ERROR("Failed to read %s for %s: %s", "targetId", "animation", id);
         return NULL;
     }
 
@@ -1114,7 +1114,7 @@ Animation* Bundle::readAnimationChannel(Scene* scene, Animation* animation, cons
     unsigned int targetAttribute;
     if (!read(&targetAttribute))
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "targetAttribute", "animation", id);
+        GP_ERROR("Failed to read %s for %s: %s", "targetAttribute", "animation", id);
         return NULL;
     }
 
@@ -1129,7 +1129,7 @@ Animation* Bundle::readAnimationChannel(Scene* scene, Animation* animation, cons
         target = scene->findNode(targetId.c_str());
         if (!target)
         {
-            LOG_ERROR_VARG("Failed to read %s for %s: %s", "animation target", targetId.c_str(), id);
+            GP_ERROR("Failed to read %s for %s: %s", "animation target", targetId.c_str(), id);
             return NULL;
         }
     }
@@ -1155,35 +1155,35 @@ Animation* Bundle::readAnimationChannelData(Animation* animation, const char* id
     // read key times
     if (!readArray(&keyTimesCount, &keyTimes, sizeof(unsigned int)))
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "keyTimes", "animation", id);
+        GP_ERROR("Failed to read %s for %s: %s", "keyTimes", "animation", id);
         return NULL;
     }
     
     // read key values
     if (!readArray(&valuesCount, &values))
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "values", "animation", id);
+        GP_ERROR("Failed to read %s for %s: %s", "values", "animation", id);
         return NULL;
     }
     
     // read tangentsIn
     if (!readArray(&tangentsInCount, &tangentsIn))
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "tangentsIn", "animation", id);
+        GP_ERROR("Failed to read %s for %s: %s", "tangentsIn", "animation", id);
         return NULL;
     }
     
     // read tangent_out
     if (!readArray(&tangentsOutCount, &tangentsOut))
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "tangentsOut", "animation", id);
+        GP_ERROR("Failed to read %s for %s: %s", "tangentsOut", "animation", id);
         return NULL;
     }
     
     // read interpolations
     if (!readArray(&interpolationCount, &interpolation, sizeof(unsigned int)))
     {
-        LOG_ERROR_VARG("Failed to read %s for %s: %s", "interpolation", "animation", id);
+        GP_ERROR("Failed to read %s for %s: %s", "interpolation", "animation", id);
         return NULL;
     }
 
@@ -1193,7 +1193,7 @@ Animation* Bundle::readAnimationChannelData(Animation* animation, const char* id
     // TODO: Handle other target attributes later.
     if (targetAttribute > 0)
     {
-        assert(keyTimes.size() > 0 && values.size() > 0);
+        GP_ASSERT(keyTimes.size() > 0 && values.size() > 0);
         if (animation == NULL)
         {
             // TODO: This code currently assumes LINEAR only
@@ -1210,7 +1210,7 @@ Animation* Bundle::readAnimationChannelData(Animation* animation, const char* id
 
 Mesh* Bundle::loadMesh(const char* id)
 {
-    return loadMesh(id, false);
+    return loadMesh(id, NULL);
 }
 
 Mesh* Bundle::loadMesh(const char* id, const char* nodeId)
@@ -1236,7 +1236,7 @@ Mesh* Bundle::loadMesh(const char* id, const char* nodeId)
     Mesh* mesh = Mesh::createMesh(meshData->vertexFormat, meshData->vertexCount, false);
     if (mesh == NULL)
     {
-        LOG_ERROR_VARG("Failed to create mesh: %s", id);
+        GP_ERROR("Failed to create mesh: %s", id);
         SAFE_DELETE_ARRAY(meshData);
         return NULL;
     }
@@ -1258,7 +1258,7 @@ Mesh* Bundle::loadMesh(const char* id, const char* nodeId)
         MeshPart* part = mesh->addPart(partData->primitiveType, partData->indexFormat, partData->indexCount, false);
         if (part == NULL)
         {
-            LOG_ERROR_VARG("Failed to create mesh part (i=%d): %s", i, id);
+            GP_ERROR("Failed to create mesh part (i=%d): %s", i, id);
             SAFE_DELETE(meshData);
             return NULL;
         }
@@ -1380,7 +1380,7 @@ Bundle::MeshData* Bundle::readMeshData()
 
 Bundle::MeshData* Bundle::readMeshData(const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
 
     unsigned int len = strlen(url);
     if (len == 0)
@@ -1426,7 +1426,7 @@ Font* Bundle::loadFont(const char* id)
     std::string family = readString(_file);
     if (family.empty())
     {
-        LOG_ERROR_VARG("Failed to read font family for font: %s", id);
+        GP_ERROR("Failed to read font family for font: %s", id);
         return NULL;
     }
 
@@ -1435,7 +1435,7 @@ Font* Bundle::loadFont(const char* id)
     if (fread(&style, 4, 1, _file) != 1 ||
         fread(&size, 4, 1, _file) != 1)
     {
-        LOG_ERROR_VARG("Failed to read style and/or size for font: %s", id);
+        GP_ERROR("Failed to read style and/or size for font: %s", id);
         return NULL;
     }
 
@@ -1446,13 +1446,13 @@ Font* Bundle::loadFont(const char* id)
     unsigned int glyphCount;
     if (fread(&glyphCount, 4, 1, _file) != 1 || glyphCount == 0)
     {
-        LOG_ERROR_VARG("Failed to read glyph count for font: %s", id);
+        GP_ERROR("Failed to read glyph count for font: %s", id);
         return NULL;
     }
     Font::Glyph* glyphs = new Font::Glyph[glyphCount];
     if (fread(glyphs, sizeof(Font::Glyph), glyphCount, _file) != glyphCount)
     {
-        LOG_ERROR_VARG("Failed to read %d glyphs for font: %s", glyphCount, id);
+        GP_ERROR("Failed to read %d glyphs for font: %s", glyphCount, id);
         SAFE_DELETE_ARRAY(glyphs);
         return NULL;
     }
@@ -1463,20 +1463,20 @@ Font* Bundle::loadFont(const char* id)
         fread(&height, 4, 1, _file) != 1 ||
         fread(&textureByteCount, 4, 1, _file) != 1)
     {
-        LOG_ERROR_VARG("Failed to read texture attributes for font: %s", id);
+        GP_ERROR("Failed to read texture attributes for font: %s", id);
         SAFE_DELETE_ARRAY(glyphs);
         return NULL;
     }
     if (textureByteCount != (width * height))
     {
-        LOG_ERROR_VARG("Invalid texture byte for font: %s", id);
+        GP_ERROR("Invalid texture byte for font: %s", id);
         SAFE_DELETE_ARRAY(glyphs);
         return NULL;
     }
     unsigned char* textureData = new unsigned char[textureByteCount];
     if (fread(textureData, 1, textureByteCount, _file) != textureByteCount)
     {
-        LOG_ERROR_VARG("Failed to read %d texture bytes for font: %s", textureByteCount, id);
+        GP_ERROR("Failed to read %d texture bytes for font: %s", textureByteCount, id);
         SAFE_DELETE_ARRAY(glyphs);
         SAFE_DELETE_ARRAY(textureData);
         return NULL;
@@ -1490,7 +1490,7 @@ Font* Bundle::loadFont(const char* id)
 
     if (texture == NULL)
     {
-        LOG_ERROR_VARG("Failed to create texture for font: %s", id);
+        GP_ERROR("Failed to create texture for font: %s", id);
         SAFE_DELETE_ARRAY(glyphs);
         return NULL;
     }

+ 7 - 7
gameplay/src/Camera.cpp

@@ -53,14 +53,14 @@ Camera::Type Camera::getCameraType() const
 
 float Camera::getFieldOfView() const
 {
-    assert(_type == Camera::PERSPECTIVE);
+    GP_ASSERT(_type == Camera::PERSPECTIVE);
 
     return _fieldOfView;
 }
 
 void Camera::setFieldOfView(float fieldOfView)
 {
-    assert(_type == Camera::PERSPECTIVE);
+    GP_ASSERT(_type == Camera::PERSPECTIVE);
 
     _fieldOfView = fieldOfView;
     _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
@@ -68,14 +68,14 @@ void Camera::setFieldOfView(float fieldOfView)
 
 float Camera::getZoomX() const
 {
-    assert(_type == Camera::ORTHOGRAPHIC);
+    GP_ASSERT(_type == Camera::ORTHOGRAPHIC);
 
     return _zoom[0];
 }
 
 void Camera::setZoomX(float zoomX)
 {
-    assert(_type == Camera::ORTHOGRAPHIC);
+    GP_ASSERT(_type == Camera::ORTHOGRAPHIC);
 
     _zoom[0] = zoomX;
     _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
@@ -83,14 +83,14 @@ void Camera::setZoomX(float zoomX)
 
 float Camera::getZoomY() const
 {
-    assert(_type == Camera::ORTHOGRAPHIC);
+    GP_ASSERT(_type == Camera::ORTHOGRAPHIC);
 
     return _zoom[1];
 }
 
 void Camera::setZoomY(float zoomY)
 {
-    assert(_type == Camera::ORTHOGRAPHIC);
+    GP_ASSERT(_type == Camera::ORTHOGRAPHIC);
 
     _zoom[1] = zoomY;
     _dirtyBits |= CAMERA_DIRTY_PROJ | CAMERA_DIRTY_VIEW_PROJ | CAMERA_DIRTY_INV_VIEW_PROJ | CAMERA_DIRTY_BOUNDS;
@@ -332,7 +332,7 @@ Camera* Camera::clone(NodeCloneContext &context) const
     {
         cameraClone = createOrthographic(getZoomX(), getZoomY(), getAspectRatio(), _nearPlane, _farPlane);
     }
-    assert(cameraClone);
+    GP_ASSERT(cameraClone);
 
     if (Node* node = context.findClonedNode(getNode()))
     {

+ 6 - 1
gameplay/src/CheckBox.cpp

@@ -21,6 +21,8 @@ CheckBox::~CheckBox()
 
 CheckBox* CheckBox::create(Theme::Style* style, Properties* properties)
 {
+    GP_ASSERT(properties);
+
     CheckBox* checkBox = new CheckBox();
     checkBox->initialize(style, properties);
     properties->getVector2("imageSize", &checkBox->_imageSize);
@@ -58,7 +60,7 @@ void CheckBox::addListener(Control::Listener* listener, int eventFlags)
 {
     if ((eventFlags & Control::Listener::TEXT_CHANGED) == Control::Listener::TEXT_CHANGED)
     {
-        assert("TEXT_CHANGED event is not applicable to CheckBox.");
+        GP_ERROR("TEXT_CHANGED event is not applicable to CheckBox.");
         eventFlags &= ~Control::Listener::TEXT_CHANGED;
     }
 
@@ -131,6 +133,9 @@ void CheckBox::update(const Rectangle& clip, const Vector2& offset)
 
 void CheckBox::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
 {
+    GP_ASSERT(spriteBatch);
+    GP_ASSERT(_image);
+
     // Left, v-center.
     // TODO: Set an alignment for icons.
     

+ 26 - 50
gameplay/src/Container.cpp

@@ -62,6 +62,8 @@ Container* Container::create(Layout::Type type)
 
 Container* Container::create(Theme::Style* style, Properties* properties, Theme* theme)
 {
+    GP_ASSERT(properties);
+
     const char* layoutString = properties->getString("layout");
     Container* container = Container::create(getLayoutType(layoutString));
     container->initialize(style, properties);
@@ -72,6 +74,9 @@ Container* Container::create(Theme::Style* style, Properties* properties, Theme*
 
 void Container::addControls(Theme* theme, Properties* properties)
 {
+    GP_ASSERT(theme);
+    GP_ASSERT(properties);
+
     // Add all the controls to this container.
     Properties* controlSpace = properties->getNextNamespace();
     while (controlSpace != NULL)
@@ -80,11 +85,9 @@ void Container::addControls(Theme* theme, Properties* properties)
 
         const char* controlStyleName = controlSpace->getString("style");
         Theme::Style* controlStyle = NULL;
-        if (controlStyleName)
-        {
-                controlStyle = theme->getStyle(controlStyleName);
-        }
-        assert(controlStyle);
+        GP_ASSERT(controlStyleName);
+        controlStyle = theme->getStyle(controlStyleName);
+        GP_ASSERT(controlStyle);
 
         std::string controlName(controlSpace->getNamespace());
         std::transform(controlName.begin(), controlName.end(), controlName.begin(), (int(*)(int))toupper);
@@ -116,6 +119,10 @@ void Container::addControls(Theme* theme, Properties* properties)
         {
             control = TextBox::create(controlStyle, controlSpace);
         }
+        else
+        {
+            GP_ERROR("Failed to create control; unrecognized control name \'%s\'.", controlName.c_str());
+        }
 
         // Add the new control to the form.
         if (control)
@@ -135,6 +142,7 @@ Layout* Container::getLayout()
 
 unsigned int Container::addControl(Control* control)
 {
+    GP_ASSERT(control);
     _controls.push_back(control);
 
     return _controls.size() - 1;
@@ -142,6 +150,7 @@ unsigned int Container::addControl(Control* control)
 
 void Container::insertControl(Control* control, unsigned int index)
 {
+    GP_ASSERT(control);
     std::vector<Control*>::iterator it = _controls.begin() + index;
     _controls.insert(it, control);
 }
@@ -161,18 +170,21 @@ void Container::removeControl(const char* id)
         if (strcmp(id, c->getID()) == 0)
         {
             _controls.erase(it);
+            return;
         }
     }
 }
 
 void Container::removeControl(Control* control)
 {
+    GP_ASSERT(control);
     std::vector<Control*>::iterator it;
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
         if (*it == control)
         {
             _controls.erase(it);
+            return;
         }
     }
 }
@@ -185,10 +197,12 @@ Control* Container::getControl(unsigned int index) const
 
 Control* Container::getControl(const char* id) const
 {
+    GP_ASSERT(id);
     std::vector<Control*>::const_iterator it;
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
         Control* c = *it;
+        GP_ASSERT(c);
         if (strcmp(id, c->getID()) == 0)
         {
             return c;
@@ -206,7 +220,7 @@ Control* Container::getControl(const char* id) const
     return NULL;
 }
 
-std::vector<Control*> Container::getControls() const
+const std::vector<Control*>& Container::getControls() const
 {
     return _controls;
 }
@@ -220,6 +234,7 @@ Animation* Container::getAnimation(const char* id) const
     for (; itr != end; itr++)
     {
         control = *itr;
+        GP_ASSERT(control);
         Animation* animation = control->getAnimation(id);
         if (animation)
             return animation;
@@ -240,51 +255,9 @@ void Container::update(const Rectangle& clip, const Vector2& offset)
     // Update this container's viewport.
     Control::update(clip, offset);
 
+    GP_ASSERT(_layout);
     _layout->update(this);
 }
-/*
-void Container::drawBorder(SpriteBatch* spriteBatch, const Rectangle& clip, const Vector2& offset)
-{
-    // First draw our own border.
-    Control::drawBorder(spriteBatch, clip);
-
-    // Now call drawBorder on all controls within this container.
-    std::vector<Control*>::const_iterator it;
-    for (it = _controls.begin(); it < _controls.end(); it++)
-    {
-        Control* control = *it;
-        if (control->isDirty())
-        {
-            control->drawBorder(spriteBatch, _viewportClipBounds);
-        }
-    }
-}
-
-void Container::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
-{
-    std::vector<Control*>::const_iterator it;
-    for (it = _controls.begin(); it < _controls.end(); it++)
-    {
-        Control* control = *it;
-        if (control->isDirty())
-            control->drawImages(spriteBatch, _viewportClipBounds);
-    }
-
-    _dirty = false;
-}
-
-void Container::drawText(const Rectangle& clip)
-{
-    std::vector<Control*>::const_iterator it;
-    for (it = _controls.begin(); it < _controls.end(); it++)
-    {
-        Control* control = *it;
-        if (control->isDirty())
-            control->drawText(_viewportClipBounds);
-    }
-
-    _dirty = false;
-}*/
 
 void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, float targetHeight)
 {
@@ -308,6 +281,7 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
         Control* control = *it;
+        GP_ASSERT(control);
         if (!needsClear || control->isDirty() || control->_clearBounds.intersects(boundsUnion))
         {
             control->draw(spriteBatch, _viewportClipBounds, needsClear, targetHeight);
@@ -329,6 +303,7 @@ bool Container::isDirty()
         std::vector<Control*>::const_iterator it;
         for (it = _controls.begin(); it < _controls.end(); it++)
         {
+            GP_ASSERT(*it);
             if ((*it)->isDirty())
             {
                 return true;
@@ -347,7 +322,6 @@ bool Container::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int con
     }
 
     bool eventConsumed = false;
-
     const Theme::Border& border = getBorder(_state);
     const Theme::Padding& padding = getPadding();
     float xPos = border.left + padding.left;
@@ -363,6 +337,7 @@ bool Container::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int con
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
         Control* control = *it;
+        GP_ASSERT(control);
         if (!control->isEnabled())
         {
             continue;
@@ -422,6 +397,7 @@ void Container::keyEvent(Keyboard::KeyEvent evt, int key)
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
         Control* control = *it;
+        GP_ASSERT(control);
         if (!control->isEnabled())
         {
             continue;

+ 1 - 1
gameplay/src/Container.h

@@ -112,7 +112,7 @@ public:
      *
      * @return The vector of the controls within this container.
      */
-    std::vector<Control*> getControls() const;
+    const std::vector<Control*>& getControls() const;
 
     /**
      * Gets the first animation in the control with the specified ID.

+ 85 - 20
gameplay/src/Control.cpp

@@ -35,6 +35,7 @@ Control::~Control()
 
 void Control::initialize(Theme::Style* style, Properties* properties)
 {
+    GP_ASSERT(properties);
     _style = style;
 
     // Properties not defined by the style.
@@ -207,7 +208,9 @@ void Control::setOpacity(float opacity, unsigned char states)
 
 float Control::getOpacity(State state) const
 {
-    return getOverlay(state)->getOpacity();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getOpacity();
 }
 
 void Control::setBorder(float top, float bottom, float left, float right, unsigned char states)
@@ -226,7 +229,9 @@ void Control::setBorder(float top, float bottom, float left, float right, unsign
 
 const Theme::Border& Control::getBorder(State state) const
 {
-    return getOverlay(state)->getBorder();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getBorder();
 }
 
 void Control::setSkinRegion(const Rectangle& region, unsigned char states)
@@ -245,12 +250,16 @@ void Control::setSkinRegion(const Rectangle& region, unsigned char states)
 
 const Rectangle& Control::getSkinRegion(State state) const
 {
-    return getOverlay(state)->getSkinRegion();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getSkinRegion();
 }
 
 const Theme::UVs& Control::getSkinUVs(Theme::Skin::SkinArea area, State state) const
 {
-    return getOverlay(state)->getSkinUVs(area);
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getSkinUVs(area);
 }
 
 void Control::setSkinColor(const Vector4& color, unsigned char states)
@@ -269,11 +278,14 @@ void Control::setSkinColor(const Vector4& color, unsigned char states)
 
 const Vector4& Control::getSkinColor(State state) const
 {
-    return getOverlay(state)->getSkinColor();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getSkinColor();
 }
 
 void Control::setMargin(float top, float bottom, float left, float right)
 {
+    GP_ASSERT(_style);
     overrideStyle();
     _style->setMargin(top, bottom, left, right);
     _dirty = true;
@@ -281,11 +293,13 @@ void Control::setMargin(float top, float bottom, float left, float right)
 
 const Theme::Margin& Control::getMargin() const
 {
+    GP_ASSERT(_style);
     return _style->getMargin();
 }
 
 void Control::setPadding(float top, float bottom, float left, float right)
 {
+    GP_ASSERT(_style);
     overrideStyle();
     _style->setPadding(top, bottom, left, right);
     _dirty = true;
@@ -293,6 +307,7 @@ void Control::setPadding(float top, float bottom, float left, float right)
     
 const Theme::Padding& Control::getPadding() const
 {
+    GP_ASSERT(_style);
     return _style->getPadding();
 }
 
@@ -312,7 +327,9 @@ void Control::setImageRegion(const char* id, const Rectangle& region, unsigned c
 
 const Rectangle& Control::getImageRegion(const char* id, State state) const
 {
-    return getOverlay(state)->getImageRegion(id);
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getImageRegion(id);
 }
 
 void Control::setImageColor(const char* id, const Vector4& color, unsigned char states)
@@ -331,12 +348,16 @@ void Control::setImageColor(const char* id, const Vector4& color, unsigned char
 
 const Vector4& Control::getImageColor(const char* id, State state) const
 {
-    return getOverlay(state)->getImageColor(id);
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getImageColor(id);
 }
 
 const Theme::UVs& Control::getImageUVs(const char* id, State state) const
 {
-    return getOverlay(state)->getImageUVs(id);
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getImageUVs(id);
 }
 
 void Control::setCursorRegion(const Rectangle& region, unsigned char states)
@@ -355,7 +376,9 @@ void Control::setCursorRegion(const Rectangle& region, unsigned char states)
 
 const Rectangle& Control::getCursorRegion(State state) const
 {
-    return getOverlay(state)->getCursorRegion();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getCursorRegion();
 }
 
 void Control::setCursorColor(const Vector4& color, unsigned char states)
@@ -374,12 +397,16 @@ void Control::setCursorColor(const Vector4& color, unsigned char states)
 
 const Vector4& Control::getCursorColor(State state)
 {
-    return getOverlay(state)->getCursorColor();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getCursorColor();
 }
     
 const Theme::UVs& Control::getCursorUVs(State state)
 {
-    return getOverlay(state)->getCursorUVs();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getCursorUVs();
 }
 
 void Control::setFont(Font* font, unsigned char states)
@@ -398,7 +425,9 @@ void Control::setFont(Font* font, unsigned char states)
 
 Font* Control::getFont(State state) const
 {
-    return getOverlay(state)->getFont();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getFont();
 }
 
 void Control::setFontSize(unsigned int fontSize, unsigned char states)
@@ -417,7 +446,9 @@ void Control::setFontSize(unsigned int fontSize, unsigned char states)
 
 unsigned int Control::getFontSize(State state) const
 {
-    return getOverlay(state)->getFontSize();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getFontSize();
 }
 
 void Control::setTextColor(const Vector4& color, unsigned char states)
@@ -436,7 +467,9 @@ void Control::setTextColor(const Vector4& color, unsigned char states)
 
 const Vector4& Control::getTextColor(State state) const
 {
-    return getOverlay(state)->getTextColor();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getTextColor();
 }
 
 void Control::setTextAlignment(Font::Justify alignment, unsigned char states)
@@ -455,7 +488,9 @@ void Control::setTextAlignment(Font::Justify alignment, unsigned char states)
 
 Font::Justify Control::getTextAlignment(State state) const
 {
-    return getOverlay(state)->getTextAlignment();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getTextAlignment();
 }
 
 void Control::setTextRightToLeft(bool rightToLeft, unsigned char states)
@@ -474,7 +509,9 @@ void Control::setTextRightToLeft(bool rightToLeft, unsigned char states)
 
 bool Control::getTextRightToLeft(State state) const
 {
-    return getOverlay(state)->getTextRightToLeft();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getTextRightToLeft();
 }
 
 const Rectangle& Control::getClipBounds() const
@@ -561,6 +598,8 @@ bool Control::getConsumeTouchEvents()
 
 void Control::addListener(Control::Listener* listener, int eventFlags)
 {
+    GP_ASSERT(listener);
+
     if ((eventFlags & Listener::PRESS) == Listener::PRESS)
     {
         addSpecificListener(listener, Listener::PRESS);
@@ -589,6 +628,8 @@ void Control::addListener(Control::Listener* listener, int eventFlags)
 
 void Control::addSpecificListener(Control::Listener* listener, Listener::EventType eventType)
 {
+    GP_ASSERT(listener);
+
     if (!_listeners)
     {
         _listeners = new std::map<Listener::EventType, std::list<Listener*>*>();
@@ -648,6 +689,7 @@ void Control::notifyListeners(Listener::EventType eventType)
             std::list<Listener*>* listenerList = itr->second;
             for (std::list<Listener*>::iterator listenerItr = listenerList->begin(); listenerItr != listenerList->end(); listenerItr++)
             {
+                GP_ASSERT(*listenerItr);
                 (*listenerItr)->controlEvent(this, eventType);
             }
         }
@@ -757,7 +799,7 @@ void Control::update(const Rectangle& clip, const Vector2& offset)
 
 void Control::drawBorder(SpriteBatch* spriteBatch, const Rectangle& clip)
 {
-    if (!_skin || _bounds.width <= 0 || _bounds.height <= 0)
+    if (!spriteBatch || !_skin || _bounds.width <= 0 || _bounds.height <= 0)
         return;
 
     // Get the border and background images for this control's current state.
@@ -879,7 +921,11 @@ Control::State Control::getState(const char* state)
 
 Theme::ThemeImage* Control::getImage(const char* id, State state)
 {
-    return getOverlay(state)->getImageList()->getImage(id);
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    Theme::ImageList* imageList = overlay->getImageList();
+    GP_ASSERT(imageList);
+    return imageList->getImage(id);
 }
 
 // Implementation of AnimationHandler
@@ -905,6 +951,8 @@ unsigned int Control::getAnimationPropertyComponentCount(int propertyId) const
 
 void Control::getAnimationPropertyValue(int propertyId, AnimationValue* value)
 {
+    GP_ASSERT(value);
+
     switch(propertyId)
     {
     case ANIMATE_POSITION:
@@ -935,6 +983,8 @@ void Control::getAnimationPropertyValue(int propertyId, AnimationValue* value)
 
 void Control::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
 {
+    GP_ASSERT(value);
+
     switch(propertyId)
     {
     case ANIMATE_POSITION:
@@ -973,6 +1023,9 @@ void Control::setAnimationPropertyValue(int propertyId, AnimationValue* value, f
 
 Theme::Style::Overlay** Control::getOverlays(unsigned char overlayTypes, Theme::Style::Overlay** overlays)
 {
+    GP_ASSERT(overlays);
+    GP_ASSERT(_style);
+
     unsigned int index = 0;
     if ((overlayTypes & NORMAL) == NORMAL)
     {
@@ -999,6 +1052,8 @@ Theme::Style::Overlay** Control::getOverlays(unsigned char overlayTypes, Theme::
 
 Theme::Style::Overlay* Control::getOverlay(State state) const
 {
+    GP_ASSERT(_style);
+
     switch(state)
     {
     case Control::NORMAL:
@@ -1022,13 +1077,17 @@ void Control::overrideStyle()
     }
 
     // Copy the style.
-    WARN_VARG("%d", sizeof(Theme::Style::Overlay));
+    GP_ASSERT(_style);
     _style = new Theme::Style(*_style);
     _styleOverridden = true;
 }
 
 void Control::overrideThemedProperties(Properties* properties, unsigned char states)
 {
+    GP_ASSERT(properties);
+    GP_ASSERT(_style);
+    GP_ASSERT(_style->_theme);
+
     Theme::ImageList* imageList = NULL;
     Theme::ThemeImage* cursor = NULL;
     Theme::Skin* skin = NULL;
@@ -1128,7 +1187,9 @@ void Control::setSkin(Theme::Skin* skin, unsigned char states)
 
 Theme::Skin* Control::getSkin(State state)
 {
-    return getOverlay(state)->getSkin();
+    Theme::Style::Overlay* overlay = getOverlay(state);
+    GP_ASSERT(overlay);
+    return overlay->getSkin();
 }
 
 Control::Alignment Control::getAlignment(const char* alignment)
@@ -1198,6 +1259,10 @@ Control::Alignment Control::getAlignment(const char* alignment)
     {
         return Control::ALIGN_BOTTOM_RIGHT;
     }
+    else
+    {
+        GP_ERROR("Failed to get corresponding control alignment for unsupported value \'%s\'.", alignment);
+    }
 
     // Default.
     return Control::ALIGN_TOP_LEFT;

+ 5 - 5
gameplay/src/Effect.cpp

@@ -79,7 +79,7 @@ Effect* Effect::createFromFile(const char* vshPath, const char* fshPath, const c
 
     if (effect == NULL)
     {
-        LOG_ERROR_VARG("Failed to create effect from shaders: %s, %s", vshPath, fshPath);
+        GP_ERROR("Failed to create effect from shaders: %s, %s", vshPath, fshPath);
     }
     else
     {
@@ -130,7 +130,7 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
             GL_ASSERT( glGetShaderInfoLog(vertexShader, length, NULL, infoLog) );
             infoLog[length-1] = '\0';
         }
-        LOG_ERROR_VARG("Compile failed for vertex shader (%s): %s", vshPath == NULL ? "NULL" : vshPath, infoLog == NULL ? "" : infoLog);
+        GP_ERROR("Compile failed for vertex shader (%s): %s", vshPath == NULL ? "NULL" : vshPath, infoLog == NULL ? "" : infoLog);
         SAFE_DELETE_ARRAY(infoLog);
 
         // Clean up.
@@ -162,7 +162,7 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
             GL_ASSERT( glGetShaderInfoLog(fragmentShader, length, NULL, infoLog) );
             infoLog[length-1] = '\0';
         }
-        LOG_ERROR_VARG("Compile failed for fragment shader (%s): %s", fshPath == NULL ? "NULL" : fshPath, infoLog == NULL ? "" : infoLog);
+        GP_ERROR("Compile failed for fragment shader (%s): %s", fshPath == NULL ? "NULL" : fshPath, infoLog == NULL ? "" : infoLog);
         SAFE_DELETE_ARRAY(infoLog);
 
         // Clean up.
@@ -193,7 +193,7 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
             GL_ASSERT( glGetProgramInfoLog(program, length, NULL, infoLog) );
             infoLog[length-1] = '\0';
         }
-        LOG_ERROR_VARG("Linking program failed (%s,%s): %s", vshPath == NULL ? "NULL" : vshPath, fshPath == NULL ? "NULL" : fshPath, infoLog == NULL ? "" : infoLog);
+        GP_ERROR("Linking program failed (%s,%s): %s", vshPath == NULL ? "NULL" : vshPath, fshPath == NULL ? "NULL" : fshPath, infoLog == NULL ? "" : infoLog);
         SAFE_DELETE_ARRAY(infoLog);
 
         // Clean up.
@@ -387,7 +387,7 @@ void Effect::setValue(Uniform* uniform, const Vector4* values, unsigned int coun
 
 void Effect::setValue(Uniform* uniform, const Texture::Sampler* sampler)
 {
-    assert(uniform->_type == GL_SAMPLER_2D);
+    GP_ASSERT(uniform->_type == GL_SAMPLER_2D);
 
     GL_ASSERT( glActiveTexture(GL_TEXTURE0 + uniform->_index) );
 

+ 6 - 5
gameplay/src/FileSystem.cpp

@@ -11,6 +11,7 @@
 #endif
 
 #ifdef __ANDROID__
+#include <android/asset_manager.h>
 extern AAssetManager* __assetManager;
 #endif
 
@@ -49,7 +50,7 @@ void makepath(std::string path, int mode)
             // Directory does not exist.
             if (mkdir(dirPath.c_str(), 0777) != 0)
             {
-                WARN_VARG("Failed to create directory: '%s'", dirPath.c_str());
+                GP_WARN("Failed to create directory: '%s'", dirPath.c_str());
                 return;
             }
         }
@@ -169,7 +170,7 @@ FILE* FileSystem::openFile(const char* path, const char* mode)
             FILE* file = fopen(fullPath.c_str(), "wb");
         
             int ret = fwrite(data, sizeof(unsigned char), length, file);
-            assert(ret == length);
+            GP_ASSERT(ret == length);
             fclose(file);
         }
     }
@@ -198,7 +199,7 @@ char* FileSystem::readAll(const char* filePath, int* fileSize)
     FILE* file = openFile(filePath, "rb");
     if (file == NULL)
     {
-        LOG_ERROR_VARG("Failed to load file: %s", filePath);
+        GP_ERROR("Failed to load file: %s", filePath);
         return NULL;
     }
 
@@ -210,10 +211,10 @@ char* FileSystem::readAll(const char* filePath, int* fileSize)
     // Read entire file contents.
     char* buffer = new char[size + 1];
     int read = (int)fread(buffer, 1, size, file);
-    assert(read == size);
+    GP_ASSERT(read == size);
     if (read != size)
     {
-        LOG_ERROR_VARG("Read error for file: %s (%d < %d)", filePath, (int)read, (int)size);
+        GP_ERROR("Read error for file: %s (%d < %d)", filePath, (int)read, (int)size);
         SAFE_DELETE_ARRAY(buffer);
         return NULL;
     }

+ 2 - 0
gameplay/src/FlowLayout.cpp

@@ -41,6 +41,7 @@ Layout::Type FlowLayout::getType()
 
 void FlowLayout::update(const Container* container)
 {
+    GP_ASSERT(container);
     const Rectangle& containerBounds = container->getBounds();
     const Theme::Border& containerBorder = container->getBorder(container->getState());
     const Theme::Padding& containerPadding = container->getPadding();
@@ -58,6 +59,7 @@ void FlowLayout::update(const Container* container)
     for (unsigned int i = 0; i < controlsCount; i++)
     {
         Control* control = controls.at(i);
+        GP_ASSERT(control);
 
         //align(control, container);
 

+ 6 - 2
gameplay/src/Font.cpp

@@ -124,7 +124,7 @@ Font* Font::create(const char* family, Style style, unsigned int size, Glyph* gl
         __fontEffect = Effect::createFromSource(FONT_VSH, FONT_FSH);
         if (__fontEffect == NULL)
         {
-            LOG_ERROR("Failed to create effect for font.");
+            GP_ERROR("Failed to create effect for font.");
             SAFE_RELEASE(texture);
             return NULL;
         }
@@ -142,7 +142,7 @@ Font* Font::create(const char* family, Style style, unsigned int size, Glyph* gl
 
     if (batch == NULL)
     {
-        LOG_ERROR("Failed to create batch for font.");
+        GP_ERROR("Failed to create batch for font.");
         return NULL;
     }
 
@@ -1824,6 +1824,10 @@ Font::Justify Font::getJustify(const char* justify)
     {
         return Font::ALIGN_BOTTOM_RIGHT;
     }
+    else
+    {
+        GP_ERROR("Failed to get corresponding font justification for unsupported value \'%s\'.", justify);
+    }
 
     // Default.
     return Font::ALIGN_TOP_LEFT;

+ 44 - 18
gameplay/src/Form.cpp

@@ -1,6 +1,8 @@
 #include "Base.h"
 #include "Form.h"
 #include "AbsoluteLayout.h"
+#include "FlowLayout.h"
+#include "ScrollLayout.h"
 #include "VerticalLayout.h"
 #include "Game.h"
 #include "Theme.h"
@@ -41,18 +43,19 @@ Form::~Form()
 Form* Form::create(const char* url)
 {
     // Load Form from .form file.
-    assert(url);
-
     Properties* properties = Properties::create(url);
-    assert(properties);
     if (properties == NULL)
+    {
+        GP_ASSERT(properties);
         return NULL;
+    }
 
     // Check if the Properties is valid and has a valid namespace.
     Properties* formProperties = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
     assert(formProperties);
     if (!formProperties || !(strcmp(formProperties->getNamespace(), "form") == 0))
     {
+        GP_ASSERT(formProperties);
         SAFE_DELETE(properties);
         return NULL;
     }
@@ -68,21 +71,25 @@ Form* Form::create(const char* url)
         layout = AbsoluteLayout::create();
         break;
     case Layout::LAYOUT_FLOW:
+        layout = FlowLayout::create();
         break;
     case Layout::LAYOUT_VERTICAL:
         layout = VerticalLayout::create();
         break;
+    case Layout::LAYOUT_SCROLL:
+        layout = ScrollLayout::create();
+        break;
+    default:
+        GP_ERROR("Unsupported layout type \'%d\'.", getLayoutType(layoutString));
     }
 
-    assert(themeFile);
     Theme* theme = Theme::create(themeFile);
-    assert(theme);
+    GP_ASSERT(theme);
 
     Form* form = new Form();
     form->_layout = layout;
     form->_theme = theme;
 
-    //Theme* theme = form->_theme;
     const char* styleName = formProperties->getString("style");
     form->initialize(theme->getStyle(styleName), formProperties);
 
@@ -120,6 +127,7 @@ Form* Form::create(const char* url)
     // Create the frame buffer.
     form->_frameBuffer = FrameBuffer::create(form->_id.c_str());
     RenderTarget* rt = RenderTarget::create(form->_id.c_str(), w, h);
+    GP_ASSERT(rt);
     form->_frameBuffer->setRenderTarget(rt);
     SAFE_RELEASE(rt);
 
@@ -140,6 +148,7 @@ Form* Form::getForm(const char* id)
     for (it = __forms.begin(); it < __forms.end(); it++)
     {
         Form* f = *it;
+        GP_ASSERT(f);
         if (strcmp(id, f->getID()) == 0)
         {
             return f;
@@ -207,27 +216,30 @@ void Form::update()
 
 void Form::draw()
 {
-    // The first time a form is drawn, its contents are rendered into a framebuffer.
-    // The framebuffer will only be 
+    /*
+    The first time a form is drawn, its contents are rendered into a framebuffer.
+    The framebuffer will only be drawn into again when the contents of the form change.
 
-    // If this form has a node then it's a 3D form.  The contents will be rendered
-    // into a framebuffer which will be used to texture a quad.  The quad will be
-    // given the same dimensions as the form and must be transformed appropriately
-    // by the user, unless they call setQuad() themselves.
+    If this form has a node then it's a 3D form and the framebuffer will be used
+    to texture a quad.  The quad will be given the same dimensions as the form and
+    must be transformed appropriately by the user, unless they call setQuad() themselves.
 
-    // On the other hand, if this form has not been set on a node it will render
-    // directly to the display.
+    On the other hand, if this form has not been set on a node, SpriteBatch will be used
+    to render the contents of the frambuffer directly to the display.
+    */
 
     // Check whether this form has changed since the last call to draw()
     // and if so, render into the framebuffer.
     if (isDirty())
     {
+        GP_ASSERT(_frameBuffer);
         _frameBuffer->bind();
 
         Game* game = Game::getInstance();
         Rectangle prevViewport = game->getViewport();
         game->setViewport(Rectangle(_bounds.x, _bounds.y, _bounds.width, _bounds.height));
 
+        GP_ASSERT(_theme);
         _theme->setProjectionMatrix(_projectionMatrix);
         draw(_theme->getSpriteBatch(), _viewportClipBounds);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
@@ -241,6 +253,7 @@ void Form::draw()
 
     if (_node)
     {
+        GP_ASSERT(_quad);
         _quad->draw();
     }
     else
@@ -248,6 +261,7 @@ void Form::draw()
         if (!_spriteBatch)
         {
             _spriteBatch = SpriteBatch::create(_frameBuffer->getRenderTarget()->getTexture());
+            GP_ASSERT(_spriteBatch);
         }
 
         _spriteBatch->begin();
@@ -258,6 +272,8 @@ void Form::draw()
 
 void Form::draw(SpriteBatch* spriteBatch, const Rectangle& clip)
 {
+    GP_ASSERT(spriteBatch);
+
     std::vector<Control*>::const_iterator it;
 
     // Batch each font individually.
@@ -282,6 +298,7 @@ void Form::draw(SpriteBatch* spriteBatch, const Rectangle& clip)
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
         Control* control = *it;
+        GP_ASSERT(control);
 
         if (_skin || control->isDirty() || control->_clearBounds.intersects(boundsUnion))
         {
@@ -310,21 +327,27 @@ void Form::initializeQuad(Mesh* mesh)
     // Release current model.
     SAFE_RELEASE(_quad);
 
-    // Create the model
+    // Create the model.
     _quad = Model::create(mesh);
 
-    // Create the material
+    // Create the material.
     Material* material = _quad->setMaterial("res/shaders/textured.vsh", "res/shaders/textured.fsh");
+    GP_ASSERT(material);
 
-    // Set the common render state block for the material
+    // Set the common render state block for the material.
+    GP_ASSERT(_theme);
+    GP_ASSERT(_theme->getSpriteBatch());
     RenderState::StateBlock* stateBlock = _theme->getSpriteBatch()->getStateBlock();
+    GP_ASSERT(stateBlock);
     stateBlock->setDepthWrite(true);
     material->setStateBlock(stateBlock);
 
-    // Bind the WorldViewProjection matrix
+    // Bind the WorldViewProjection matrix.
     material->setParameterAutoBinding("u_worldViewProjectionMatrix", RenderState::WORLD_VIEW_PROJECTION_MATRIX);
 
+    // Bind the texture.
     Texture::Sampler* sampler = Texture::Sampler::create(_frameBuffer->getRenderTarget()->getTexture());
+    GP_ASSERT(sampler);
     sampler->setWrapMode(Texture::CLAMP, Texture::CLAMP);
     material->getParameter("u_diffuseTexture")->setValue(sampler);
     material->getParameter("u_diffuseColor")->setValue(Vector4::one());
@@ -340,6 +363,7 @@ bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int
     for (it = __forms.begin(); it < __forms.end(); it++)
     {
         Form* form = *it;
+        GP_ASSERT(form);
 
         if (form->isEnabled())
         {
@@ -347,6 +371,7 @@ bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int
             if (node)
             {
                 Scene* scene = node->getScene();
+                GP_ASSERT(scene);
                 Camera* camera = scene->getActiveCamera();
 
                 if (camera)
@@ -432,6 +457,7 @@ void Form::keyEventInternal(Keyboard::KeyEvent evt, int key)
     for (it = __forms.begin(); it < __forms.end(); it++)
     {
         Form* form = *it;
+        GP_ASSERT(form);
         if (form->isEnabled())
         {
             form->keyEvent(evt, key);

+ 1 - 1
gameplay/src/FrameBuffer.cpp

@@ -127,7 +127,7 @@ unsigned int FrameBuffer::getMaxRenderTargets()
 
 void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 {
-    assert(index < __maxRenderTargets);
+    GP_ASSERT(index < __maxRenderTargets);
 
     if (_renderTargets[index] == target)
     {

+ 1 - 3
gameplay/src/Frustum.cpp

@@ -62,7 +62,7 @@ void Frustum::getMatrix(Matrix* dst) const
 
 void Frustum::getCorners(Vector3* corners) const
 {
-    assert(corners);
+    GP_ASSERT(corners);
 
     Plane::intersection(_near, _left, _top, &corners[0]);
     Plane::intersection(_near, _left, _bottom, &corners[1]);
@@ -125,8 +125,6 @@ void Frustum::set(const Frustum& frustum)
 
 void Frustum::updatePlanes()
 {
-    _matrix.m;
-
     _near.set(Vector3(_matrix.m[3] + _matrix.m[2], _matrix.m[7] + _matrix.m[6], _matrix.m[11] + _matrix.m[10]), _matrix.m[15] + _matrix.m[14]);
     _far.set(Vector3(_matrix.m[3] - _matrix.m[2], _matrix.m[7] - _matrix.m[6], _matrix.m[11] - _matrix.m[10]), _matrix.m[15] - _matrix.m[14]);
     _bottom.set(Vector3(_matrix.m[3] + _matrix.m[1], _matrix.m[7] + _matrix.m[5], _matrix.m[11] + _matrix.m[9]), _matrix.m[15] + _matrix.m[13]);

+ 3 - 2
gameplay/src/Game.cpp

@@ -19,7 +19,7 @@ Game::Game()
       _clearDepth(1.0f), _clearStencil(0),
       _animationController(NULL), _audioController(NULL), _physicsController(NULL), _audioListener(NULL)
 {
-    assert(__gameInstance == NULL);
+    GP_ASSERT(__gameInstance == NULL);
     __gameInstance = this;
     _timeEvents = new std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >();
 }
@@ -41,6 +41,7 @@ Game::~Game()
 
 Game* Game::getInstance()
 {
+    GP_ASSERT(__gameInstance);
     return __gameInstance;
 }
 
@@ -288,7 +289,7 @@ void Game::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactI
 
 void Game::schedule(long timeOffset, TimeListener* timeListener, void* cookie)
 {
-    assert(timeListener);
+    GP_ASSERT(timeListener);
     TimeEvent timeEvent(getGameTime() + timeOffset, timeListener, cookie);
     _timeEvents->push(timeEvent);
 }

+ 2 - 2
gameplay/src/Image.cpp

@@ -18,7 +18,7 @@ Image* Image::create(const char* path)
     unsigned char sig[8];
     if (fread(sig, 1, 8, fp) != 8 || png_sig_cmp(sig, 0, 8) != 0)
     {
-        LOG_ERROR_VARG("Texture is not a valid PNG: %s", path);
+        GP_ERROR("Texture is not a valid PNG: %s", path);
         fclose(fp);
         return NULL;
     }
@@ -73,7 +73,7 @@ Image* Image::create(const char* path)
         break;
 
     default:
-        LOG_ERROR_VARG("Unsupported PNG color type (%d) for texture: %s", (int)colorType, path);
+        GP_ERROR("Unsupported PNG color type (%d) for texture: %s", (int)colorType, path);
         fclose(fp);
         png_destroy_read_struct(&png, &info, NULL);
         return NULL;

+ 4 - 5
gameplay/src/Label.cpp

@@ -27,6 +27,8 @@ Label* Label::create(Theme::Style* style, Properties* properties)
 
 void Label::initialize(Theme::Style* style, Properties* properties)
 {
+    GP_ASSERT(properties);
+
     Control::initialize(style, properties);
 
     const char* text = properties->getString("text");
@@ -40,14 +42,11 @@ void Label::addListener(Control::Listener* listener, int eventFlags)
 {
     if ((eventFlags & Listener::TEXT_CHANGED) == Listener::TEXT_CHANGED)
     {
-        assert("TEXT_CHANGED event is not applicable to this control.");
-        eventFlags &= ~Listener::TEXT_CHANGED;
+        GP_ERROR("TEXT_CHANGED event is not applicable to this control.");
     }
-
     if ((eventFlags & Listener::VALUE_CHANGED) == Listener::VALUE_CHANGED)
     {
-        assert("VALUE_CHANGED event is not applicable to this control.");
-        eventFlags &= ~Listener::VALUE_CHANGED;
+        GP_ERROR("VALUE_CHANGED event is not applicable to this control.");
     }
 
     _consumeTouchEvents = true;

+ 5 - 2
gameplay/src/Layout.cpp

@@ -8,9 +8,12 @@ namespace gameplay
 
 void Layout::align(Control* control, const Container* container)
 {
+    GP_ASSERT(control);
+    GP_ASSERT(container);
+
     if (control->_alignment != Control::ALIGN_TOP_LEFT ||
         control->_autoWidth || control->_autoHeight)
-    {
+    {
         Rectangle controlBounds = control->getBounds();
         const Theme::Margin& controlMargin = control->getMargin();
         const Rectangle& containerBounds = container->getBounds();
@@ -20,7 +23,7 @@ void Layout::align(Control* control, const Container* container)
         float clipWidth = containerBounds.width - containerBorder.left - containerBorder.right - containerPadding.left - containerPadding.right;
         float clipHeight = containerBounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom;
 
-        if (control->_autoWidth)
+        if (control->_autoWidth)
         {
             controlBounds.width = clipWidth;
         }

+ 14 - 14
gameplay/src/Light.cpp

@@ -81,7 +81,7 @@ const Vector3& Light::getColor() const
     case SPOT:
         return _spot->color;
     default:
-        assert(0);
+        GP_ASSERT(0);
         return Vector3::zero();
 
     }
@@ -105,7 +105,7 @@ void Light::setColor(const Vector3& color)
 
 float Light::getRange()  const
 {
-    assert(_type != DIRECTIONAL);
+    GP_ASSERT(_type != DIRECTIONAL);
 
     switch (_type)
     {
@@ -114,14 +114,14 @@ float Light::getRange()  const
     case SPOT:
         return _spot->range;
     default:
-        assert(0);
+        GP_ASSERT(0);
         return 0.0f;
     }
 }
     
 void Light::setRange(float range)
 {
-    assert(_type != DIRECTIONAL);
+    GP_ASSERT(_type != DIRECTIONAL);
 
     switch (_type)
     {
@@ -138,7 +138,7 @@ void Light::setRange(float range)
 
 float Light::getRangeInverse() const
 {
-    assert(_type != DIRECTIONAL);
+    GP_ASSERT(_type != DIRECTIONAL);
 
     switch (_type)
     {
@@ -147,21 +147,21 @@ float Light::getRangeInverse() const
     case SPOT:
         return _spot->rangeInverse;
     default:
-        assert(0);
+        GP_ASSERT(0);
         return 0.0f;
     }
 }
     
 float Light::getInnerAngle()  const
 {
-    assert(_type == SPOT);
+    GP_ASSERT(_type == SPOT);
 
     return _spot->innerAngle;
 }
 
 void Light::setInnerAngle(float innerAngle)
 {
-    assert(_type == SPOT);
+    GP_ASSERT(_type == SPOT);
 
     _spot->innerAngle = innerAngle;
     _spot->innerAngleCos = cos(innerAngle);
@@ -169,14 +169,14 @@ void Light::setInnerAngle(float innerAngle)
     
 float Light::getOuterAngle()  const
 {
-    assert(_type == SPOT);
+    GP_ASSERT(_type == SPOT);
 
     return _spot->outerAngle;
 }
 
 void Light::setOuterAngle(float outerAngle)
 {
-    assert(_type == SPOT);
+    GP_ASSERT(_type == SPOT);
 
     _spot->outerAngle = outerAngle;
     _spot->outerAngleCos = cos(outerAngle);
@@ -184,14 +184,14 @@ void Light::setOuterAngle(float outerAngle)
     
 float Light::getInnerAngleCos()  const
 {
-    assert(_type == SPOT);
+    GP_ASSERT(_type == SPOT);
 
     return _spot->innerAngleCos;
 }
     
 float Light::getOuterAngleCos()  const
 {
-    assert(_type == SPOT);
+    GP_ASSERT(_type == SPOT);
 
     return _spot->outerAngleCos;
 }
@@ -211,9 +211,9 @@ Light* Light::clone(NodeCloneContext &context) const
         lightClone = createSpot(getColor(), getRange(), getInnerAngle(), getOuterAngle());
         break;
     default:
-        assert(false);
+        GP_ASSERT(false);
     }
-    assert(lightClone);
+    GP_ASSERT(lightClone);
 
     if (Node* node = context.findClonedNode(getNode()))
     {

+ 6 - 6
gameplay/src/Material.cpp

@@ -34,11 +34,11 @@ Material::~Material()
 
 Material* Material::create(const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
 
     // Load the material properties from file
     Properties* properties = Properties::create(url);
-    assert(properties);
+    GP_ASSERT(properties);
     if (properties == NULL)
     {
         return NULL;
@@ -53,7 +53,7 @@ Material* Material::create(const char* url)
 Material* Material::create(Properties* materialProperties)
 {
     // Check if the Properties is valid and has a valid namespace.
-    assert(materialProperties);
+    GP_ASSERT(materialProperties);
     if (!materialProperties || !(strcmp(materialProperties->getNamespace(), "material") == 0))
     {
         return NULL;
@@ -151,7 +151,7 @@ unsigned int Material::getTechniqueCount() const
 
 Technique* Material::getTechnique(unsigned int index) const
 {
-    assert(index < _techniques.size());
+    GP_ASSERT(index < _techniques.size());
 
     return _techniques[index];
 }
@@ -227,9 +227,9 @@ bool Material::loadPass(Technique* technique, Properties* passProperties)
 {
     // Fetch shader info required to create the effect of this technique.
     const char* vertexShaderPath = passProperties->getString("vertexShader");
-    assert(vertexShaderPath);
+    GP_ASSERT(vertexShaderPath);
     const char* fragmentShaderPath = passProperties->getString("fragmentShader");
-    assert(fragmentShaderPath);
+    GP_ASSERT(fragmentShaderPath);
     const char* defines = passProperties->getString("defines");
     std::string define;
     if (defines != NULL)

+ 10 - 10
gameplay/src/MaterialParameter.cpp

@@ -232,7 +232,7 @@ void MaterialParameter::bind(Effect* effect)
         if (!_uniform)
         {
             // This parameter was not found in the specified effect, so do nothing.
-            WARN_VARG("Warning: Material parameter '%s' not found in effect '%s'.", _name.c_str(), effect->getId());
+            GP_WARN("Warning: Material parameter '%s' not found in effect '%s'.", _name.c_str(), effect->getId());
             return;
         }
     }
@@ -246,7 +246,7 @@ void MaterialParameter::bind(Effect* effect)
         }
         else
         {
-            assert(_value.floatPtrValue);
+            GP_ASSERT(_value.floatPtrValue);
             effect->setValue(_uniform, _value.floatPtrValue, _count);
         }
         break;
@@ -257,32 +257,32 @@ void MaterialParameter::bind(Effect* effect)
         }
         else
         {
-            assert(_value.intPtrValue);
+            GP_ASSERT(_value.intPtrValue);
             effect->setValue(_uniform, _value.intPtrValue, _count);
         }
         break;
     case MaterialParameter::VECTOR2:
-        assert(_value.floatPtrValue);
+        GP_ASSERT(_value.floatPtrValue);
         effect->setValue(_uniform, reinterpret_cast<Vector2*>(_value.floatPtrValue), _count);
         break;
     case MaterialParameter::VECTOR3:
-        assert(_value.floatPtrValue);
+        GP_ASSERT(_value.floatPtrValue);
         effect->setValue(_uniform, reinterpret_cast<Vector3*>(_value.floatPtrValue), _count);
         break;
     case MaterialParameter::VECTOR4:
-        assert(_value.floatPtrValue);
+        GP_ASSERT(_value.floatPtrValue);
         effect->setValue(_uniform, reinterpret_cast<Vector4*>(_value.floatPtrValue), _count);
         break;
     case MaterialParameter::MATRIX:
-        assert(_value.floatPtrValue);
+        GP_ASSERT(_value.floatPtrValue);
         effect->setValue(_uniform, reinterpret_cast<Matrix*>(_value.floatPtrValue), _count);
         break;
     case MaterialParameter::SAMPLER:
-        assert(_value.samplerValue);
+        GP_ASSERT(_value.samplerValue);
         effect->setValue(_uniform, _value.samplerValue);
         break;
     case MaterialParameter::METHOD:
-        assert(_value.method);
+        GP_ASSERT(_value.method);
         _value.method->setValue(effect);
         break;
     }
@@ -383,7 +383,7 @@ void MaterialParameter::getAnimationPropertyValue(int propertyId, AnimationValue
 
 void MaterialParameter::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
 {
-    assert(blendWeight >= 0.0f && blendWeight <= 1.0f);
+    GP_ASSERT(blendWeight >= 0.0f && blendWeight <= 1.0f);
 
     switch (propertyId)
     {

+ 29 - 29
gameplay/src/Matrix.cpp

@@ -68,7 +68,7 @@ void Matrix::createLookAt(float eyePositionX, float eyePositionY, float eyePosit
                           float targetPositionX, float targetPositionY, float targetPositionZ,
                           float upX, float upY, float upZ, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     Vector3 eye(eyePositionX, eyePositionY, eyePositionZ);
     Vector3 target(targetPositionX, targetPositionY, targetPositionZ);
@@ -111,7 +111,7 @@ void Matrix::createLookAt(float eyePositionX, float eyePositionY, float eyePosit
 void Matrix::createPerspective(float fieldOfView, float aspectRatio,
                                      float zNearPlane, float zFarPlane, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     float f_n = 1.0f / (zFarPlane - zNearPlane);
     float factor = 1.0f / tanf(MATH_DEG_TO_RAD(fieldOfView) * 0.5f);
@@ -135,7 +135,7 @@ void Matrix::createOrthographic(float width, float height, float zNearPlane, flo
 void Matrix::createOrthographicOffCenter(float left, float right, float bottom, float top,
                                          float zNearPlane, float zFarPlane, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     float r_l = 1.0f / (right - left);
     float t_b = 1.0f / (top - bottom);
@@ -153,7 +153,7 @@ void Matrix::createOrthographicOffCenter(float left, float right, float bottom,
 
 void Matrix::createScale(const Vector3& scale, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     memcpy(dst, MATRIX_IDENTITY, MATRIX_SIZE);
 
@@ -164,7 +164,7 @@ void Matrix::createScale(const Vector3& scale, Matrix* dst)
 
 void Matrix::createScale(float xScale, float yScale, float zScale, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     memcpy(dst, MATRIX_IDENTITY, MATRIX_SIZE);
 
@@ -176,7 +176,7 @@ void Matrix::createScale(float xScale, float yScale, float zScale, Matrix* dst)
 
 void Matrix::createRotation(const Quaternion& q, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     float x2 = q.x + q.x;
     float y2 = q.y + q.y;
@@ -215,7 +215,7 @@ void Matrix::createRotation(const Quaternion& q, Matrix* dst)
 
 void Matrix::createRotation(const Vector3& axis, float angle, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     float x = axis.x;
     float y = axis.y;
@@ -274,7 +274,7 @@ void Matrix::createRotation(const Vector3& axis, float angle, Matrix* dst)
 
 void Matrix::createRotationX(float angle, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     memcpy(dst, MATRIX_IDENTITY, MATRIX_SIZE);
 
@@ -289,7 +289,7 @@ void Matrix::createRotationX(float angle, Matrix* dst)
 
 void Matrix::createRotationY(float angle, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     memcpy(dst, MATRIX_IDENTITY, MATRIX_SIZE);
 
@@ -304,7 +304,7 @@ void Matrix::createRotationY(float angle, Matrix* dst)
 
 void Matrix::createRotationZ(float angle, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     memcpy(dst, MATRIX_IDENTITY, MATRIX_SIZE);
 
@@ -319,7 +319,7 @@ void Matrix::createRotationZ(float angle, Matrix* dst)
 
 void Matrix::createTranslation(const Vector3& translation, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     memcpy(dst, MATRIX_IDENTITY, MATRIX_SIZE);
 
@@ -330,7 +330,7 @@ void Matrix::createTranslation(const Vector3& translation, Matrix* dst)
 
 void Matrix::createTranslation(float xTranslation, float yTranslation, float zTranslation, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     memcpy(dst, MATRIX_IDENTITY, MATRIX_SIZE);
 
@@ -346,7 +346,7 @@ void Matrix::add(float scalar)
 
 void Matrix::add(float scalar, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->m[0]  = m[0]  + scalar;
     dst->m[1]  = m[1]  + scalar;
@@ -373,7 +373,7 @@ void Matrix::add(const Matrix& m)
 
 void Matrix::add(const Matrix& m1, const Matrix& m2, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->m[0]  = m1.m[0]  + m2.m[0];
     dst->m[1]  = m1.m[1]  + m2.m[1];
@@ -535,7 +535,7 @@ void Matrix::getTranslation(Vector3* translation) const
 
 void Matrix::getUpVector(Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = m[4];
     dst->y = m[5];
@@ -544,7 +544,7 @@ void Matrix::getUpVector(Vector3* dst) const
 
 void Matrix::getDownVector(Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
     dst->x = -m[4];
     dst->y = -m[5];
     dst->z = -m[6];
@@ -552,7 +552,7 @@ void Matrix::getDownVector(Vector3* dst) const
 
 void Matrix::getLeftVector(Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = -m[0];
     dst->y = -m[1];
@@ -561,7 +561,7 @@ void Matrix::getLeftVector(Vector3* dst) const
 
 void Matrix::getRightVector(Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = m[0];
     dst->y = m[1];
@@ -570,7 +570,7 @@ void Matrix::getRightVector(Vector3* dst) const
 
 void Matrix::getForwardVector(Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = -m[8];
     dst->y = -m[9];
@@ -579,7 +579,7 @@ void Matrix::getForwardVector(Vector3* dst) const
 
 void Matrix::getBackVector(Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = m[8];
     dst->y = m[9];
@@ -657,7 +657,7 @@ void Matrix::multiply(float scalar, Matrix* dst) const
 
 void Matrix::multiply(const Matrix& m, float scalar, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->m[0]  = m.m[0]  * scalar;
     dst->m[1]  = m.m[1]  * scalar;
@@ -684,7 +684,7 @@ void Matrix::multiply(const Matrix& m)
 
 void Matrix::multiply(const Matrix& m1, const Matrix& m2, Matrix* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     // Support the case where m1 or m2 is the same array as dst.
     float product[16];
@@ -792,7 +792,7 @@ void Matrix::rotateZ(float angle)
 
 void Matrix::rotateZ(float angle, Matrix* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     Matrix r;
     createRotationZ(angle, &r);
@@ -816,7 +816,7 @@ void Matrix::scale(float xScale, float yScale, float zScale)
 
 void Matrix::scale(float xScale, float yScale, float zScale, Matrix* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     Matrix s;
     createScale(xScale, yScale, zScale, &s);
@@ -855,7 +855,7 @@ void Matrix::set(float m11, float m12, float m13, float m14, float m21, float m2
 
 void Matrix::set(const float* m)
 {
-    assert(m);
+    GP_ASSERT(m);
     memcpy(this->m, m, MATRIX_SIZE);
 }
 
@@ -921,7 +921,7 @@ void Matrix::transformVector(const Vector3& vector, Vector3* dst) const
 
 void Matrix::transformVector(float x, float y, float z, float w, Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
     
     dst->set(
         x * m[0] + y * m[4] + z * m[8] + w * m[12],
@@ -936,7 +936,7 @@ void Matrix::transformVector(Vector4* vector) const
 
 void Matrix::transformVector(const Vector4& vector, Vector4* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->set(
         vector.x * m[0] + vector.y * m[4] + vector.z * m[8] + vector.w * m[12],
@@ -952,7 +952,7 @@ void Matrix::translate(float x, float y, float z)
 
 void Matrix::translate(float x, float y, float z, Matrix* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     Matrix t;
     createTranslation(x, y, z, &t);
@@ -976,7 +976,7 @@ void Matrix::transpose()
 
 void Matrix::transpose(Matrix* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
     
     float t[16] = {
         m[0], m[4], m[8], m[12],

+ 4 - 4
gameplay/src/MeshBatch.cpp

@@ -36,7 +36,7 @@ MeshBatch* MeshBatch::create(const VertexFormat& vertexFormat, Mesh::PrimitiveTy
 
 MeshBatch* MeshBatch::create(const VertexFormat& vertexFormat, Mesh::PrimitiveType primitiveType, Material* material, bool indexed, unsigned int initialCapacity, unsigned int growSize)
 {
-    assert(material);
+    GP_ASSERT(material);
 
     MeshBatch* batch = new MeshBatch(vertexFormat, primitiveType, material, indexed, initialCapacity, growSize);
 
@@ -73,7 +73,7 @@ void MeshBatch::setCapacity(unsigned int capacity)
 
 bool MeshBatch::resize(unsigned int capacity)
 {
-    assert(capacity > 0);
+    GP_ASSERT(capacity > 0);
     if (capacity == 0)
         return false;
 
@@ -103,7 +103,7 @@ bool MeshBatch::resize(unsigned int capacity)
         vertexCapacity = capacity + 2;
         break;
     default:
-        assert(0); // unexpected
+        GP_ASSERT(0); // unexpected
         break;
     }
 
@@ -112,7 +112,7 @@ bool MeshBatch::resize(unsigned int capacity)
     // for now, which is the same number of vertices as indices.
     unsigned int indexCapacity = vertexCapacity;
 
-    assert(indexCapacity <= USHRT_MAX);
+    GP_ASSERT(indexCapacity <= USHRT_MAX);
     if (indexCapacity > USHRT_MAX)
         return false;
 

+ 1 - 1
gameplay/src/MeshBatch.inl

@@ -11,7 +11,7 @@ Material* MeshBatch::getMaterial() const
 template <class T>
 void MeshBatch::add(T* vertices, unsigned int vertexCount, unsigned short* indices, unsigned int indexCount)
 {
-    assert(sizeof(T) == _vertexFormat.getVertexSize());
+    GP_ASSERT(sizeof(T) == _vertexFormat.getVertexSize());
     
     unsigned int newVertexCount = _vertexCount + vertexCount;
     unsigned int newIndexCount = _indexCount + indexCount;

+ 6 - 6
gameplay/src/MeshSkin.cpp

@@ -37,13 +37,13 @@ unsigned int MeshSkin::getJointCount() const
 
 Joint* MeshSkin::getJoint(unsigned int index) const
 {
-    assert(index < _joints.size());
+    GP_ASSERT(index < _joints.size());
     return _joints[index];
 }
 
 Joint* MeshSkin::getJoint(const char* id) const
 {
-    assert(id);
+    GP_ASSERT(id);
 
     for (unsigned int i = 0, count = _joints.size(); i < count; ++i)
     {
@@ -66,7 +66,7 @@ MeshSkin* MeshSkin::clone(NodeCloneContext &context) const
         const unsigned int jointCount = getJointCount();
         skin->setJointCount(jointCount);
 
-        assert(skin->_rootNode == NULL);
+        GP_ASSERT(skin->_rootNode == NULL);
         
         // Check if the root node has already been cloned.
         if (Node* rootNode = context.findClonedNode(_rootNode))
@@ -80,7 +80,7 @@ MeshSkin* MeshSkin::clone(NodeCloneContext &context) const
         }
         
         Node* node = skin->_rootNode->findNode(_rootJoint->getId());
-        assert(node);
+        GP_ASSERT(node);
         skin->_rootJoint = static_cast<Joint*>(node);
         for (unsigned int i = 0; i < jointCount; ++i)
         {
@@ -92,7 +92,7 @@ MeshSkin* MeshSkin::clone(NodeCloneContext &context) const
                 if (strcmp(skin->_rootJoint->getId(), oldJoint->getId()) == 0)
                     newJoint = static_cast<Joint*>(skin->_rootJoint);
             }
-            assert(newJoint);
+            GP_ASSERT(newJoint);
             skin->setJoint(newJoint, i);
         }
     }
@@ -128,7 +128,7 @@ void MeshSkin::setJointCount(unsigned int jointCount)
 
 void MeshSkin::setJoint(Joint* joint, unsigned int index)
 {
-    assert(index < _joints.size());
+    GP_ASSERT(index < _joints.size());
 
     if (_joints[index])
     {

+ 2 - 2
gameplay/src/Model.cpp

@@ -51,7 +51,7 @@ unsigned int Model::getMeshPartCount() const
 
 Material* Model::getMaterial(int partIndex)
 {
-    assert(partIndex == -1 || (partIndex >= 0 && partIndex < (int)getMeshPartCount()));
+    GP_ASSERT(partIndex == -1 || (partIndex >= 0 && partIndex < (int)getMeshPartCount()));
 
     Material* m = NULL;
 
@@ -75,7 +75,7 @@ Material* Model::getMaterial(int partIndex)
 
 void Model::setMaterial(Material* material, int partIndex)
 {
-    assert(partIndex == -1 || (partIndex >= 0 && partIndex < (int)getMeshPartCount()));
+    GP_ASSERT(partIndex == -1 || (partIndex >= 0 && partIndex < (int)getMeshPartCount()));
 
     Material* oldMaterial = NULL;
 

+ 19 - 8
gameplay/src/Node.cpp

@@ -87,7 +87,7 @@ Node::Type Node::getType() const
 
 void Node::addChild(Node* child)
 {
-    assert(child);
+    GP_ASSERT(child);
 
     if (child->_parent == this)
     {
@@ -285,7 +285,7 @@ unsigned int Node::getChildCount() const
 
 Node* Node::findNode(const char* id, bool recursive, bool exactMatch) const
 {
-    assert(id);
+    GP_ASSERT(id);
 
     // If the node has a model with a mesh skin, search the skin's hierarchy as well.
     Node* rootNode = NULL;
@@ -329,7 +329,7 @@ Node* Node::findNode(const char* id, bool recursive, bool exactMatch) const
 
 unsigned int Node::findNodes(const char* id, std::vector<Node*>& nodes, bool recursive, bool exactMatch) const
 {
-    assert(id);
+    GP_ASSERT(id);
     
     unsigned int count = 0;
 
@@ -601,11 +601,22 @@ void Node::transformChanged()
     _dirtyBits |= NODE_DIRTY_WORLD | NODE_DIRTY_BOUNDS;
 
     // Notify our children that their transform has also changed (since transforms are inherited).
-    Joint* rootJoint = NULL;
     Node* n = getFirstChild();
     while (n)
     {
-        n->transformChanged();
+        if (Transform::isTransformChangedSuspended())
+        {
+            // If the DIRTY_NOTIFY bit is not set
+            if (!n->isDirty(Transform::DIRTY_NOTIFY))
+            {
+                n->transformChanged();
+                suspendTransformChange(n);
+            }
+        }
+        else
+        {
+            n->transformChanged();
+        }
         n = n->getNextSibling();
     }
 
@@ -1016,10 +1027,10 @@ PhysicsCollisionObject* Node::setCollisionObject(const char* url)
 {
     // Load the collision object properties from file.
     Properties* properties = Properties::create(url);
-    assert(properties);
+    GP_ASSERT(properties);
     if (properties == NULL)
     {
-        WARN_VARG("Failed to load collision object file: %s", url);
+        GP_WARN("Failed to load collision object file: %s", url);
         return NULL;
     }
 
@@ -1039,7 +1050,7 @@ PhysicsCollisionObject* Node::setCollisionObject(Properties* properties)
         strcmp(properties->getNamespace(), "ghostObject") == 0 || 
         strcmp(properties->getNamespace(), "rigidBody") == 0))
     {
-        WARN("Failed to load collision object from properties object: must be non-null object and have namespace equal to \'character\', \'ghostObject\', or \'rigidBody\'.");
+        GP_WARN("Failed to load collision object from properties object: must be non-null object and have namespace equal to \'character\', \'ghostObject\', or \'rigidBody\'.");
         return NULL;
     }
 

+ 9 - 9
gameplay/src/ParticleEmitter.cpp

@@ -45,24 +45,24 @@ ParticleEmitter::~ParticleEmitter()
 
 ParticleEmitter* ParticleEmitter::create(const char* textureFile, TextureBlending textureBlending, unsigned int particleCountMax)
 {
-    assert(textureFile);
+    GP_ASSERT(textureFile);
 
     Texture* texture = NULL;
     texture = Texture::create(textureFile, false);
 
     if (!texture)
     {
-        LOG_ERROR_VARG("Error creating ParticleEmitter: Could not read texture file: %s", textureFile);
+        GP_ERROR("Error creating ParticleEmitter: Could not read texture file: %s", textureFile);
         return NULL;
     }
 
     // Use default SpriteBatch material.
     SpriteBatch* batch =  SpriteBatch::create(texture, NULL, particleCountMax);
     texture->release(); // batch owns the texture.
-    assert(batch);
+    GP_ASSERT(batch);
 
     ParticleEmitter* emitter = new ParticleEmitter(batch, particleCountMax);
-    assert(emitter);
+    GP_ASSERT(emitter);
 
     // By default assume only one frame which uses the entire texture.
     emitter->setTextureBlending(textureBlending);
@@ -79,12 +79,12 @@ ParticleEmitter* ParticleEmitter::create(const char* textureFile, TextureBlendin
 
 ParticleEmitter* ParticleEmitter::create(const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
 
     Properties* properties = Properties::create(url);
     if (!properties)
     {
-        LOG_ERROR_VARG("Error loading ParticleEmitter: Could not load file: %s", url);
+        GP_ERROR("Error loading ParticleEmitter: Could not load file: %s", url);
         return NULL;
     }
 
@@ -98,14 +98,14 @@ ParticleEmitter* ParticleEmitter::create(Properties* properties)
 {
     if (!properties || strcmp(properties->getNamespace(), "particle") != 0)
     {
-        LOG_ERROR("Error loading ParticleEmitter: No 'particle' namespace found");
+        GP_ERROR("Error loading ParticleEmitter: No 'particle' namespace found");
         return NULL;
     }
 
     Properties* sprite = properties->getNextNamespace();
     if (!sprite || strcmp(sprite->getNamespace(), "sprite") != 0)
     {
-        LOG_ERROR("Error loading ParticleEmitter: No 'sprite' namespace found");
+        GP_ERROR("Error loading ParticleEmitter: No 'sprite' namespace found");
         return NULL;
     }
 
@@ -114,7 +114,7 @@ ParticleEmitter* ParticleEmitter::create(Properties* properties)
     const char* texturePath = sprite->getString("path");
     if (strlen(texturePath) == 0)
     {
-        LOG_ERROR_VARG("Error loading ParticleEmitter: No texture path specified: %s", texturePath);
+        GP_ERROR("Error loading ParticleEmitter: No texture path specified: %s", texturePath);
         return NULL;
     }
 

+ 2 - 2
gameplay/src/Pass.cpp

@@ -10,7 +10,7 @@ namespace gameplay
 Pass::Pass(const char* id, Technique* technique, Effect* effect) :
     _id(id ? id : ""), _technique(technique), _effect(effect), _vaBinding(NULL)
 {
-    assert(technique);
+    GP_ASSERT(technique);
 
     RenderState::_parent = _technique;
 }
@@ -25,7 +25,7 @@ Pass* Pass::create(const char* id, Technique* technique, const char* vshPath, co
 {
     // Attempt to create/load the effect
     Effect* effect = Effect::createFromFile(vshPath, fshPath, defines);
-    assert(effect);
+    GP_ASSERT(effect);
     if (effect == NULL)
     {
         return NULL;

+ 3 - 3
gameplay/src/PhysicsCharacter.cpp

@@ -87,10 +87,10 @@ PhysicsCharacter::~PhysicsCharacter()
 PhysicsCharacter* PhysicsCharacter::create(Node* node, Properties* properties)
 {
     // Check if the properties is valid and has a valid namespace.
-    assert(properties);
+    GP_ASSERT(properties);
     if (!properties || !(strcmp(properties->getNamespace(), "character") == 0))
     {
-        WARN("Failed to load physics character from properties object: must be non-null object and have namespace equal to \'character\'.");
+        GP_WARN("Failed to load physics character from properties object: must be non-null object and have namespace equal to \'character\'.");
         return NULL;
     }
 
@@ -98,7 +98,7 @@ PhysicsCharacter* PhysicsCharacter::create(Node* node, Properties* properties)
     PhysicsCollisionShape::Definition* shape = PhysicsCollisionShape::Definition::create(node, properties);
     if (shape == NULL)
     {
-        WARN("Failed to create collision shape during physics character creation.");
+        GP_WARN("Failed to create collision shape during physics character creation.");
         return NULL;
     }
 

+ 9 - 9
gameplay/src/PhysicsCollisionShape.cpp

@@ -118,13 +118,13 @@ PhysicsCollisionShape::Definition& PhysicsCollisionShape::Definition::operator=(
 PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Node* node, Properties* properties)
 {
     // Check if the properties is valid and has a valid namespace.
-    assert(properties);
+    GP_ASSERT(properties);
     if (!properties || 
         !(strcmp(properties->getNamespace(), "character") == 0 || 
         strcmp(properties->getNamespace(), "ghostObject") == 0 || 
         strcmp(properties->getNamespace(), "rigidBody") == 0))
     {
-        WARN("Failed to load physics collision shape from properties object: must be non-null object and have namespace equal to \'character\', \'ghostObject\', or \'rigidBody\'.");
+        GP_WARN("Failed to load physics collision shape from properties object: must be non-null object and have namespace equal to \'character\', \'ghostObject\', or \'rigidBody\'.");
         return NULL;
     }
 
@@ -158,7 +158,7 @@ PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Nod
                 type = SHAPE_CAPSULE;
             else
             {
-                WARN_VARG("Could not create physics collision shape; unsupported value for collision shape type: '%s'.", typeStr.c_str());
+                GP_WARN("Could not create physics collision shape; unsupported value for collision shape type: '%s'.", typeStr.c_str());
                 return NULL;
             }
 
@@ -194,7 +194,7 @@ PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Nod
 
     if (!typeSpecified)
     {
-        WARN("Missing 'type' specifier for collision shape definition.");
+        GP_WARN("Missing 'type' specifier for collision shape definition.");
         return NULL;
     }
 
@@ -259,7 +259,7 @@ PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Nod
             Mesh* nodeMesh = node->getModel() ? node->getModel()->getMesh() : NULL;
             if (nodeMesh == NULL)
             {
-                WARN("Cannot create mesh rigid body for node without mode/mesh.");
+                GP_WARN("Cannot create mesh rigid body for node without mode/mesh.");
                 return NULL;
             }
 
@@ -275,7 +275,7 @@ PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Nod
                 case Mesh::LINE_STRIP:
                 case Mesh::POINTS:
                 case Mesh::TRIANGLE_STRIP:
-                    WARN("Mesh rigid bodies are currently only supported on meshes with primitive type equal to TRIANGLES.");
+                    GP_WARN("Mesh rigid bodies are currently only supported on meshes with primitive type equal to TRIANGLES.");
                     SAFE_DELETE(shape);
                     break;
             }
@@ -285,7 +285,7 @@ PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Nod
         case SHAPE_HEIGHTFIELD:
             if (imagePath == NULL)
             {
-                WARN("Heightfield rigid body requires an image path.");
+                GP_WARN("Heightfield rigid body requires an image path.");
             }
             else
             {
@@ -301,7 +301,7 @@ PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Nod
                     case Image::RGBA:
                         break;
                     default:
-                        WARN_VARG("Heightmap: pixel format is not supported: %d", image->getFormat());
+                        GP_WARN("Heightmap: pixel format is not supported: %d", image->getFormat());
                         return NULL;
                 }
 
@@ -310,7 +310,7 @@ PhysicsCollisionShape::Definition* PhysicsCollisionShape::Definition::create(Nod
             }
             break;
         default:
-            WARN("Unsupported value for physics collision shape type.");
+            GP_WARN("Unsupported value for physics collision shape type.");
             break;
     }
 

+ 1 - 1
gameplay/src/PhysicsConstraint.cpp

@@ -145,7 +145,7 @@ Vector3 PhysicsConstraint::getWorldCenterOfMass(const Model* model)
         else
         {
             // Warn the user that the model has no bounding volume.
-            WARN_VARG("Model \'%s\' has no bounding volume - center of mass is defaulting to local coordinate origin.", model->getNode()->getId());
+            GP_WARN("Model \'%s\' has no bounding volume - center of mass is defaulting to local coordinate origin.", model->getNode()->getId());
             model->getNode()->getWorldMatrix().transformPoint(&center);
         }
     }

+ 10 - 10
gameplay/src/PhysicsController.cpp

@@ -507,7 +507,7 @@ void PhysicsController::addCollisionObject(PhysicsCollisionObject* object)
         break;
 
     default:
-        assert(0); // unexpected (new type?)
+        GP_ASSERT(0); // unexpected (new type?)
         break;
     }
 }
@@ -529,7 +529,7 @@ void PhysicsController::removeCollisionObject(PhysicsCollisionObject* object)
             break;
 
         default:
-            assert(0); // unexpected (new type?)
+            GP_ASSERT(0); // unexpected (new type?)
             break;
         }
     }
@@ -851,7 +851,7 @@ PhysicsCollisionShape* PhysicsController::createHeightfield(Node* node, Image* i
             pixelSize = 4;
             break;
         default:
-            LOG_ERROR("Unsupported pixel format for heightmap image.");
+            GP_ERROR("Unsupported pixel format for heightmap image.");
             return NULL;
     }
 
@@ -914,7 +914,7 @@ PhysicsCollisionShape* PhysicsController::createHeightfield(Node* node, Image* i
 
 PhysicsCollisionShape* PhysicsController::createMesh(Mesh* mesh, const Vector3& scale)
 {
-    assert(mesh);
+    GP_ASSERT(mesh);
 
     // Only support meshes with triangle list primitive types
     bool triMesh = true;
@@ -936,7 +936,7 @@ PhysicsCollisionShape* PhysicsController::createMesh(Mesh* mesh, const Vector3&
 
     if (!triMesh)
     {
-        LOG_ERROR("Mesh rigid bodies are currently only supported on meshes with TRIANGLES primitive type.");
+        GP_ERROR("Mesh rigid bodies are currently only supported on meshes with TRIANGLES primitive type.");
         return NULL;
     }
 
@@ -944,7 +944,7 @@ PhysicsCollisionShape* PhysicsController::createMesh(Mesh* mesh, const Vector3&
     // in order to fetch mesh data for computing mesh rigid body.
     if (strlen(mesh->getUrl()) == 0)
     {
-        LOG_ERROR("Cannot create mesh rigid body for mesh without valid URL.");
+        GP_ERROR("Cannot create mesh rigid body for mesh without valid URL.");
         return NULL;
     }
 
@@ -1122,13 +1122,13 @@ bool PhysicsController::checkConstraintRigidBodies(PhysicsRigidBody* a, PhysicsR
 {
     if (!a->supportsConstraints())
     {
-        WARN_VARG("Rigid body '%s' does not support constraints; unexpected behavior may occur.", a->_node->getId());
+        GP_WARN("Rigid body '%s' does not support constraints; unexpected behavior may occur.", a->_node->getId());
         return false;
     }
     
     if (b && !b->supportsConstraints())
     {
-        WARN_VARG("Rigid body '%s' does not support constraints; unexpected behavior may occur.", b->_node->getId());
+        GP_WARN("Rigid body '%s' does not support constraints; unexpected behavior may occur.", b->_node->getId());
         return false;
     }
 
@@ -1247,12 +1247,12 @@ void PhysicsController::DebugDrawer::drawContactPoint(const btVector3& pointOnB,
 
 void PhysicsController::DebugDrawer::reportErrorWarning(const char* warningString)
 {
-    WARN(warningString);
+    GP_WARN(warningString);
 }
 
 void PhysicsController::DebugDrawer::draw3dText(const btVector3& location, const char* textString)
 {
-    WARN("Physics debug drawing: 3D text is not supported.");
+    GP_WARN("Physics debug drawing: 3D text is not supported.");
 }
 
 void PhysicsController::DebugDrawer::setDebugMode(int mode)

+ 3 - 3
gameplay/src/PhysicsGhostObject.cpp

@@ -42,10 +42,10 @@ PhysicsGhostObject::~PhysicsGhostObject()
 PhysicsGhostObject* PhysicsGhostObject::create(Node* node, Properties* properties)
 {
     // Check if the properties is valid and has a valid namespace.
-    assert(properties);
+    GP_ASSERT(properties);
     if (!properties || !(strcmp(properties->getNamespace(), "ghostObject") == 0))
     {
-        WARN("Failed to load ghost object from properties object: must be non-null object and have namespace equal to \'ghost\'.");
+        GP_WARN("Failed to load ghost object from properties object: must be non-null object and have namespace equal to \'ghost\'.");
         return NULL;
     }
 
@@ -53,7 +53,7 @@ PhysicsGhostObject* PhysicsGhostObject::create(Node* node, Properties* propertie
     PhysicsCollisionShape::Definition* shape = PhysicsCollisionShape::Definition::create(node, properties);
     if (shape == NULL)
     {
-        WARN("Failed to create collision shape during ghost object creation.");
+        GP_WARN("Failed to create collision shape during ghost object creation.");
         return NULL;
     }
 

+ 5 - 5
gameplay/src/PhysicsRigidBody.cpp

@@ -144,10 +144,10 @@ void PhysicsRigidBody::applyTorqueImpulse(const Vector3& torque)
 PhysicsRigidBody* PhysicsRigidBody::create(Node* node, Properties* properties)
 {
     // Check if the properties is valid and has a valid namespace.
-    assert(properties);
+    GP_ASSERT(properties);
     if (!properties || !(strcmp(properties->getNamespace(), "rigidBody") == 0))
     {
-        WARN("Failed to load rigid body from properties object: must be non-null object and have namespace equal to \'rigidBody\'.");
+        GP_WARN("Failed to load rigid body from properties object: must be non-null object and have namespace equal to \'rigidBody\'.");
         return NULL;
     }
 
@@ -155,7 +155,7 @@ PhysicsRigidBody* PhysicsRigidBody::create(Node* node, Properties* properties)
     PhysicsCollisionShape::Definition* shape = PhysicsCollisionShape::Definition::create(node, properties);
     if (shape == NULL)
     {
-        WARN("Failed to create collision shape during rigid body creation.");
+        GP_WARN("Failed to create collision shape during rigid body creation.");
         return NULL;
     }
 
@@ -227,7 +227,7 @@ float PhysicsRigidBody::getHeight(float x, float y) const
     // This function is only supported for heightfield rigid bodies.
     if (_collisionShape->getType() != PhysicsCollisionShape::SHAPE_HEIGHTFIELD)
     {
-        WARN("Attempting to get the height of a non-heightfield rigid body.");
+        GP_WARN("Attempting to get the height of a non-heightfield rigid body.");
         return 0.0f;
     }
 
@@ -248,7 +248,7 @@ float PhysicsRigidBody::getHeight(float x, float y) const
     // Check that the x, y position is within the bounds.
     if (x < 0.0f || x > w || y < 0.0f || y > h)
     {
-        WARN_VARG("Attempting to get height at point '%f, %f', which is outside the range of the heightfield with width %d and height %d.", x, y, w, h);
+        GP_WARN("Attempting to get height at point '%f, %f', which is outside the range of the heightfield with width %d and height %d.", x, y, w, h);
         return 0.0f;
     }
 

+ 0 - 1
gameplay/src/PlatformMacOSX.mm

@@ -566,7 +566,6 @@ extern void printError(const char* format, ...)
     va_list argptr;
     va_start(argptr, format);
     vfprintf(stderr, format, argptr);
-    fprintf(stderr, "\n");
     va_end(argptr);
 }
     

+ 81 - 63
gameplay/src/PlatformQNX.cpp

@@ -404,7 +404,6 @@ extern void printError(const char* format, ...)
     va_list argptr;
     va_start(argptr, format);
     vfprintf(stderr, format, argptr);
-    fprintf(stderr, "\n");
     va_end(argptr);
 }
 
@@ -778,6 +777,7 @@ int Platform::enterMessagePump()
     int domain;
     mtouch_event_t touchEvent;
     int touchId = 0;
+    bool suspended = false;
 
     // Get the initial time.
     clock_gettime(CLOCK_REALTIME, &__timespec);
@@ -794,7 +794,7 @@ int Platform::enterMessagePump()
         while (true)
         {
             rc = bps_get_event(&event, 1);
-            assert(rc == BPS_SUCCESS);
+            GP_ASSERT(rc == BPS_SUCCESS);
 
             if (event == NULL)
                 break;
@@ -950,6 +950,23 @@ int Platform::enterMessagePump()
                 case NAVIGATOR_SWIPE_DOWN:
                     _game->menu();
                     break;
+                case NAVIGATOR_WINDOW_STATE:
+                {
+                	navigator_window_state_t state = navigator_event_get_window_state(event);
+                	switch (state)
+                	{
+                	case NAVIGATOR_WINDOW_FULLSCREEN:
+                		_game->resume();
+                		suspended = false;
+                		break;
+                	case NAVIGATOR_WINDOW_THUMBNAIL:
+                	case NAVIGATOR_WINDOW_INVISIBLE:
+                		_game->pause();
+                		suspended = true;
+                		break;
+                	}
+                	break;
+                }
                 case NAVIGATOR_EXIT:
                     _game->exit();
                     break;
@@ -957,13 +974,11 @@ int Platform::enterMessagePump()
             }
             else if (domain == sensor_get_domain())
             {
-            	if (bps_event_get_code(event) == SENSOR_AZIMUTH_PITCH_ROLL_READING)
-            	{
-					float azimuth;
-					sensor_event_get_apr(event, &azimuth, &__pitch, &__roll);
-
-
-				   }
+                if (bps_event_get_code(event) == SENSOR_AZIMUTH_PITCH_ROLL_READING)
+                {
+                    float azimuth;
+                    sensor_event_get_apr(event, &azimuth, &__pitch, &__roll);
+                }
             }
         }
 
@@ -971,27 +986,30 @@ int Platform::enterMessagePump()
         if (_game->getState() == Game::UNINITIALIZED)
             break;
 
-        _game->frame();
-
-        // Post the new frame to the display.
-        // Note that there are a couple cases where eglSwapBuffers could fail
-        // with an error code that requires a certain level of re-initialization:
-        //
-        // 1) EGL_BAD_NATIVE_WINDOW - Called when the surface we're currently using
-        //    is invalidated. This would require us to destroy our EGL surface,
-        //    close our OpenKODE window, and start again.
-        //
-        // 2) EGL_CONTEXT_LOST - Power management event that led to our EGL context
-        //    being lost. Requires us to re-create and re-initalize our EGL context
-        //    and all OpenGL ES state.
-        //
-        // For now, if we get these, we'll simply exit.
-        rc = eglSwapBuffers(__eglDisplay, __eglSurface);
-        if (rc != EGL_TRUE)
+        if (!suspended)
         {
-            _game->exit();
-            perror("eglSwapBuffers");
-            break;
+            _game->frame();
+
+            // Post the new frame to the display.
+            // Note that there are a couple cases where eglSwapBuffers could fail
+            // with an error code that requires a certain level of re-initialization:
+            //
+            // 1) EGL_BAD_NATIVE_WINDOW - Called when the surface we're currently using
+            //    is invalidated. This would require us to destroy our EGL surface,
+            //    close our OpenKODE window, and start again.
+            //
+            // 2) EGL_CONTEXT_LOST - Power management event that led to our EGL context
+            //    being lost. Requires us to re-create and re-initalize our EGL context
+            //    and all OpenGL ES state.
+            //
+            // For now, if we get these, we'll simply exit.
+            rc = eglSwapBuffers(__eglDisplay, __eglSurface);
+            if (rc != EGL_TRUE)
+            {
+                _game->exit();
+                perror("eglSwapBuffers");
+                break;
+            }
         }
     }
 
@@ -1059,40 +1077,40 @@ bool Platform::isMultiTouch()
 
 void Platform::getAccelerometerValues(float* pitch, float* roll)
 {
-	switch(__orientationAngle)
-	{
-	// Landscape based device adjusting for landscape game mode
-	case 0:
-		if (pitch)
-			*pitch = __pitch;
-		if (roll)
-			*roll = -__roll;
-		break;
-	case 180:
-		if (pitch)
-			*pitch = -__pitch;
-		if (roll)
-			*roll = __roll;
-		break;
-
-	// Portrait based device adjusting for landscape game mode
-	case 90:
-		if (pitch)
-			*pitch = -__roll;
-		if (roll)
-			*roll = -__pitch;
-		break;
-
-	case  270:
-		if (pitch)
-			*pitch = __roll;
-		if (roll)
-			*roll = __pitch;
-		break;
-
-	default:
-		break;
-	}
+    switch(__orientationAngle)
+    {
+    // Landscape based device adjusting for landscape game mode
+    case 0:
+        if (pitch)
+            *pitch = __pitch;
+        if (roll)
+            *roll = -__roll;
+        break;
+    case 180:
+        if (pitch)
+            *pitch = -__pitch;
+        if (roll)
+            *roll = __roll;
+        break;
+
+    // Portrait based device adjusting for landscape game mode
+    case 90:
+        if (pitch)
+            *pitch = -__roll;
+        if (roll)
+            *roll = -__pitch;
+        break;
+
+    case  270:
+        if (pitch)
+            *pitch = __roll;
+        if (roll)
+            *roll = __pitch;
+        break;
+
+    default:
+        break;
+    }
 }
 
 void Platform::swapBuffers()

+ 2 - 4
gameplay/src/PlatformWin32.cpp

@@ -416,14 +416,12 @@ extern void printError(const char* format, ...)
 {
     va_list argptr;
     va_start(argptr, format);
-    fprintf(stderr, "\n");
     int sz = vfprintf(stderr, format, argptr);
     if (sz > 0)
     {
-        char* buf = new char[sz + 2];
+        char* buf = new char[sz + 1];
         vsprintf(buf, format, argptr);
-        buf[sz] = '\n';
-        buf[sz+1] = 0;
+        buf[sz] = 0;
         OutputDebugStringA(buf);
         SAFE_DELETE_ARRAY(buf);
     }

+ 37 - 38
gameplay/src/PlatformiOS.mm

@@ -45,7 +45,7 @@ int getKey(unichar keyCode);
 {
     EAGLContext* context;	
     CADisplayLink* displayLink;
-	GLuint defaultFramebuffer;
+    GLuint defaultFramebuffer;
     GLuint colorRenderbuffer;
     GLuint depthRenderbuffer;
     GLint framebufferWidth;
@@ -87,11 +87,11 @@ int getKey(unichar keyCode);
 - (id) initWithFrame:(CGRect)frame
 {
     if ((self = [super initWithFrame:frame]))
-	{
+    {
         // A system version of 3.1 or greater is required to use CADisplayLink. 
-		NSString *reqSysVer = @"3.1";
-		NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
-		if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
+        NSString *reqSysVer = @"3.1";
+        NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
+        if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
         {
             // Log the system version
             NSLog(@"System Version: %@", currSysVer);
@@ -113,12 +113,12 @@ int getKey(unichar keyCode);
         self.contentScaleFactor = scale;
         layer.contentsScale = scale;
         
-		context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
         if (!context || ![EAGLContext setCurrentContext:context])
-		{
-			[self release];
-			return nil;
-		}
+        {
+            [self release];
+            return nil;
+        }
 
         if (!defaultFramebuffer)
         {
@@ -135,7 +135,7 @@ int getKey(unichar keyCode);
         depthRenderbuffer = 0;
         framebufferWidth = 0;
         framebufferHeight = 0;
-		swapInterval = 1;        
+        swapInterval = 1;        
         updating = FALSE;
         
         [self createFramebuffer];
@@ -156,11 +156,11 @@ int getKey(unichar keyCode);
     _game->exit();
     [self deleteFramebuffer];
     
-	if ([EAGLContext currentContext] == context)
+    if ([EAGLContext currentContext] == context)
     {
         [EAGLContext setCurrentContext:nil];
     }
-	[context release];
+    [context release];
     [super dealloc];
 }
 
@@ -228,15 +228,15 @@ int getKey(unichar keyCode);
 
 - (void)setSwapInterval:(NSInteger)interval
 {
-	if (interval >= 1)
-	{
-		swapInterval = interval;		
-		if (updating)
-		{
-			[self stopUpdating];
-			[self startUpdating];
-		}
-	}
+    if (interval >= 1)
+    {
+        swapInterval = interval;		
+        if (updating)
+        {
+            [self stopUpdating];
+            [self startUpdating];
+        }
+    }
 }
 
 - (int)swapInterval 
@@ -255,25 +255,25 @@ int getKey(unichar keyCode);
 
 - (void)startUpdating
 {
-	if (!updating)
-	{
+    if (!updating)
+    {
         displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
         [displayLink setFrameInterval:swapInterval];
         [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
         _game->resume();
-		updating = TRUE;
-	}
+        updating = TRUE;
+    }
 }
 
 - (void)stopUpdating
 {
-	if (updating)
-	{
+    if (updating)
+    {
         _game->pause();
-		[displayLink invalidate];
+        [displayLink invalidate];
         displayLink = nil;
-		updating = FALSE;
-	}
+        updating = FALSE;
+    }
 }
 
 - (void)update:(id)sender
@@ -504,27 +504,27 @@ int getKey(unichar keyCode);
 
 - (void)applicationWillResignActive:(UIApplication*)application
 {    
-	[viewController stopUpdating];
+    [viewController stopUpdating];
 }
 
 - (void)applicationDidEnterBackground:(UIApplication*)application 
 {
-	[viewController stopUpdating];
+    [viewController stopUpdating];
 }
 
 - (void)applicationWillEnterForeground:(UIApplication*)application 
 {	
-	[viewController startUpdating];
+    [viewController startUpdating];
 }
 
 - (void)applicationDidBecomeActive:(UIApplication*)application 
 {
-	[viewController startUpdating];
+    [viewController startUpdating];
 }
 
 - (void)applicationWillTerminate:(UIApplication*)application 
 {	
-	[viewController stopUpdating];
+    [viewController stopUpdating];
 }
 
 - (void)dealloc 
@@ -533,7 +533,7 @@ int getKey(unichar keyCode);
     [viewController release];
     [window release];
     [motionManager release];
-	[super dealloc];
+    [super dealloc];
 }
 
 @end
@@ -775,7 +775,6 @@ extern void printError(const char* format, ...)
     va_list argptr;
     va_start(argptr, format);
     vfprintf(stderr, format, argptr);
-    fprintf(stderr, "\n");
     va_end(argptr);
 }
 

+ 24 - 24
gameplay/src/Properties.cpp

@@ -48,11 +48,11 @@ Properties::Properties(FILE* file, const char* name, const char* id, const char*
 
 Properties* Properties::create(const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
 
     if (!url || strlen(url) == 0)
     {
-        WARN("Attempting to create a Properties object from an empty URL!");
+        GP_WARN("Attempting to create a Properties object from an empty URL!");
         return NULL;
     }
 
@@ -119,7 +119,7 @@ Properties* Properties::create(const char* url)
                 iter = properties->getNextNamespace();
                 if (iter == NULL)
                 {
-                    WARN_VARG("Failed to load Properties object from URL '%s'.", url);
+                    GP_WARN("Failed to load Properties object from URL '%s'.", url);
                     return NULL;
                 }
             }
@@ -173,7 +173,7 @@ void Properties::readProperties(FILE* file)
                 name = strtok(line, " =\t");
                 if (name == NULL)
                 {
-                    LOG_ERROR("Error parsing properties file: value without name.");
+                    GP_ERROR("Error parsing properties file: value without name.");
                     return;
                 }
 
@@ -181,7 +181,7 @@ void Properties::readProperties(FILE* file)
                 value = strtok(NULL, "=");
                 if (value == NULL)
                 {
-                    LOG_ERROR("Error parsing properties file: name without value.");
+                    GP_ERROR("Error parsing properties file: name without value.");
                 }
 
                 // Remove white-space from value.
@@ -214,7 +214,7 @@ void Properties::readProperties(FILE* file)
                 name = trimWhiteSpace(name);
                 if (name == NULL)
                 {
-                    LOG_ERROR("Error parsing properties file: unknown error.");
+                    GP_ERROR("Error parsing properties file: unknown error.");
                 }
                 else if (name[0] == '}')
                 {
@@ -541,7 +541,7 @@ const char* Properties::getId() const
 
 bool Properties::exists(const char* name) const
 {
-    assert(name);
+    GP_ASSERT(name);
     return _properties.find(name) != _properties.end();
 }
 
@@ -654,7 +654,7 @@ int Properties::getInt(const char* name) const
         scanned = sscanf(valueString, "%d", &value);
         if (scanned != 1)
         {
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             return 0;
         }
         return value;
@@ -673,7 +673,7 @@ float Properties::getFloat(const char* name) const
         scanned = sscanf(valueString, "%f", &value);
         if (scanned != 1)
         {
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             return 0.0f;
         }
         return value;
@@ -692,7 +692,7 @@ long Properties::getLong(const char* name) const
         scanned = sscanf(valueString, "%ld", &value);
         if (scanned != 1)
         {
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             return 0L;
         }
         return value;
@@ -703,7 +703,7 @@ long Properties::getLong(const char* name) const
 
 bool Properties::getMatrix(const char* name, Matrix* out) const
 {
-    assert(out);
+    GP_ASSERT(out);
 
     const char* valueString = getString(name);
     if (valueString)
@@ -716,7 +716,7 @@ bool Properties::getMatrix(const char* name, Matrix* out) const
 
         if (scanned != 16)
         {
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             out->setIdentity();
             return false;
         }
@@ -731,7 +731,7 @@ bool Properties::getMatrix(const char* name, Matrix* out) const
 
 bool Properties::getVector2(const char* name, Vector2* out) const
 {
-    assert(out);
+    GP_ASSERT(out);
 
     const char* valueString = getString(name);
     if (valueString)
@@ -741,7 +741,7 @@ bool Properties::getVector2(const char* name, Vector2* out) const
         scanned = sscanf(valueString, "%f,%f", &x, &y);
         if (scanned != 2)
         {
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             out->set(0.0f, 0.0f);
             return false;
         }
@@ -756,7 +756,7 @@ bool Properties::getVector2(const char* name, Vector2* out) const
 
 bool Properties::getVector3(const char* name, Vector3* out) const
 {
-    assert(out);
+    GP_ASSERT(out);
 
     const char* valueString = getString(name);
     if (valueString)
@@ -766,7 +766,7 @@ bool Properties::getVector3(const char* name, Vector3* out) const
         scanned = sscanf(valueString, "%f,%f,%f", &x, &y, &z);
         if (scanned != 3)
         {
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             out->set(0.0f, 0.0f, 0.0f);
             return false;
         }
@@ -781,7 +781,7 @@ bool Properties::getVector3(const char* name, Vector3* out) const
 
 bool Properties::getVector4(const char* name, Vector4* out) const
 {
-    assert(out);
+    GP_ASSERT(out);
 
     const char* valueString = getString(name);
     if (valueString)
@@ -791,7 +791,7 @@ bool Properties::getVector4(const char* name, Vector4* out) const
         scanned = sscanf(valueString, "%f,%f,%f,%f", &x, &y, &z, &w);
         if (scanned != 4)
         {
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             out->set(0.0f, 0.0f, 0.0f, 0.0f);
             return false;
         }
@@ -806,7 +806,7 @@ bool Properties::getVector4(const char* name, Vector4* out) const
 
 bool Properties::getQuaternionFromAxisAngle(const char* name, Quaternion* out) const
 {
-    assert(out);
+    GP_ASSERT(out);
 
     const char* valueString = getString(name);
     if (valueString)
@@ -816,7 +816,7 @@ bool Properties::getQuaternionFromAxisAngle(const char* name, Quaternion* out) c
         scanned = sscanf(valueString, "%f,%f,%f,%f", &x, &y, &z, &theta);
         if (scanned != 4)
         {
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             out->set(0.0f, 0.0f, 0.0f, 1.0f);
             return false;
         }
@@ -831,7 +831,7 @@ bool Properties::getQuaternionFromAxisAngle(const char* name, Quaternion* out) c
 
 bool Properties::getColor(const char* name, Vector3* out) const
 {
-    assert(out);
+    GP_ASSERT(out);
 
     const char* valueString = getString(name);
     if (valueString)
@@ -840,7 +840,7 @@ bool Properties::getColor(const char* name, Vector3* out) const
             valueString[0] != '#')
         {
             // Not a color string.
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             out->set(0.0f, 0.0f, 0.0f);
             return false;
         }
@@ -859,7 +859,7 @@ bool Properties::getColor(const char* name, Vector3* out) const
 
 bool Properties::getColor(const char* name, Vector4* out) const
 {
-    assert(out);
+    GP_ASSERT(out);
 
     const char* valueString = getString(name);
     if (valueString)
@@ -868,7 +868,7 @@ bool Properties::getColor(const char* name, Vector4* out) const
             valueString[0] != '#')
         {
             // Not a color string.
-            LOG_ERROR_VARG("Error parsing property: %s", name);
+            GP_ERROR("Error parsing property: %s", name);
             out->set(0.0f, 0.0f, 0.0f, 0.0f);
             return false;
         }

+ 3 - 3
gameplay/src/Properties.h

@@ -95,7 +95,7 @@ namespace gameplay
         // Print the name and ID of the current namespace.
         const char* spacename = properties->getNamespace();
         const char* id = properties->getId();
-        WARN_VARG("Namespace: %s  ID: %s\n{", spacename, id);
+        GP_WARN("Namespace: %s  ID: %s\n{", spacename, id);
  
         // Print all properties in this namespace.
         const char* name = properties->getNextProperty();
@@ -103,10 +103,10 @@ namespace gameplay
         while (name != NULL)
         {
             value = properties->getString(name);
-            WARN_VARG("%s = %s", name, value);
+            GP_WARN("%s = %s", name, value);
             name = properties->getNextProperty();
         }
-        WARN("}\n");
+        GP_WARN("}\n");
  
         // Print the properties of every namespace within this one.
         Properties* space = properties->getNextNamespace();

+ 11 - 11
gameplay/src/Quaternion.cpp

@@ -62,14 +62,14 @@ bool Quaternion::isZero() const
 
 void Quaternion::createFromRotationMatrix(const Matrix& m, Quaternion* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     m.getRotation(dst);
 }
 
 void Quaternion::createFromAxisAngle(const Vector3& axis, float angle, Quaternion* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     float halfAngle = angle * 0.5f;
     float sinHalfAngle = sinf(halfAngle);
@@ -151,7 +151,7 @@ void Quaternion::normalize()
 
 void Quaternion::normalize(Quaternion* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     if (this != dst)
     {
@@ -189,7 +189,7 @@ void Quaternion::set(float x, float y, float z, float w)
 
 void Quaternion::set(float* array)
 {
-    assert(array);
+    GP_ASSERT(array);
 
     x = array[0];
     y = array[1];
@@ -225,7 +225,7 @@ void Quaternion::setIdentity()
 
 float Quaternion::toAxisAngle(Vector3* axis) const
 {
-    assert(axis);
+    GP_ASSERT(axis);
 
     Quaternion q(x, y, z, w);
     q.normalize();
@@ -239,8 +239,8 @@ float Quaternion::toAxisAngle(Vector3* axis) const
 
 void Quaternion::lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion* dst)
 {
-    assert(dst);
-    assert(!(t < 0.0f || t > 1.0f));
+    GP_ASSERT(dst);
+    GP_ASSERT(!(t < 0.0f || t > 1.0f));
 
     if (t == 0.0f)
     {
@@ -268,8 +268,8 @@ void Quaternion::slerp(const Quaternion& q1, const Quaternion& q2, float t, Quat
 
 void Quaternion::squad(const Quaternion& q1, const Quaternion& q2, const Quaternion& s1, const Quaternion& s2, float t, Quaternion* dst)
 {
-    assert(dst);
-    assert(!(t < 0.0f || t > 1.0f));
+    GP_ASSERT(dst);
+    GP_ASSERT(!(t < 0.0f || t > 1.0f));
 
     Quaternion dstQ(0.0f, 0.0f, 0.0f, 1.0f);
     Quaternion dstS(0.0f, 0.0f, 0.0f, 1.0f);
@@ -285,8 +285,8 @@ void Quaternion::slerp(float q1x, float q1y, float q1z, float q1w, float q2x, fl
     // It contains no division operations, no trig, no inverse trig
     // and no sqrt. Not only does this code tolerate small constraint
     // errors in the input quaternions, it actually corrects for them.
-    assert(dstx && dsty && dstz && dstw);
-    assert(!(t < 0.0f || t > 1.0f));
+    GP_ASSERT(dstx && dsty && dstz && dstw);
+    GP_ASSERT(!(t < 0.0f || t > 1.0f));
 
     if (t == 0.0f)
     {

+ 1 - 0
gameplay/src/Quaternion.h

@@ -41,6 +41,7 @@ class Matrix;
 class Quaternion
 {
     friend class Curve;
+    friend class Transform;
 
 public:
 

+ 7 - 2
gameplay/src/RadioButton.cpp

@@ -26,6 +26,8 @@ RadioButton::~RadioButton()
 
 RadioButton* RadioButton::create(Theme::Style* style, Properties* properties)
 {
+    GP_ASSERT(properties);
+
     RadioButton* radioButton = new RadioButton();
     radioButton->initialize(style, properties);
 
@@ -67,8 +69,7 @@ void RadioButton::addListener(Control::Listener* listener, int eventFlags)
 {
     if ((eventFlags & Listener::TEXT_CHANGED) == Listener::TEXT_CHANGED)
     {
-        assert("TEXT_CHANGED event is not applicable to RadioButton.");
-        eventFlags &= ~Listener::TEXT_CHANGED;
+        GP_ERROR("TEXT_CHANGED event is not applicable to RadioButton.");
     }
 
     Control::addListener(listener, eventFlags);
@@ -111,6 +112,7 @@ void RadioButton::clearSelected(const std::string& groupId)
     for (it = __radioButtons.begin(); it < __radioButtons.end(); it++)
     {
         RadioButton* radioButton = *it;
+        GP_ASSERT(radioButton);
         if (groupId == radioButton->_groupId)
         {
             radioButton->_selected = false;
@@ -159,6 +161,9 @@ void RadioButton::update(const Rectangle& clip, const Vector2& offset)
 
 void RadioButton::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
 {
+    GP_ASSERT(spriteBatch);
+    GP_ASSERT(_image);
+
     // Left, v-center.
     // TODO: Set an alignment for radio button images.   
     const Rectangle& region = _image->getRegion();

+ 4 - 4
gameplay/src/RenderState.cpp

@@ -52,7 +52,7 @@ void RenderState::finalize()
 
 MaterialParameter* RenderState::getParameter(const char* name) const
 {
-    assert(name);
+    GP_ASSERT(name);
 
     MaterialParameter* param;
 
@@ -492,13 +492,13 @@ RenderState::Blend parseBlend(const char* value)
     if (upper == "SRC_ALPHA_SATURATE")
         return RenderState::BLEND_SRC_ALPHA_SATURATE;
 
-    WARN_VARG("Warning: Unrecognized blend value (%s), defaulting to BLEND_ONE.", value);
+    GP_WARN("Warning: Unrecognized blend value (%s), defaulting to BLEND_ONE.", value);
     return RenderState::BLEND_ONE;
 }
 
 void RenderState::StateBlock::setState(const char* name, const char* value)
 {
-    assert(name && value);
+    GP_ASSERT(name && value);
 
     if (strcmp(name, "blend") == 0)
     {
@@ -526,7 +526,7 @@ void RenderState::StateBlock::setState(const char* name, const char* value)
     }
     else
     {
-        WARN_VARG("Warning: Invalid render state: %s", name);
+        GP_WARN("Warning: Invalid render state: %s", name);
     }
 }
 

+ 4 - 4
gameplay/src/Scene.cpp

@@ -59,7 +59,7 @@ void Scene::setId(const char* id)
 
 Node* Scene::findNode(const char* id, bool recursive, bool exactMatch) const
 {
-    assert(id);
+    GP_ASSERT(id);
 
     // Search immediate children first.
     for (Node* child = getFirstNode(); child != NULL; child = child->getNextSibling())
@@ -89,7 +89,7 @@ Node* Scene::findNode(const char* id, bool recursive, bool exactMatch) const
 
 unsigned int Scene::findNodes(const char* id, std::vector<Node*>& nodes, bool recursive, bool exactMatch) const
 {
-    assert(id);
+    GP_ASSERT(id);
 
     unsigned int count = 0;
 
@@ -129,7 +129,7 @@ Node* Scene::addNode(const char* id)
 
 void Scene::addNode(Node* node)
 {
-    assert(node);
+    GP_ASSERT(node);
 
     if (node->_scene == this)
     {
@@ -180,7 +180,7 @@ void Scene::addNode(Node* node)
 
 void Scene::removeNode(Node* node)
 {
-    assert(node);
+    GP_ASSERT(node);
 
     if (node->_scene != this)
         return;

+ 44 - 44
gameplay/src/SceneLoader.cpp

@@ -13,23 +13,23 @@ std::string SceneLoader::_path;
 
 Scene* SceneLoader::load(const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
 
     // Load the scene properties from file.
     Properties* properties = Properties::create(url);
-    assert(properties);
+    GP_ASSERT(properties);
     if (properties == NULL)
     {
-        WARN_VARG("Failed to load scene file: %s", url);
+        GP_WARN("Failed to load scene file: %s", url);
         return NULL;
     }
 
     // Check if the properties object is valid and has a valid namespace.
     Properties* sceneProperties = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
-    assert(sceneProperties);
+    GP_ASSERT(sceneProperties);
     if (!sceneProperties || !(strcmp(sceneProperties->getNamespace(), "scene") == 0))
     {
-        WARN("Failed to load scene from properties object: must be non-null object and have namespace equal to 'scene'.");
+        GP_WARN("Failed to load scene from properties object: must be non-null object and have namespace equal to 'scene'.");
         SAFE_DELETE(properties);
         return NULL;
     }
@@ -159,7 +159,7 @@ void SceneLoader::applyNodeProperties(const Scene* scene, const Properties* scen
             Node* node = scene->findNode(sceneNode._nodeID);
             if (!node)
             {
-                WARN_VARG("Attempting to set a property for node '%s', which does not exist in the scene.", sceneNode._nodeID);
+                GP_WARN("Attempting to set a property for node '%s', which does not exist in the scene.", sceneNode._nodeID);
                 continue;
             }
 
@@ -204,7 +204,7 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
         Properties* p = _propertiesFromFile[snp._file];
         if (!p)
         {
-            WARN_VARG("The referenced node data in file '%s' failed to load.", snp._file.c_str());
+            GP_WARN("The referenced node data in file '%s' failed to load.", snp._file.c_str());
             return;
         }
 
@@ -214,7 +214,7 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
             p = p->getNamespace(snp._id.c_str());
             if (!p)
             {
-                WARN_VARG("The referenced node data at '%s#%s' failed to load.", snp._file.c_str(), snp._id.c_str());
+                GP_WARN("The referenced node data at '%s#%s' failed to load.", snp._file.c_str(), snp._id.c_str());
                 return;
             }
         }
@@ -236,7 +236,7 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
         }
         case SceneNodeProperty::MATERIAL:
             if (!node->getModel())
-                WARN_VARG("Attempting to set a material on node '%s', which has no model.", sceneNode._nodeID);
+                GP_WARN("Attempting to set a material on node '%s', which has no model.", sceneNode._nodeID);
             else
             {
                 Material* material = Material::create(p);
@@ -259,7 +259,7 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
             Properties* p = _propertiesFromFile[snp._file];
             if (!p)
             {
-                WARN_VARG("The referenced node data in file '%s' failed to load.", snp._file.c_str());
+                GP_WARN("The referenced node data in file '%s' failed to load.", snp._file.c_str());
                 return;
             }
 
@@ -269,7 +269,7 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
                 p = p->getNamespace(snp._id.c_str());
                 if (!p)
                 {
-                    WARN_VARG("The referenced node data at '%s#%s' failed to load.", snp._file.c_str(), snp._id.c_str());
+                    GP_WARN("The referenced node data at '%s#%s' failed to load.", snp._file.c_str(), snp._id.c_str());
                     return;
                 }
             }
@@ -283,15 +283,15 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
             // Check to make sure the type of the namespace used to load the physics collision object is correct.
             if (snp._type == SceneNodeProperty::CHARACTER && strcmp(p->getNamespace(), "character") != 0)
             {
-                WARN_VARG("Attempting to set a 'character' (physics collision object attribute) on a node using a '%s' definition.", p->getNamespace());
+                GP_WARN("Attempting to set a 'character' (physics collision object attribute) on a node using a '%s' definition.", p->getNamespace());
             }
             else if (snp._type == SceneNodeProperty::GHOSTOBJECT && strcmp(p->getNamespace(), "ghostObject") != 0)
             {
-                WARN_VARG("Attempting to set a 'ghostObject' (physics collision object attribute) on a node using a '%s' definition.", p->getNamespace());
+                GP_WARN("Attempting to set a 'ghostObject' (physics collision object attribute) on a node using a '%s' definition.", p->getNamespace());
             }
             else if (snp._type == SceneNodeProperty::RIGIDBODY && strcmp(p->getNamespace(), "rigidBody") != 0)
             {
-                WARN_VARG("Attempting to set a 'rigidBody' (physics collision object attribute) on a node using a '%s' definition.", p->getNamespace());
+                GP_WARN("Attempting to set a 'rigidBody' (physics collision object attribute) on a node using a '%s' definition.", p->getNamespace());
             }
             else
             {
@@ -302,16 +302,16 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
                 {
                     Node* modelNode = node->getScene()->findNode(name);
                     if (!modelNode)
-                        WARN_VARG("Node '%s' does not exist; attempting to use its model for collision object creation.", name);
+                        GP_WARN("Node '%s' does not exist; attempting to use its model for collision object creation.", name);
                     else
                     {
                         if (!modelNode->getModel())
-                            WARN_VARG("Node '%s' does not have a model; attempting to use its model for collision object creation.", name);
+                            GP_WARN("Node '%s' does not have a model; attempting to use its model for collision object creation.", name);
                         else
                         {
                             // Temporarily set rigidBody model on model so it's used during collision object creation.
                             Model* model = node->getModel();
-                            assert(model);
+                            GP_ASSERT(model);
                         
                             // Up ref count to prevent node from releasing the model when we swap it.
                             model->addRef(); 
@@ -378,7 +378,7 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
             break;
         }
         default:
-            WARN_VARG("Unsupported node property type: %d.", snp._type);
+            GP_WARN("Unsupported node property type: %d.", snp._type);
             break;
         }
     }
@@ -415,7 +415,7 @@ void SceneLoader::applyNodeUrls(Scene* scene)
                     }
                     else
                     {
-                        WARN_VARG("Could not find node '%s' in main scene GPB file.", snp._id.c_str());
+                        GP_WARN("Could not find node '%s' in main scene GPB file.", snp._id.c_str());
                     }
                 }
                 else
@@ -437,7 +437,7 @@ void SceneLoader::applyNodeUrls(Scene* scene)
                     }
                     else
                     {
-                        WARN_VARG("Could not find any nodes matching '%s' in main scene GPB file.", snp._id.c_str());
+                        GP_WARN("Could not find any nodes matching '%s' in main scene GPB file.", snp._id.c_str());
                     }
                 }
             }
@@ -462,7 +462,7 @@ void SceneLoader::applyNodeUrls(Scene* scene)
                         }
                         else
                         {
-                            WARN_VARG("Could not load node '%s' in GPB file '%s'.", snp._id.c_str(), snp._file.c_str());
+                            GP_WARN("Could not load node '%s' in GPB file '%s'.", snp._id.c_str(), snp._file.c_str());
                         }
                     }
                     else
@@ -493,7 +493,7 @@ void SceneLoader::applyNodeUrls(Scene* scene)
                         }
                         if (matchCount == 0)
                         {
-                            WARN_VARG("Could not find any nodes matching '%s' in GPB file '%s'.", snp._id.c_str(), snp._file.c_str());
+                            GP_WARN("Could not find any nodes matching '%s' in GPB file '%s'.", snp._id.c_str(), snp._file.c_str());
                         }
                     }
 
@@ -501,7 +501,7 @@ void SceneLoader::applyNodeUrls(Scene* scene)
                 }
                 else
                 {
-                    WARN_VARG("Failed to load GPB file '%s' for node stitching.", snp._file.c_str());
+                    GP_WARN("Failed to load GPB file '%s' for node stitching.", snp._file.c_str());
                 }
             }
 
@@ -522,7 +522,7 @@ void SceneLoader::buildReferenceTables(Properties* sceneProperties)
         {
             if (strlen(ns->getId()) == 0)
             {
-                WARN("Nodes must have an ID; skipping the current node.");
+                GP_WARN("Nodes must have an ID; skipping the current node.");
                 continue;
             }
 
@@ -595,7 +595,7 @@ void SceneLoader::buildReferenceTables(Properties* sceneProperties)
                 }
                 else
                 {
-                    WARN_VARG("Unsupported node property: %s = %s", name, ns->getString());
+                    GP_WARN("Unsupported node property: %s = %s", name, ns->getString());
                 }
             }
         }
@@ -610,20 +610,20 @@ void SceneLoader::buildReferenceTables(Properties* sceneProperties)
                     const char* animationID = animation->getId();
                     if (strlen(animationID) == 0)
                     {
-                        WARN("Animations must have an ID; skipping the current animation.");
+                        GP_WARN("Animations must have an ID; skipping the current animation.");
                         continue;
                     }
 
                     const char* url = animation->getString("url");
                     if (!url)
                     {
-                        WARN_VARG("Animations must have a URL; skipping animation '%s'.", animationID);
+                        GP_WARN("Animations must have a URL; skipping animation '%s'.", animationID);
                         continue;
                     }
                     const char* targetID = animation->getString("target");
                     if (!targetID)
                     {
-                        WARN_VARG("Animations must have a target; skipping animation '%s'.", animationID);
+                        GP_WARN("Animations must have a target; skipping animation '%s'.", animationID);
                         continue;
                     }
 
@@ -631,7 +631,7 @@ void SceneLoader::buildReferenceTables(Properties* sceneProperties)
                 }
                 else
                 {
-                    WARN_VARG("Unsupported child namespace (of 'animations'): %s", ns->getNamespace());
+                    GP_WARN("Unsupported child namespace (of 'animations'): %s", ns->getNamespace());
                 }
             }
         }
@@ -643,7 +643,7 @@ void SceneLoader::buildReferenceTables(Properties* sceneProperties)
         else
         {
             // TODO: Should we ignore these items? They could be used for generic properties file inheritance.
-            WARN_VARG("Unsupported child namespace (of 'scene'): %s", ns->getNamespace());
+            GP_WARN("Unsupported child namespace (of 'scene'): %s", ns->getNamespace());
         }
     }
 }
@@ -658,7 +658,7 @@ void SceneLoader::createAnimations(const Scene* scene)
         Node* node = scene->findNode(_animations[i]._targetID);
         if (!node)
         {
-            WARN_VARG("Attempting to create an animation targeting node '%s', which does not exist in the scene.", _animations[i]._targetID);
+            GP_WARN("Attempting to create an animation targeting node '%s', which does not exist in the scene.", _animations[i]._targetID);
             continue;
         }
 
@@ -666,7 +666,7 @@ void SceneLoader::createAnimations(const Scene* scene)
         Properties* p = _propertiesFromFile[_animations[i]._file];
         if (!p)
         {
-            WARN_VARG("The referenced animation data in file '%s' failed to load.", _animations[i]._file.c_str());
+            GP_WARN("The referenced animation data in file '%s' failed to load.", _animations[i]._file.c_str());
             continue;
         }
         if (_animations[i]._id.size() > 0)
@@ -674,7 +674,7 @@ void SceneLoader::createAnimations(const Scene* scene)
             p = p->getNamespace(_animations[i]._id.c_str());
             if (!p)
             {
-                WARN_VARG("The referenced animation data at '%s#%s' failed to load.", _animations[i]._file.c_str(), _animations[i]._id.c_str());
+                GP_WARN("The referenced animation data at '%s#%s' failed to load.", _animations[i]._file.c_str(), _animations[i]._id.c_str());
                 continue;
             }
         }
@@ -769,7 +769,7 @@ Scene* SceneLoader::loadMainSceneData(const Properties* sceneProperties)
     Bundle* bundle = Bundle::create(_path.c_str());
     if (!bundle)
     {
-        WARN_VARG("Failed to load scene GPB file '%s'.", _path.c_str());
+        GP_WARN("Failed to load scene GPB file '%s'.", _path.c_str());
         return NULL;
     }
 
@@ -777,7 +777,7 @@ Scene* SceneLoader::loadMainSceneData(const Properties* sceneProperties)
     Scene* scene = bundle->loadScene(NULL);
     if (!scene)
     {
-        WARN_VARG("Failed to load scene from '%s'.", _path.c_str());
+        GP_WARN("Failed to load scene from '%s'.", _path.c_str());
         SAFE_RELEASE(bundle);
         return NULL;
     }
@@ -816,18 +816,18 @@ void SceneLoader::loadPhysics(Properties* physics, Scene* scene)
             name = constraint->getString("rigidBodyA");
             if (!name)
             {
-                WARN_VARG("Missing property 'rigidBodyA' for constraint %s", constraint->getId());
+                GP_WARN("Missing property 'rigidBodyA' for constraint %s", constraint->getId());
                 continue;
             }
             Node* rbANode = scene->findNode(name);
             if (!rbANode)
             {
-                WARN_VARG("Node '%s' to be used as 'rigidBodyA' for constraint %s cannot be found.", name, constraint->getId());
+                GP_WARN("Node '%s' to be used as 'rigidBodyA' for constraint %s cannot be found.", name, constraint->getId());
                 continue;
             }
             if (!rbANode->getCollisionObject() || rbANode->getCollisionObject()->getType() != PhysicsCollisionObject::RIGID_BODY)
             {
-                WARN_VARG("Node '%s' to be used as 'rigidBodyA' does not have a rigid body.", name);
+                GP_WARN("Node '%s' to be used as 'rigidBodyA' does not have a rigid body.", name);
                 continue;
             }
             PhysicsRigidBody* rbA = static_cast<PhysicsRigidBody*>(rbANode->getCollisionObject());
@@ -843,12 +843,12 @@ void SceneLoader::loadPhysics(Properties* physics, Scene* scene)
                 Node* rbBNode = scene->findNode(name);
                 if (!rbBNode)
                 {
-                    WARN_VARG("Node '%s' to be used as 'rigidBodyB' for constraint %s cannot be found.", name, constraint->getId());
+                    GP_WARN("Node '%s' to be used as 'rigidBodyB' for constraint %s cannot be found.", name, constraint->getId());
                     continue;
                 }
                 if (!rbBNode->getCollisionObject() || rbBNode->getCollisionObject()->getType() != PhysicsCollisionObject::RIGID_BODY)
                 {
-                    WARN_VARG("Node '%s' to be used as 'rigidBodyB' does not have a rigid body.", name);
+                    GP_WARN("Node '%s' to be used as 'rigidBodyB' does not have a rigid body.", name);
                     continue;
                 }
                 rbB = static_cast<PhysicsRigidBody*>(rbBNode->getCollisionObject());
@@ -888,7 +888,7 @@ void SceneLoader::loadPhysics(Properties* physics, Scene* scene)
         }
         else
         {
-            WARN_VARG("Unsupported child namespace (of 'physics'): %s", physics->getNamespace());
+            GP_WARN("Unsupported child namespace (of 'physics'): %s", physics->getNamespace());
         }
     }
 }
@@ -900,9 +900,9 @@ void SceneLoader::loadReferencedFiles()
     for (; iter != _propertiesFromFile.end(); iter++)
     {
         Properties* p = Properties::create(iter->first.c_str());
-        assert(p);
+        GP_ASSERT(p);
         if (p == NULL)
-            WARN_VARG("Failed to load referenced file: %s", iter->first.c_str());
+            GP_WARN("Failed to load referenced file: %s", iter->first.c_str());
 
         iter->second = p;
     }
@@ -940,7 +940,7 @@ PhysicsConstraint* SceneLoader::loadSpringConstraint(const Properties* constrain
 {
     if (!rbB)
     {
-        WARN("Spring constraints require two rigid bodies.");
+        GP_WARN("Spring constraints require two rigid bodies.");
         return NULL;
     }
 

+ 9 - 0
gameplay/src/ScreenDisplayer.h

@@ -14,6 +14,11 @@ class ScreenDisplayer
 {
 public:
 
+	/**
+	 * Constructor.
+	 */
+	ScreenDisplayer();
+
     /**
      * Displays a screen using the {@link Game#renderOnce} mechanism for at least the given amount of time.
      * 
@@ -35,6 +40,10 @@ private:
     long _startTime;
 };
 
+inline ScreenDisplayer::ScreenDisplayer() : _time(0L), _startTime(0L)
+{
+}
+
 template <typename T> void ScreenDisplayer::run(T* instance, void (T::*method) (void*), void* cookie, long time)
 {
     _time = time;

+ 9 - 2
gameplay/src/Slider.cpp

@@ -13,6 +13,8 @@ Slider::~Slider()
 
 Slider* Slider::create(Theme::Style* style, Properties* properties)
 {
+    GP_ASSERT(properties);
+
     Slider* slider = new Slider();
     slider->initialize(style, properties);
 
@@ -68,8 +70,7 @@ void Slider::addListener(Control::Listener* listener, int eventFlags)
 {
     if ((eventFlags & Listener::TEXT_CHANGED) == Listener::TEXT_CHANGED)
     {
-        assert("TEXT_CHANGED event is not applicable to Slider.");
-        eventFlags &= ~Listener::TEXT_CHANGED;
+        GP_ERROR("TEXT_CHANGED event is not applicable to Slider.");
     }
 
     Control::addListener(listener, eventFlags);
@@ -152,6 +153,12 @@ void Slider::update(const Rectangle& clip, const Vector2& offset)
 
 void Slider::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
 {
+    GP_ASSERT(spriteBatch);
+    GP_ASSERT(_minImage);
+    GP_ASSERT(_maxImage);
+    GP_ASSERT(_markerImage);
+    GP_ASSERT(_trackImage);
+
     // TODO: Vertical slider.
 
     // The slider is drawn in the center of the control (perpendicular to orientation).

+ 3 - 3
gameplay/src/SpriteBatch.cpp

@@ -83,7 +83,7 @@ SpriteBatch* SpriteBatch::create(const char* texturePath, Effect* effect, unsign
 
 SpriteBatch* SpriteBatch::create(Texture* texture, Effect* effect, unsigned int initialCapacity)
 {
-    assert(texture != NULL);
+    GP_ASSERT(texture != NULL);
 
     bool customEffect = (effect != NULL);
     if (!customEffect)
@@ -94,7 +94,7 @@ SpriteBatch* SpriteBatch::create(Texture* texture, Effect* effect, unsigned int
             __spriteEffect = Effect::createFromSource(SPRITE_VSH, SPRITE_FSH);
             if (__spriteEffect == NULL)
             {
-                LOG_ERROR("Unable to load sprite effect.");
+                GP_ERROR("Unable to load sprite effect.");
                 return NULL;
             }
 
@@ -120,7 +120,7 @@ SpriteBatch* SpriteBatch::create(Texture* texture, Effect* effect, unsigned int
     }
     if (!samplerUniform)
     {
-        LOG_ERROR("No uniform of type GL_SAMPLER_2D found in sprite effect.");
+        GP_ERROR("No uniform of type GL_SAMPLER_2D found in sprite effect.");
         SAFE_RELEASE(effect);
         return NULL;
     }

+ 2 - 2
gameplay/src/Technique.cpp

@@ -9,7 +9,7 @@ namespace gameplay
 Technique::Technique(const char* id, Material* material)
     : _id(id ? id : ""), _material(material)
 {
-    assert(material);
+    GP_ASSERT(material);
 
     RenderState::_parent = material;
 }
@@ -35,7 +35,7 @@ unsigned int Technique::getPassCount() const
 
 Pass* Technique::getPass(unsigned int index) const
 {
-    assert(index < _passes.size());
+    GP_ASSERT(index < _passes.size());
 
     return _passes[index];
 }

+ 9 - 2
gameplay/src/TextBox.cpp

@@ -33,8 +33,7 @@ void TextBox::addListener(Control::Listener* listener, int eventFlags)
 {
     if ((eventFlags & Listener::VALUE_CHANGED) == Listener::VALUE_CHANGED)
     {
-        assert("VALUE_CHANGED event is not applicable to TextBox.");
-        eventFlags &= ~Listener::VALUE_CHANGED;
+        GP_ERROR("VALUE_CHANGED event is not applicable to TextBox.");
     }
 
     Control::addListener(listener, eventFlags);
@@ -131,6 +130,7 @@ void TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                     case Keyboard::KEY_DELETE:
                     {
                         Font* font = getFont(_state);
+                        GP_ASSERT(font);
                         unsigned int fontSize = getFontSize(_state);
                         Font::Justify textAlignment = getTextAlignment(_state);
                         bool rightToLeft = getTextRightToLeft(_state);
@@ -148,6 +148,7 @@ void TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                     case Keyboard::KEY_LEFT_ARROW:
                     {
                         Font* font = getFont(_state);
+                        GP_ASSERT(font);
                         unsigned int fontSize = getFontSize(_state);
                         Font::Justify textAlignment = getTextAlignment(_state);
                         bool rightToLeft = getTextRightToLeft(_state);
@@ -162,6 +163,7 @@ void TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                     case Keyboard::KEY_RIGHT_ARROW:
                     {
                         Font* font = getFont(_state);
+                        GP_ASSERT(font);
                         unsigned int fontSize = getFontSize(_state);
                         Font::Justify textAlignment = getTextAlignment(_state);
                         bool rightToLeft = getTextRightToLeft(_state);
@@ -176,6 +178,7 @@ void TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                     case Keyboard::KEY_UP_ARROW:
                     {
                         Font* font = getFont(_state);
+                        GP_ASSERT(font);
                         unsigned int fontSize = getFontSize(_state);
                         Font::Justify textAlignment = getTextAlignment(_state);
                         bool rightToLeft = getTextRightToLeft(_state);
@@ -189,6 +192,7 @@ void TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                     case Keyboard::KEY_DOWN_ARROW:
                     {
                         Font* font = getFont(_state);
+                        GP_ASSERT(font);
                         unsigned int fontSize = getFontSize(_state);
                         Font::Justify textAlignment = getTextAlignment(_state);
                         bool rightToLeft = getTextRightToLeft(_state);
@@ -206,6 +210,7 @@ void TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
             case Keyboard::KEY_CHAR:
             {
                 Font* font = getFont(_state);
+                GP_ASSERT(font);
                 unsigned int fontSize = getFontSize(_state);
                 Font::Justify textAlignment = getTextAlignment(_state);
                 bool rightToLeft = getTextRightToLeft(_state);
@@ -299,9 +304,11 @@ void TextBox::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
     if (_state == FOCUS)
     {
         // Draw the cursor at its current location.
+        GP_ASSERT(_caretImage);
         const Rectangle& region = _caretImage->getRegion();
         if (!region.isEmpty())
         {
+            GP_ASSERT(spriteBatch);
             const Theme::UVs uvs = _caretImage->getUVs();
             Vector4 color = _caretImage->getColor();
             color.w *= _opacity;

+ 9 - 9
gameplay/src/Texture.cpp

@@ -97,7 +97,7 @@ Texture* Texture::create(const char* path, bool generateMipmaps)
         return texture;
     }
 
-    LOG_ERROR_VARG("Failed to load texture: %s", path);
+    GP_ERROR("Failed to load texture: %s", path);
     return NULL;
 }
 
@@ -178,7 +178,7 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     FILE* file = FileSystem::openFile(path, "rb");
     if (file == NULL)
     {
-        LOG_ERROR_VARG("Failed to load file: %s", path);
+        GP_ERROR("Failed to load file: %s", path);
         return NULL;
     }
 
@@ -186,10 +186,10 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     unsigned int size = sizeof(pvrtc_file_header);
     pvrtc_file_header header;
     unsigned int read = (int)fread(&header, 1, size, file);
-    assert(read == size);
+    GP_ASSERT(read == size);
     if (read != size)
     {
-        LOG_ERROR_VARG("Read file header error for pvrtc file: %s (%d < %d)", path, (int)read, (int)size);
+        GP_ERROR("Read file header error for pvrtc file: %s (%d < %d)", path, (int)read, (int)size);
         fclose(file);
         return NULL;
     }
@@ -200,7 +200,7 @@ Texture* Texture::createCompressedPVRTC(const char* path)
         PVRTCIdentifier[2] != (char)((header.pvrtcTag >> 16) & 0xff) ||
         PVRTCIdentifier[3] != (char)((header.pvrtcTag >> 24) & 0xff))
      {
-        LOG_ERROR_VARG("Invalid PVRTC compressed texture file: %s", path);
+        GP_ERROR("Invalid PVRTC compressed texture file: %s", path);
         fclose(file);
         return NULL;
     }
@@ -218,17 +218,17 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     }
     else
     {
-        LOG_ERROR_VARG("Invalid PVRTC compressed texture format flags for file: %s", path);
+        GP_ERROR("Invalid PVRTC compressed texture format flags for file: %s", path);
         fclose(file);
         return NULL;
     }
 
     unsigned char* data = new unsigned char[header.dataSize];
     read = (int)fread(data, 1, header.dataSize, file);
-    assert(read == header.dataSize);
+    GP_ASSERT(read == header.dataSize);
     if (read != header.dataSize)
     {
-        LOG_ERROR_VARG("Read file data error for pvrtc file: %s (%d < %d)", path, (int)read, (int)header.dataSize);
+        GP_ERROR("Read file data error for pvrtc file: %s (%d < %d)", path, (int)read, (int)header.dataSize);
         SAFE_DELETE_ARRAY(data);
         fclose(file);
         return NULL;
@@ -348,7 +348,7 @@ Texture::Sampler::~Sampler()
 
 Texture::Sampler* Texture::Sampler::create(Texture* texture)
 {
-    assert(texture != NULL);
+    GP_ASSERT(texture != NULL);
 
     texture->addRef();
     return new Sampler(texture);

+ 68 - 27
gameplay/src/Theme.cpp

@@ -55,7 +55,7 @@ Theme::~Theme()
 
 Theme* Theme::create(const char* url)
 {
-    assert(url);
+    GP_ASSERT(url);
 
     // Search theme cache first.
     for (unsigned int i = 0, count = __themeCache.size(); i < count; ++i)
@@ -72,7 +72,7 @@ Theme* Theme::create(const char* url)
 
     // Load theme properties from file path.
     Properties* properties = Properties::create(url);
-    assert(properties);
+    GP_ASSERT(properties);
     if (properties == NULL)
     {
         return NULL;
@@ -80,7 +80,7 @@ Theme* Theme::create(const char* url)
 
     // Check if the Properties is valid and has a valid namespace.
     Properties* themeProperties = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
-    assert(themeProperties);
+    GP_ASSERT(themeProperties);
     if (!themeProperties || !(strcmp(themeProperties->getNamespace(), "theme") == 0))
     {
         SAFE_DELETE(properties);
@@ -94,7 +94,9 @@ Theme* Theme::create(const char* url)
     // Parse the Properties object and set up the theme.
     const char* textureFile = themeProperties->getString("texture");
     theme->_texture = Texture::create(textureFile, false);
+    GP_ASSERT(theme->_texture);
     theme->_spriteBatch = SpriteBatch::create(theme->_texture);
+    GP_ASSERT(theme->_spriteBatch);
 
     float tw = 1.0f / theme->_texture->getWidth();
     float th = 1.0f / theme->_texture->getHeight();
@@ -140,6 +142,7 @@ Theme* Theme::create(const char* url)
             }
 
             Skin* skin = Skin::create(space->getId(), tw, th, region, border, color);
+            GP_ASSERT(skin);
             theme->_skins.push_back(skin);
         }
 
@@ -202,6 +205,7 @@ Theme* Theme::create(const char* url)
                     theme->lookUpSprites(innerSpace, &imageList, &cursor, &skin);
 
                     normal = Theme::Style::Overlay::create();
+                    GP_ASSERT(normal);
                     normal->setSkin(skin);
                     normal->setCursor(cursor);
                     normal->setImageList(imageList);
@@ -212,9 +216,11 @@ Theme* Theme::create(const char* url)
                     normal->setTextRightToLeft(rightToLeft);
                     normal->setOpacity(opacity);
 
-                    theme->_fonts.insert(font);
-
-                    if (font) font->release();
+                    if (font)
+                    {
+                        theme->_fonts.insert(font);
+                        font->release();
+                    }
 
                     // Done with this pass.
                     break;
@@ -224,7 +230,8 @@ Theme* Theme::create(const char* url)
             }
 
             // At least the OVERLAY_NORMAL is required.
-            assert(normal);
+            if (!normal)
+                GP_ERROR("All themes require the normal state overlay to be defined.");
 
             space->rewind();
             innerSpace = space->getNextNamespace();
@@ -330,6 +337,7 @@ Theme* Theme::create(const char* url)
                     if (strcmp(innerSpacename, "stateFocus") == 0)
                     {
                         focus = Theme::Style::Overlay::create();
+                        GP_ASSERT(focus);
                         focus->setSkin(skin);
                         focus->setCursor(cursor);
                         focus->setImageList(imageList);
@@ -340,11 +348,13 @@ Theme* Theme::create(const char* url)
                         focus->setTextRightToLeft(rightToLeft);
                         focus->setOpacity(opacity);
 
-                        theme->_fonts.insert(font);
+                        if (font)
+                            theme->_fonts.insert(font);
                     }
                     else if (strcmp(innerSpacename, "stateActive") == 0)
                     {
                         active = Theme::Style::Overlay::create();
+                        GP_ASSERT(active);
                         active->setSkin(skin);
                         active->setCursor(cursor);
                         active->setImageList(imageList);
@@ -355,11 +365,13 @@ Theme* Theme::create(const char* url)
                         active->setTextRightToLeft(rightToLeft);
                         active->setOpacity(opacity);
 
-                        theme->_fonts.insert(font);
+                        if (font)
+                            theme->_fonts.insert(font);
                     }
                     else if (strcmp(innerSpacename, "stateDisabled") == 0)
                     {
                         disabled = Theme::Style::Overlay::create();
+                        GP_ASSERT(disabled);
                         disabled->setSkin(skin);
                         disabled->setCursor(cursor);
                         disabled->setImageList(imageList);
@@ -370,7 +382,8 @@ Theme* Theme::create(const char* url)
                         disabled->setTextRightToLeft(rightToLeft);
                         disabled->setOpacity(opacity);
 
-                        theme->_fonts.insert(font);
+                        if (font)
+                            theme->_fonts.insert(font);
                     }
                 }
 
@@ -396,6 +409,7 @@ Theme* Theme::create(const char* url)
             }
 
             Theme::Style* s = new Theme::Style(theme, space->getId(), tw, th, margin, padding, normal, focus, active, disabled);
+            GP_ASSERT(s);
             theme->_styles.push_back(s);
         }
 
@@ -412,8 +426,11 @@ Theme* Theme::create(const char* url)
 
 Theme::Style* Theme::getStyle(const char* name) const
 {
+    GP_ASSERT(name);
+
     for (unsigned int i = 0, count = _styles.size(); i < count; ++i)
     {
+        GP_ASSERT(_styles[i]);
         if (strcmp(name, _styles[i]->getId()) == 0)
         {
             return _styles[i];
@@ -425,6 +442,7 @@ Theme::Style* Theme::getStyle(const char* name) const
 
 void Theme::setProjectionMatrix(const Matrix& matrix)
 {
+    GP_ASSERT(_spriteBatch);
     _spriteBatch->setProjectionMatrix(matrix);
 
     // Set the matrix on each Font used by the style.
@@ -432,8 +450,9 @@ void Theme::setProjectionMatrix(const Matrix& matrix)
     for (it = _fonts.begin(); it != _fonts.end(); ++it)
     {
         Font* font = *it;
-        if (font)
-            font->getSpriteBatch()->setProjectionMatrix(matrix);
+        GP_ASSERT(font);
+        GP_ASSERT(font->getSpriteBatch());
+        font->getSpriteBatch()->setProjectionMatrix(matrix);
     }
 }
 
@@ -443,8 +462,8 @@ SpriteBatch* Theme::getSpriteBatch() const
 }
 
 /**************
-    * Theme::UVs *
-    **************/
+ * Theme::UVs *
+ **************/
 Theme::UVs::UVs()
     : u1(0), v1(0), u2(0), v2(0)
 {
@@ -462,17 +481,17 @@ const Theme::UVs& Theme::UVs::empty()
 }
 
 /**********************
-    * Theme::SideRegions *
-    **********************/
+ * Theme::SideRegions *
+ **********************/
 const Theme::SideRegions& Theme::SideRegions::empty()
 {
     static SideRegions empty;
     return empty;
 }
 
-/****************
-    * Theme::ThemeImage *
-    ****************/
+/*********************
+ * Theme::ThemeImage *
+ *********************/
 Theme::ThemeImage::ThemeImage(float tw, float th, const Rectangle& region, const Vector4& color)
     : _region(region), _color(color)
 {
@@ -485,6 +504,8 @@ Theme::ThemeImage::~ThemeImage()
 
 Theme::ThemeImage* Theme::ThemeImage::create(float tw, float th, Properties* properties, const Vector4& defaultColor)
 {
+    GP_ASSERT(properties);
+
     Vector4 regionVector;                
     properties->getVector4("region", &regionVector);
     const Rectangle region(regionVector.x, regionVector.y, regionVector.z, regionVector.w);
@@ -530,8 +551,8 @@ const Vector4& Theme::ThemeImage::getColor() const
 }
 
 /********************
-    * Theme::ImageList *
-    ********************/
+ * Theme::ImageList *
+ ********************/
 Theme::ImageList::ImageList(const Vector4& color) : _color(color)
 {
 }
@@ -545,6 +566,7 @@ Theme::ImageList::ImageList(const ImageList& copy)
     for (it = copy._images.begin(); it != copy._images.end(); it++)
     {
         ThemeImage* image = *it;
+        GP_ASSERT(image);
         _images.push_back(new ThemeImage(*image));
     }
 }
@@ -561,6 +583,8 @@ Theme::ImageList::~ImageList()
 
 Theme::ImageList* Theme::ImageList::create(float tw, float th, Properties* properties)
 {
+    GP_ASSERT(properties);
+
     Vector4 color(1, 1, 1, 1);
     if (properties->exists("color"))
     {
@@ -579,6 +603,7 @@ Theme::ImageList* Theme::ImageList::create(float tw, float th, Properties* prope
     while (space != NULL)
     {
         ThemeImage* image = ThemeImage::create(tw, th, space, color);
+        GP_ASSERT(image);
         imageList->_images.push_back(image);
         space = properties->getNextNamespace();
     }
@@ -593,10 +618,14 @@ const char* Theme::ImageList::getId() const
 
 Theme::ThemeImage* Theme::ImageList::getImage(const char* imageId) const
 {
+    GP_ASSERT(imageId);
+
     std::vector<ThemeImage*>::const_iterator it;
     for (it = _images.begin(); it != _images.end(); it++)
     {
         ThemeImage* image = *it;
+        GP_ASSERT(image);
+        GP_ASSERT(image->getId());
         if (strcmp(image->getId(), imageId) == 0)
         {
             return image;
@@ -607,8 +636,8 @@ Theme::ThemeImage* Theme::ImageList::getImage(const char* imageId) const
 }
 
 /***************
-    * Theme::Skin *
-    ***************/
+ * Theme::Skin *
+ ***************/
 Theme::Skin* Theme::Skin::create(const char* id, float tw, float th, const Rectangle& region, const Theme::Border& border, const Vector4& color)
 {
     Skin* skin = new Skin(tw, th, region, border, color);
@@ -717,25 +746,31 @@ const Vector4& Theme::Skin::getColor() const
 }
     
 /**
-    * Theme utility methods.
-    */
+ * Theme utility methods.
+ */
 void Theme::generateUVs(float tw, float th, float x, float y, float width, float height, UVs* uvs)
 {
+    GP_ASSERT(uvs);
     uvs->u1 = x * tw;
     uvs->u2 = (x + width) * tw;
     uvs->v1 = 1.0f - (y * th);
     uvs->v2 = 1.0f - ((y + height) * th);
 }
 
-void Theme::lookUpSprites(const Properties* overlaySpace, ImageList** imageList, ThemeImage** cursor, Skin** Skin)
+void Theme::lookUpSprites(const Properties* overlaySpace, ImageList** imageList, ThemeImage** cursor, Skin** skin)
 {
+    GP_ASSERT(overlaySpace);
+
     const char* imageListString = overlaySpace->getString("imageList");
     if (imageListString)
     {
         for (unsigned int i = 0; i < _imageLists.size(); ++i)
         {
+            GP_ASSERT(_imageLists[i]);
+            GP_ASSERT(_imageLists[i]->getId());
             if (strcmp(_imageLists[i]->getId(), imageListString) == 0)
             {
+                GP_ASSERT(imageList);
                 *imageList = _imageLists[i];
                 break;
             }
@@ -747,8 +782,11 @@ void Theme::lookUpSprites(const Properties* overlaySpace, ImageList** imageList,
     {
         for (unsigned int i = 0; i < _images.size(); ++i)
         {
+            GP_ASSERT(_images[i]);
+            GP_ASSERT(_images[i]->getId());
             if (strcmp(_images[i]->getId(), cursorString) == 0)
             {
+                GP_ASSERT(cursor);
                 *cursor = _images[i];
                 break;
             }
@@ -760,9 +798,12 @@ void Theme::lookUpSprites(const Properties* overlaySpace, ImageList** imageList,
     {
         for (unsigned int i = 0; i < _skins.size(); ++i)
         {
+            GP_ASSERT(_skins[i]);
+            GP_ASSERT(_skins[i]->getId());
             if (strcmp(_skins[i]->getId(), skinString) == 0)
             {
-                *Skin = _skins[i];
+                GP_ASSERT(skin);
+                *skin = _skins[i];
                 break;
             }
         }

+ 17 - 6
gameplay/src/ThemeStyle.cpp

@@ -27,6 +27,7 @@ Theme::Style::Style(const Style& copy)
 
     for (int i = 0; i < OVERLAY_MAX; i++)
     {
+        GP_ASSERT(copy._overlays[i]);
         _overlays[i] = new Theme::Style::Overlay(*copy._overlays[i]);
     }
 }
@@ -41,7 +42,7 @@ Theme::Style::~Style()
     
 const char* Theme::Style::getId() const
 {
-    return _id.data();
+    return _id.c_str();
 }
 
 Theme::Style::Overlay* Theme::Style::getOverlay(OverlayType overlayType) const
@@ -177,7 +178,7 @@ const Vector4& Theme::Style::Overlay::getSkinColor() const
 
 void Theme::Style::Overlay::setSkinRegion(const Rectangle& region, float tw, float th)
 {
-    assert(_skin);
+    GP_ASSERT(_skin);
     _skin->setRegion(region, tw, th);
 }
 
@@ -263,6 +264,8 @@ void Theme::Style::Overlay::setTextColor(const Vector4& color)
 
 const Rectangle& Theme::Style::Overlay::getImageRegion(const char* id) const
 {
+    GP_ASSERT(_imageList);
+
     ThemeImage* image = _imageList->getImage(id);
     if (image)
     {
@@ -276,14 +279,16 @@ const Rectangle& Theme::Style::Overlay::getImageRegion(const char* id) const
     
 void Theme::Style::Overlay::setImageRegion(const char* id, const Rectangle& region, float tw, float th)
 {
+    GP_ASSERT(_imageList);
     ThemeImage* image = _imageList->getImage(id);
-    assert(image);
+    GP_ASSERT(image);
     image->_region.set(region);
     generateUVs(tw, th, region.x, region.y, region.width, region.height, &(image->_uvs));
 }
 
 const Vector4& Theme::Style::Overlay::getImageColor(const char* id) const
 {
+    GP_ASSERT(_imageList);
     ThemeImage* image = _imageList->getImage(id);
     if (image)
     {
@@ -297,13 +302,15 @@ const Vector4& Theme::Style::Overlay::getImageColor(const char* id) const
 
 void Theme::Style::Overlay::setImageColor(const char* id, const Vector4& color)
 {
+    GP_ASSERT(_imageList);
     ThemeImage* image = _imageList->getImage(id);
-    assert(image);
+    GP_ASSERT(image);
     image->_color.set(color);
 }
 
 const Theme::UVs& Theme::Style::Overlay::getImageUVs(const char* id) const
 {
+    GP_ASSERT(_imageList);
     ThemeImage* image = _imageList->getImage(id);
     if (image)
     {
@@ -329,7 +336,7 @@ const Rectangle& Theme::Style::Overlay::getCursorRegion() const
     
 void Theme::Style::Overlay::setCursorRegion(const Rectangle& region, float tw, float th)
 {
-    assert(_cursor);
+    GP_ASSERT(_cursor);
     _cursor->_region.set(region);
     generateUVs(tw, th, region.x, region.y, region.width, region.height, &(_cursor->_uvs));
 }
@@ -348,7 +355,7 @@ const Vector4& Theme::Style::Overlay::getCursorColor() const
 
 void Theme::Style::Overlay::setCursorColor(const Vector4& color)
 {
-    assert(_cursor);
+    GP_ASSERT(_cursor);
     _cursor->_color.set(color);
 }
 
@@ -435,6 +442,8 @@ unsigned int Theme::Style::Overlay::getAnimationPropertyComponentCount(int prope
 
 void Theme::Style::Overlay::getAnimationPropertyValue(int propertyId, AnimationValue* value)
 {
+    GP_ASSERT(value);
+
     switch(propertyId)
     {
     case ANIMATE_OPACITY:
@@ -447,6 +456,8 @@ void Theme::Style::Overlay::getAnimationPropertyValue(int propertyId, AnimationV
 
 void Theme::Style::Overlay::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
 {
+    GP_ASSERT(value);
+
     switch(propertyId)
     {
         case ANIMATE_OPACITY:

+ 76 - 12
gameplay/src/Transform.cpp

@@ -6,6 +6,9 @@
 namespace gameplay
 {
 
+int Transform::_suspendTransformChanged(0);
+std::vector<Transform*> Transform::_transformsChanged;
+
 Transform::Transform()
     : _matrixDirtyBits(0), _listeners(NULL)
 {
@@ -39,6 +42,46 @@ Transform::~Transform()
     SAFE_DELETE(_listeners);
 }
 
+void Transform::suspendTransformChanged()
+{
+    _suspendTransformChanged++;
+}
+
+void Transform::resumeTransformChanged()
+{
+    if (_suspendTransformChanged == 0) // We haven't suspended transformChanged() calls, so do nothing.
+        return;
+    
+    if (_suspendTransformChanged == 1)
+    {
+        // Call transformChanged() on all transforms in the list
+        unsigned int transformCount = _transformsChanged.size();
+        for (unsigned int i = 0; i < transformCount; i++)
+        {
+            Transform* t = _transformsChanged.at(i);
+            t->transformChanged();
+        }
+
+        // Go through list and reset DIRTY_NOTIFY bit. The list could potentially be larger here if the 
+        // transforms we were delaying calls to transformChanged() have any child nodes.
+        transformCount = _transformsChanged.size();
+        for (unsigned int i = 0; i < transformCount; i++)
+        {
+            Transform* t = _transformsChanged.at(i);
+            t->_matrixDirtyBits &= ~DIRTY_NOTIFY;
+        }
+
+        // empty list for next frame.
+        _transformsChanged.clear();
+    }
+    _suspendTransformChanged--;
+}
+
+bool Transform::isTransformChangedSuspended()
+{
+    return (_suspendTransformChanged > 0);
+}
+
 const Matrix& Transform::getMatrix() const
 {
     if (_matrixDirtyBits)
@@ -74,7 +117,7 @@ const Matrix& Transform::getMatrix() const
             Matrix::createScale(_scale, &_matrix);
         }
 
-        _matrixDirtyBits = 0;
+        _matrixDirtyBits &= ~DIRTY_TRANSLATION & ~DIRTY_ROTATION & ~DIRTY_SCALE;
     }
 
     return _matrix;
@@ -112,21 +155,21 @@ const Quaternion& Transform::getRotation() const
 
 void Transform::getRotation(Quaternion* rotation) const
 {
-    assert(rotation);
+    GP_ASSERT(rotation);
 
     rotation->set(_rotation);
 }
 
 void Transform::getRotation(Matrix* rotation) const
 {
-    assert(rotation);
+    GP_ASSERT(rotation);
 
     Matrix::createRotation(_rotation, rotation);
 }
 
 float Transform::getRotation(Vector3* axis) const
 {
-    assert(axis);
+    GP_ASSERT(axis);
     return _rotation.toAxisAngle(axis);
 }
 
@@ -530,7 +573,7 @@ void Transform::translateForward(float amount)
 
 void Transform::transformPoint(Vector3* point)
 {
-    assert(point);
+    GP_ASSERT(point);
 
     getMatrix();
     _matrix.transformPoint(point);
@@ -538,7 +581,7 @@ void Transform::transformPoint(Vector3* point)
 
 void Transform::transformPoint(const Vector3& point, Vector3* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     getMatrix();
     _matrix.transformPoint(point, dst);
@@ -546,7 +589,7 @@ void Transform::transformPoint(const Vector3& point, Vector3* dst)
 
 void Transform::transformVector(Vector3* normal)
 {
-    assert(normal);
+    GP_ASSERT(normal);
 
     getMatrix();
     _matrix.transformVector(normal);
@@ -659,7 +702,7 @@ void Transform::getAnimationPropertyValue(int propertyId, AnimationValue* value)
 
 void Transform::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
 {
-    assert(blendWeight >= 0.0f && blendWeight <= 1.0f);
+    GP_ASSERT(blendWeight >= 0.0f && blendWeight <= 1.0f);
 
     switch (propertyId)
     {
@@ -735,7 +778,28 @@ void Transform::setAnimationPropertyValue(int propertyId, AnimationValue* value,
 void Transform::dirty(char matrixDirtyBits)
 {
     _matrixDirtyBits |= matrixDirtyBits;
-    transformChanged();
+    if (isTransformChangedSuspended())
+    {
+        if (!isDirty(DIRTY_NOTIFY))
+        {
+            suspendTransformChange(this);
+        }
+    }
+    else
+    {
+        transformChanged();
+    }
+}
+
+bool Transform::isDirty(char matrixDirtyBits) const
+{
+    return (_matrixDirtyBits & matrixDirtyBits) == matrixDirtyBits;
+}
+
+void Transform::suspendTransformChange(Transform* transform)
+{
+    transform->_matrixDirtyBits |= DIRTY_NOTIFY;
+    _transformsChanged.push_back(transform);
 }
 
 void Transform::addListener(Transform::Listener* listener, long cookie)
@@ -786,9 +850,9 @@ void Transform::cloneInto(Transform* transform, NodeCloneContext &context) const
 
 void Transform::applyAnimationValueRotation(AnimationValue* value, unsigned int index, float blendWeight)
 {
-    Quaternion q(value->getFloat(index), value->getFloat(index + 1), value->getFloat(index + 2), value->getFloat(index + 3));
-    Quaternion::slerp(_rotation, q, blendWeight, &q);
-    setRotation(q);
+    Quaternion::slerp(_rotation.x, _rotation.y, _rotation.z, _rotation.w, value->getFloat(index), value->getFloat(index + 1), value->getFloat(index + 2), value->getFloat(index + 3), blendWeight, 
+        &_rotation.x, &_rotation.y, &_rotation.z, &_rotation.w);
+    dirty(DIRTY_ROTATION);
 }
 
 }

+ 37 - 0
gameplay/src/Transform.h

@@ -91,6 +91,23 @@ public:
      */
     static const int ANIMATE_SCALE_ROTATE_TRANSLATE = 17;
 
+    /**
+     * Globally suspends all transform changed events.
+     */
+    static void suspendTransformChanged();
+
+    /**
+     * Globally resumes all transform changed events.
+     */
+    static void resumeTransformChanged();
+
+    /** 
+     * Gets whether all transform changed events are suspended.
+     *
+     * @return TRUE if transform changed events are suspended; FALSE if transform changed events are not suspended.
+     */
+    static bool isTransformChangedSuspended();
+
     /**
      * Listener interface for Transform events.
      */
@@ -760,6 +777,7 @@ protected:
         DIRTY_TRANSLATION = 0x01,
         DIRTY_SCALE = 0x02,
         DIRTY_ROTATION = 0x04,
+        DIRTY_NOTIFY = 0x08
     };
 
     /**
@@ -767,6 +785,20 @@ protected:
      */
     void dirty(char matrixDirtyBits);
 
+    /** 
+     * Determines if the specified matrix dirty bit is set.
+     *
+     * @param matrixDirtyBits the matrix dirty bit to check for dirtiness.
+     * @return TRUE if the specified matrix dirty bit is set; FALSE if the specified matrix dirty bit is unset.
+     */
+    bool isDirty(char matrixDirtyBits) const;
+
+    /** 
+     * Adds the specified transform to the list of transforms waiting to be notified of a change.
+     * Sets the DIRTY_NOTIFY bit on the transform.
+     */
+    static void suspendTransformChange(Transform* transform);
+
     /**
      * Called when the transform changes.
      */
@@ -811,7 +843,12 @@ protected:
     std::list<TransformListener>* _listeners;
 
 private:
+   
     void applyAnimationValueRotation(AnimationValue* value, unsigned int index, float blendWeight);
+
+    static int _suspendTransformChanged;
+    static std::vector<Transform*> _transformsChanged;
+    
 };
 
 }

+ 7 - 7
gameplay/src/Vector2.cpp

@@ -81,7 +81,7 @@ void Vector2::add(const Vector2& v)
 
 void Vector2::add(const Vector2& v1, const Vector2& v2, Vector2* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = v1.x + v2.x;
     dst->y = v1.y + v2.y;
@@ -89,7 +89,7 @@ void Vector2::add(const Vector2& v1, const Vector2& v2, Vector2* dst)
 
 void Vector2::clamp(const Vector2& min, const Vector2& max)
 {
-    assert(!( min.x > max.x || min.y > max.y ));
+    GP_ASSERT(!( min.x > max.x || min.y > max.y ));
 
     // Clamp the x value.
     if ( x < min.x )
@@ -106,8 +106,8 @@ void Vector2::clamp(const Vector2& min, const Vector2& max)
 
 void Vector2::clamp(const Vector2& v, const Vector2& min, const Vector2& max, Vector2* dst)
 {
-    assert(dst);
-    assert(!( min.x > max.x || min.y > max.y ));
+    GP_ASSERT(dst);
+    GP_ASSERT(!( min.x > max.x || min.y > max.y ));
 
     // Clamp the x value.
     dst->x = v.x;
@@ -173,7 +173,7 @@ Vector2& Vector2::normalize()
 
 void Vector2::normalize(Vector2* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     if (dst != this)
     {
@@ -237,7 +237,7 @@ void Vector2::set(float x, float y)
 
 void Vector2::set(const float* array)
 {
-    assert(array);
+    GP_ASSERT(array);
 
     x = array[0];
     y = array[1];
@@ -263,7 +263,7 @@ void Vector2::subtract(const Vector2& v)
 
 void Vector2::subtract(const Vector2& v1, const Vector2& v2, Vector2* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = v1.x - v2.x;
     dst->y = v1.y - v2.y;

+ 8 - 8
gameplay/src/Vector3.cpp

@@ -106,7 +106,7 @@ void Vector3::add(const Vector3& v)
 
 void Vector3::add(const Vector3& v1, const Vector3& v2, Vector3* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = v1.x + v2.x;
     dst->y = v1.y + v2.y;
@@ -115,7 +115,7 @@ void Vector3::add(const Vector3& v1, const Vector3& v2, Vector3* dst)
 
 void Vector3::clamp(const Vector3& min, const Vector3& max)
 {
-    assert(!( min.x > max.x || min.y > max.y || min.z > max.z));
+    GP_ASSERT(!( min.x > max.x || min.y > max.y || min.z > max.z));
 
     // Clamp the x value.
     if ( x < min.x )
@@ -138,8 +138,8 @@ void Vector3::clamp(const Vector3& min, const Vector3& max)
 
 void Vector3::clamp(const Vector3& v, const Vector3& min, const Vector3& max, Vector3* dst)
 {
-    assert(dst);
-    assert(!( min.x > max.x || min.y > max.y || min.z > max.z));
+    GP_ASSERT(dst);
+    GP_ASSERT(!( min.x > max.x || min.y > max.y || min.z > max.z));
 
     // Clamp the x value.
     dst->x = v.x;
@@ -175,7 +175,7 @@ void Vector3::cross(const Vector3& v)
 
 void Vector3::cross(const Vector3& v1, const Vector3& v2, Vector3* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     float x = (v1.y * v2.z) - (v1.z * v2.y);
     float y = (v1.z * v2.x) - (v1.x * v2.z);
@@ -238,7 +238,7 @@ Vector3& Vector3::normalize()
 
 void Vector3::normalize(Vector3* dst) const
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     if (dst != this)
     {
@@ -279,7 +279,7 @@ void Vector3::set(float x, float y, float z)
 
 void Vector3::set(const float* array)
 {
-    assert(array);
+    GP_ASSERT(array);
 
     x = array[0];
     y = array[1];
@@ -309,7 +309,7 @@ void Vector3::subtract(const Vector3& v)
 
 void Vector3::subtract(const Vector3& v1, const Vector3& v2, Vector3* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = v1.x - v2.x;
     dst->y = v1.y - v2.y;

+ 7 - 7
gameplay/src/Vector4.cpp

@@ -113,7 +113,7 @@ void Vector4::add(const Vector4& v)
 
 void Vector4::add(const Vector4& v1, const Vector4& v2, Vector4* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = v1.x + v2.x;
     dst->y = v1.y + v2.y;
@@ -123,7 +123,7 @@ void Vector4::add(const Vector4& v1, const Vector4& v2, Vector4* dst)
 
 void Vector4::clamp(const Vector4& min, const Vector4& max)
 {
-    assert(!( min.x > max.x || min.y > max.y || min.z > max.z || min.w > max.w));
+    GP_ASSERT(!( min.x > max.x || min.y > max.y || min.z > max.z || min.w > max.w));
 
     // Clamp the x value.
     if ( x < min.x )
@@ -152,8 +152,8 @@ void Vector4::clamp(const Vector4& min, const Vector4& max)
 
 void Vector4::clamp(const Vector4& v, const Vector4& min, const Vector4& max, Vector4* dst)
 {
-    assert(dst);
-    assert(!( min.x > max.x || min.y > max.y || min.z > max.z || min.w > max.w));
+    GP_ASSERT(dst);
+    GP_ASSERT(!( min.x > max.x || min.y > max.y || min.z > max.z || min.w > max.w));
 
     // Clamp the x value.
     dst->x = v.x;
@@ -241,7 +241,7 @@ Vector4& Vector4::normalize()
 
 void Vector4::normalize(Vector4* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     if (dst != this)
     {
@@ -286,7 +286,7 @@ void Vector4::set(float x, float y, float z, float w)
 
 void Vector4::set(const float* array)
 {
-    assert(array);
+    GP_ASSERT(array);
 
     x = array[0];
     y = array[1];
@@ -320,7 +320,7 @@ void Vector4::subtract(const Vector4& v)
 
 void Vector4::subtract(const Vector4& v1, const Vector4& v2, Vector4* dst)
 {
-    assert(dst);
+    GP_ASSERT(dst);
 
     dst->x = v1.x - v2.x;
     dst->y = v1.y - v2.y;

+ 3 - 3
gameplay/src/VertexAttributeBinding.cpp

@@ -76,7 +76,7 @@ VertexAttributeBinding* VertexAttributeBinding::create(Mesh* mesh, const VertexF
         GL_ASSERT( glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &temp) );
 
         __maxVertexAttribs = temp;
-        assert(__maxVertexAttribs > 0);
+        GP_ASSERT(__maxVertexAttribs > 0);
         if (__maxVertexAttribs <= 0)
         {
             return NULL;
@@ -195,7 +195,7 @@ VertexAttributeBinding* VertexAttributeBinding::create(Mesh* mesh, const VertexF
 
         if (attrib == -1)
         {
-            //WARN_VARG("Warning: Vertex element with usage '%s' in mesh '%s' does not correspond to an attribute in effect '%s'.", VertexFormat::toString(e.usage), mesh->getUrl(), effect->getId());
+            //GP_WARN("Warning: Vertex element with usage '%s' in mesh '%s' does not correspond to an attribute in effect '%s'.", VertexFormat::toString(e.usage), mesh->getUrl(), effect->getId());
         }
         else
         {
@@ -216,7 +216,7 @@ VertexAttributeBinding* VertexAttributeBinding::create(Mesh* mesh, const VertexF
 
 void VertexAttributeBinding::setVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalize, GLsizei stride, void* pointer)
 {
-    assert(indx < (GLuint)__maxVertexAttribs);
+    GP_ASSERT(indx < (GLuint)__maxVertexAttribs);
 
     if (_handle)
     {

+ 1 - 1
gameplay/src/VertexFormat.cpp

@@ -25,7 +25,7 @@ VertexFormat::~VertexFormat()
 
 const VertexFormat::Element& VertexFormat::getElement(unsigned int index) const
 {
-    assert(index < _elements.size());
+    GP_ASSERT(index < _elements.size());
 
     return _elements[index];
 }

+ 5 - 5
gameplay/src/VerticalLayout.cpp

@@ -45,6 +45,8 @@ Layout::Type VerticalLayout::getType()
 
 void VerticalLayout::update(const Container* container)
 {
+    GP_ASSERT(container);
+
     // Need border, padding.
     Theme::Border border = container->getBorder(container->getState());
     Theme::Padding padding = container->getPadding();
@@ -70,6 +72,7 @@ void VerticalLayout::update(const Container* container)
     while (i != end)
     {
         Control* control = controls.at(i);
+        GP_ASSERT(control);
             
         align(control, container);
 
@@ -78,11 +81,8 @@ void VerticalLayout::update(const Container* container)
 
         yPosition += margin.top;
 
-        //if (control->isDirty() || control->isContainer())
-        {
-            control->setPosition(0, yPosition);
-            control->update(container->getClip(), Vector2::zero());
-        }
+        control->setPosition(0, yPosition);
+        control->update(container->getClip(), Vector2::zero());
 
         yPosition += bounds.height + margin.bottom;
 

+ 1 - 0
gameplay/src/gameplay-main-android.cpp

@@ -18,6 +18,7 @@ void android_main(struct android_app* state)
     
     __state = state;
     Game* game = Game::getInstance();
+    GP_ASSERT(game != NULL);
     Platform* platform = Platform::create(game);
     platform->enterMessagePump();
     delete platform;

+ 1 - 1
gameplay/src/gameplay-main-ios.mm

@@ -10,7 +10,7 @@ using namespace gameplay;
 int main(int argc, char** argv)
 {    
     Game* game = Game::getInstance();
-    assert(game != NULL);
+    GP_ASSERT(game != NULL);
     Platform* platform = Platform::create(game);
     int result = platform->enterMessagePump();
 	delete platform;

+ 1 - 1
gameplay/src/gameplay-main-macosx.mm

@@ -10,7 +10,7 @@ using namespace gameplay;
 int main(int argc, char** argv)
 {
     Game* game = Game::getInstance();
-    assert(game != NULL);
+    GP_ASSERT(game != NULL);
     Platform* platform = Platform::create(game);
     int result = platform->enterMessagePump();
 	delete platform;

+ 1 - 1
gameplay/src/gameplay-main-qnx.cpp

@@ -10,7 +10,7 @@ using namespace gameplay;
 int main(int argc, char** argv)
 {
     Game* game = Game::getInstance();
-    assert(game != NULL);
+    GP_ASSERT(game != NULL);
     Platform* platform = Platform::create(game);
     int result = platform->enterMessagePump();
     delete platform;

+ 1 - 1
gameplay/src/gameplay-main-win32.cpp

@@ -15,7 +15,7 @@ using namespace gameplay;
 extern "C" int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow)
 {
     Game* game = Game::getInstance();
-    assert(game != NULL);
+    GP_ASSERT(game != NULL);
     Platform* platform = Platform::create(game);
     int result = platform->enterMessagePump();
     delete platform;