Ver Fonte

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

Karim Ahmed há 13 anos atrás
pai
commit
97c2f7fc43
100 ficheiros alterados com 3565 adições e 3818 exclusões
  1. 3 0
      .gitignore
  2. 0 1
      .kateconfig
  3. 44 6
      CHANGES.md
  4. 9 2
      CMakeLists.txt
  5. 25 17
      README.md
  6. 0 8
      cmake/README.md
  7. 5 4
      gameplay-encoder/CMakeLists.txt
  8. 23 7
      gameplay-encoder/README.md
  9. 6 2
      gameplay-encoder/gameplay-encoder.vcxproj
  10. 12 0
      gameplay-encoder/gameplay-encoder.vcxproj.filters
  11. 4 2
      gameplay-encoder/gameplay-encoder.vcxproj.user
  12. 12 0
      gameplay-encoder/gameplay-encoder.xcodeproj/project.pbxproj
  13. 5 0
      gameplay-encoder/src/Base.h
  14. 1 1
      gameplay-encoder/src/DAEOptimizer.cpp
  15. 44 49
      gameplay-encoder/src/DAESceneEncoder.cpp
  16. 16 16
      gameplay-encoder/src/DAEUtil.cpp
  17. 193 48
      gameplay-encoder/src/EncoderArguments.cpp
  18. 42 1
      gameplay-encoder/src/EncoderArguments.h
  19. 114 29
      gameplay-encoder/src/FBXSceneEncoder.cpp
  20. 2 2
      gameplay-encoder/src/FileIO.h
  21. 1 1
      gameplay-encoder/src/GPBFile.cpp
  22. 42 29
      gameplay-encoder/src/Heightmap.cpp
  23. 3 2
      gameplay-encoder/src/Heightmap.h
  24. 264 0
      gameplay-encoder/src/Image.cpp
  25. 123 0
      gameplay-encoder/src/Image.h
  26. 329 0
      gameplay-encoder/src/NormalMapGenerator.cpp
  27. 35 0
      gameplay-encoder/src/NormalMapGenerator.h
  28. 1 1
      gameplay-encoder/src/Scene.h
  29. 18 0
      gameplay-encoder/src/main.cpp
  30. 52 0
      gameplay-luagen/CMakeLists.txt
  31. 0 15
      gameplay-luagen/gameplay-api/xml/combine.xslt
  32. 0 832
      gameplay-luagen/gameplay-api/xml/compound.xsd
  33. 0 3
      gameplay-luagen/gameplay-api/xml/index.xml
  34. 0 66
      gameplay-luagen/gameplay-api/xml/index.xsd
  35. 4 4
      gameplay-luagen/gameplay-luagen.vcxproj
  36. 5 0
      gameplay-luagen/src/Base.h
  37. 6 4
      gameplay-luagen/src/ClassBinding.cpp
  38. 145 92
      gameplay-luagen/src/FunctionBinding.cpp
  39. 2 0
      gameplay-luagen/src/FunctionBinding.h
  40. 46 26
      gameplay-luagen/src/Generator.cpp
  41. 42 1
      gameplay-luagen/src/main.cpp
  42. 8 2
      gameplay-newproject.bat
  43. 15 11
      gameplay-newproject.sh
  44. BIN
      gameplay-template/[email protected]
  45. 31 31
      gameplay-template/android/template.AndroidManifest.xml
  46. 3 4
      gameplay-template/android/template.build.xml
  47. 113 0
      gameplay-template/gameplay-template-CMakeLists.txt
  48. 155 7
      gameplay-template/gameplay-template.vcxproj
  49. 15 3
      gameplay-template/gameplay-template.vcxproj.user
  50. 146 92
      gameplay-template/gameplay-template.xcodeproj/project.pbxproj
  51. 1 1
      gameplay-template/res/colored.vert
  52. 6 12
      gameplay-template/template.bar-descriptor.xml
  53. 1 1
      gameplay.doxyfile
  54. 132 75
      gameplay.sln
  55. 23 15
      gameplay/.cproject
  56. 31 15
      gameplay/CMakeLists.txt
  57. 8 1
      gameplay/android/jni/Android.mk
  58. 0 591
      gameplay/gameplay.cbp
  59. 151 10
      gameplay/gameplay.vcxproj
  60. 336 318
      gameplay/gameplay.vcxproj.filters
  61. 42 968
      gameplay/gameplay.xcodeproj/project.pbxproj
  62. 1 0
      gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-ios.xcscheme
  63. 1 0
      gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-macosx.xcscheme
  64. 9 9
      gameplay/res/shaders/colored-unlit.frag
  65. 12 12
      gameplay/res/shaders/colored-unlit.vert
  66. 24 21
      gameplay/res/shaders/colored.frag
  67. 11 10
      gameplay/res/shaders/colored.vert
  68. 17 0
      gameplay/res/shaders/font.frag
  69. 19 0
      gameplay/res/shaders/font.vert
  70. 15 0
      gameplay/res/shaders/form.frag
  71. 16 0
      gameplay/res/shaders/form.vert
  72. 0 0
      gameplay/res/shaders/lighting-directional.frag
  73. 5 5
      gameplay/res/shaders/lighting-directional.vert
  74. 0 0
      gameplay/res/shaders/lighting-point.frag
  75. 9 12
      gameplay/res/shaders/lighting-point.vert
  76. 3 3
      gameplay/res/shaders/lighting-spot.frag
  77. 15 17
      gameplay/res/shaders/lighting-spot.vert
  78. 0 0
      gameplay/res/shaders/lighting.frag
  79. 0 0
      gameplay/res/shaders/skinning-none.vert
  80. 2 2
      gameplay/res/shaders/skinning.vert
  81. 16 0
      gameplay/res/shaders/sprite.frag
  82. 19 0
      gameplay/res/shaders/sprite.vert
  83. 82 0
      gameplay/res/shaders/terrain.frag
  84. 53 0
      gameplay/res/shaders/terrain.vert
  85. 36 28
      gameplay/res/shaders/textured-bumped.frag
  86. 14 10
      gameplay/res/shaders/textured-bumped.vert
  87. 13 9
      gameplay/res/shaders/textured-unlit.frag
  88. 6 6
      gameplay/res/shaders/textured-unlit.vert
  89. 27 21
      gameplay/res/shaders/textured.frag
  90. 18 13
      gameplay/res/shaders/textured.vert
  91. 1 2
      gameplay/src/AbsoluteLayout.cpp
  92. 2 2
      gameplay/src/Animation.cpp
  93. 10 6
      gameplay/src/AnimationClip.cpp
  94. 81 55
      gameplay/src/AudioBuffer.cpp
  95. 3 2
      gameplay/src/AudioBuffer.h
  96. 3 1
      gameplay/src/AudioListener.cpp
  97. 13 26
      gameplay/src/Base.h
  98. 93 113
      gameplay/src/Bundle.cpp
  99. 1 1
      gameplay/src/Bundle.h
  100. 20 4
      gameplay/src/Button.cpp

+ 3 - 0
.gitignore

@@ -9,7 +9,9 @@ Icon?
 Thumbs.db
 /.metadata
 /169.254.0.1
+/usb
 /ipch
+/build
 /cmake
 /Debug
 /Release
@@ -45,6 +47,7 @@ Thumbs.db
 /gameplay/Device-Release
 /gameplay.xcworkspace/xcuserdata
 /gameplay/gameplay.xcodeproj/xcuserdata
+/gameplay/windows
 /gameplay/android/NUL
 /gameplay/android/proguard.cfg
 /gameplay/android/proguard-project.txt

+ 0 - 1
.kateconfig

@@ -1 +0,0 @@
-kate: space-indent on; tab-width 4; indent-width 4; replace-tabs on; show-tabs: on; replace-tabs-save: off; replace-trailing-space-save: off;

+ 44 - 6
CHANGES.md

@@ -1,9 +1,47 @@
+## v1.6.0
+
+- Adds file Stream interface for reading/writing files instead of using fread/fwrite. 
+- Adds Terrain class to support for heightmap based terrains featuring LOD, multiple surface layers, loading from PNG, RAW8/16, full transform, physics, patch culling and verticle skirt for cracks.
+- Adds object-space normal map generation to gameplay-encoder for terrain normal map generation.
+- Adds scene support for loading .terrain files in .scene files.
+- Adds scene support for inline cameras to .scene files.
+- Adds suppoft for defining .scene files without 'path' to gpb. New node can not be create in .scene file.
+- Adds static Scene::getScene(const char*) to query currently active scenes in a game, helpful for script access.
+- Adds support for multiple translate, rotate and scale commands in a single node entity within .scene files, processed in-order they are defined.
+- Adds scene support for material auto binding scene ambient color, light color and light direction.
+- Adds support for setting the depth compare function on materials.
+- Adds support for texture/sampler arrays being passed to materials.
+- Adds support for loading uncompressed DDS textures for the following formats: R8G8B8, A8R8G8B8, A8B8G8R8, X8R8G8B8, X8B8G8R8
+- Adds improvments to prefer higher quality mipmap generation.
+- Adds improved Gamepad API support for button enumeration, triggers and some mobile Gamepad support on BlackBerry.
+- Adds additional gameplay-tests for billboards, forms, gamepads and lights.
+- Adds support for launching the browser via launchURL(const char*).
+- Adds physics support for setLinearFactor and setAngularFactor  on rigid bodies.
+- Adds methods to PhysicsCollisionObject to allow conversion to subclass types (i.e. PhysicsRigidBody, PhysicsCharacter, etc) from script.
+- Adds option for fullscreen without width/height config to use native desktop resolution.
+- Adds Linux support for OpenAL PulseAudio back-end.
+- Adds support for latest Bullet Physics 2.81 with NEON optimizations for mobile targets.
+- Adds support for preprocessor directive NO_LUA_BINDINGS in the gameplay project to omit inclusion of generated lua bindings in compilation for developer mode value. 
+- Adds optimizations to Lua generator to only write generated files if they differ from existing files, reducing both build times and committing of unchanged script binding files.
+- Adds changes to Slider for setValueTextVisible, setValueTextAlignment, setValueTextPrecision and getters.
+- Adds Microsoft Windows 7 64-bit support.
+- Adds Apple iOS 6 support.
+- Fixes to external-deps to reduce the size of the libraries on Windows.
+- Fixes for Android to no longer need to copy files to the SD card before reading them. None of the Android samples require an SD card.
+- Fixes for animation of opacity on UI and fonts.
+- Fixes in UI for removing controls and also setVisible(bool).
+- Fixes for UI controls missing on MacOSX.
+- Fixes for setting UI alignment programmatically.
+- Fixes for lighting shaders.
+- Fixes to the texture minification mode from GL_LINEAR_MIPMAP_LINEAR to GL_NEAREST_MIPMAP_LINEAR for newly created textures with mipmaps.
+- Fixes minor memory leaks and possible access violations when calling Game::exit() from script.
+- Fixes physics debug drawing for large scenes causing the internal MeshBatch to grow to an enormous size.
+
 ## v1.5.0
 
 - Linux support. (tested on Ubuntu 12)
 - CMake support for makefile generation for Linux.
-- CodeBlocks 10 IDE support for Linux.
-- Gamepad controllers support for desktops.
+- Gamepad API support for desktops.
 - Touch gesture support for tap, swipe and pinch.
 - Vehicle physics support via new PhysicsVehicle and PhysicsVehicleWheel classes.
 - Adds new racer sample (sample06-racer).
@@ -16,7 +54,7 @@
 - Adds Game/Platform::canExit for testing device capabilities to quit. (only ios)
 - Web community forums at http://www.gameplay3d.org/forums.
 - Changed keyTimes from unsigned long[]  to unsigned int[]. (breaks compat. in AnimationTarget and Animation::Channel)
-- Fixed inconsistencies from Bundle::getObjectID() to Bundle::getObjectId() (breaks compat. in Bundle)
+- Fixes inconsistencies from Bundle::getObjectID() to Bundle::getObjectId() (breaks compat. in Bundle)
 - Fixes the texture coordinates of Mesh::createQuad(float x, float y, float width, float height).
 - Fixes line-wise distortion when loading RGB png's into textures that are non-power of two.
 - Fixes inconsistencies in createXXXX methods.  (breaks compat. in Scene)
@@ -24,7 +62,7 @@
 - Fixes Lua print logging.
 - Fixes Lua errors to be treated as runtime warnings.
 - Fixes setVertexData to pointers instead of constant data.
-- Fixed AudioSource so that it doesn't loop by default.
+- Fixes AudioSource so that it doesn't loop by default.
 - Fixes minor UI scrolling issues.
 
 ## v1.4.0
@@ -47,7 +85,7 @@
 - Fixes to FrameBuffer, RenderTarget and DepthStencilTarget.
 - Fixes user switching in MacOSX to other applications with Apple-Tab.
 - Fixes measureText with empty string to be proper size.
-- Fixed for aliased text by applying linear filtering by default on Fonts.
+- Fixes for aliased text by applying linear filtering by default on Fonts.
 - Fixes RenderState::StateBlock::bindNoRestore() issue where blend function was not restored to the proper defaults.
 - Fixes some inconsistencies in Game event method names for menuEvent. (breaks compat. in Game)
 - Fixes some inconsistencies with AnimationClip::getID() to be same as Node::getId() and other classes. (breaks compat. in AnimationClip)
@@ -108,7 +146,7 @@
 - Fixes to the material/shader system.
 - Fixes to the ParticleEmitter.
 
-## v1.0.1
+## v1.0.0
 
 - Initial release.
 

+ 9 - 2
CMakeLists.txt

@@ -2,15 +2,22 @@ cmake_minimum_required(VERSION 2.6)
 
 project(GamePlay)
 
-set(GAMEPLAY_VERSION 1.5.0)
+set(GAMEPLAY_VERSION 1.6.0)
 set(CMAKE_C_COMPILER_INIT g++)
 
 # debug
 message( "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}" )
-if( "${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG" )
+if ( "${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG" )
     add_definitions(-D_DEBUG)
 endif()
 
+# architecture
+if ( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+set(ARCH_DIR "x64")
+else()
+set(ARCH_DIR "x86")
+endif()
+
 # gameplay library
 add_subdirectory(gameplay)
 

+ 25 - 17
README.md

@@ -1,29 +1,37 @@
-## gameplay v1.5.0
-An open-source, cross-platform 3D native C++ game framework making it easy to learn and write mobile and desktop games. 
+## gameplay v1.6.0
+
+GamePlay3D is an open-source, cross-platform 3D native C++ game framework making it easy to learn and write mobile and desktop games. 
+
+<img align="right" src="https://raw.github.com/wiki/blackberry/GamePlay/img/logo.png" alt="gameplay" />
+
+- [Website](http://www.gameplay3d.org/)
+- [Forums](http://www.gameplay3d.org/forums/)
+- [Wiki](https://github.com/blackberry/GamePlay/wiki)
+- [API Reference](http://www.gameplay3d.org/api.php)
+- [Development Guide](https://github.com/blackberry/GamePlay/wiki#wiki-Development_Guide)
 
 ## Supported Mobile Platforms
-- BlackBerry 10 and PlayBook 2.0 (using BlackBerry Native SDK)
-- Apple iOS 5.1 (using Apple XCode 4.3.2)
-- Google Android 2.3+ (using Google Android NDK, SDK API level 9+)
+- [BlackBerry 10 and PlayBook](https://github.com/blackberry/GamePlay/wiki/BlackBerry-Setup) (using BlackBerry Native SDK)
+- [Apple iOS 5+](https://github.com/blackberry/GamePlay/wiki/Apple-Xcode-Setup) (using Apple XCode 4)
+- [Google Android 2.3+](https://github.com/blackberry/GamePlay/wiki/Android-NDK-Setup) (using Google Android NDK)
 
 ## Supported Desktop Platforms
-- Microsoft Windows 7 (using Microsoft Visual Studio 2010)
-- Apple MacOS X (using Apple XCode 4.3.2)
-- Linux (using CMake or CodeBlocks 10)
+- [Microsoft Windows 7](https://github.com/blackberry/GamePlay/wiki/Visual-Studio-Setup) (using Microsoft Visual Studio 2010)
+- [Apple MacOS X](https://github.com/blackberry/GamePlay/wiki/Apple-Xcode-Setup) (using Apple XCode 4)
+- [Linux](https://github.com/blackberry/GamePlay/wiki/Linux-Setup) (using CMake)
 
 ## Roadmap for 'next' branch
-- AI Pathfinding
-- Terrain and Water
-- Asset Pipeline improvements
+- [Version 1.7.0 Milestone](https://github.com/blackberry/GamePlay/issues?milestone=4)
 
 ## License
-The project is open sourced under the Apache 2.0 license.
+The project is open sourced under the [Apache 2.0 license](http://www.tldrlegal.com/license/apache-license-2.0-%28apache-2.0%29).
+
+## Bug Reporting
+Please log bugs under [Issues](https://github.com/blackberry/GamePlay/issues) on github.
+If you are unsure if your problem is a bug then post on the [Help Forum](http://www.gameplay3d.org/forums/viewforum.php?f=3).
 
-## Bug Reporting and Feature Requests
-If you find a bug in a Sample, or have an enhancement request, simply file an 
-[Issue](https://github.com/blackberry/GamePlay/issues) and send a message (via github messages) 
-to the Committers to the project to let them know that you have filed 
-an [Issue](https://github.com/blackberry/GamePlay/issues).
+## Feature Requests
+Please post feature requests on the [Feature Request Forum](http://www.gameplay3d.org/forums/viewforum.php?f=4). Approved feature requests will be added to the github issues list. 
 
 ## Disclaimer
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 

+ 0 - 8
cmake/README.md

@@ -1,8 +0,0 @@
-## Building with CMake
-Run the following command lines from this directory:
-* cmake ..
-* make
-
-
-
-

+ 5 - 4
gameplay-encoder/CMakeLists.txt

@@ -9,13 +9,14 @@ include_directories(
     /usr/include
 )
 
+add_definitions(-D_DEBUG)
 add_definitions(-D__linux__ -DNO_BOOST -DNO_ZAE)
 
 link_directories(
-    ${CMAKE_SOURCE_DIR}/external-deps/zlib/lib/linux
-    ${CMAKE_SOURCE_DIR}/external-deps/libpng/lib/linux
-    ${CMAKE_SOURCE_DIR}/external-deps/freetype2/lib/linux
-    ${CMAKE_SOURCE_DIR}/external-deps/collada-dom/lib/linux
+    ${CMAKE_SOURCE_DIR}/external-deps/zlib/lib/linux/${ARCH_DIR}
+    ${CMAKE_SOURCE_DIR}/external-deps/libpng/lib/linux/${ARCH_DIR}
+    ${CMAKE_SOURCE_DIR}/external-deps/freetype2/lib/linux/${ARCH_DIR}
+    ${CMAKE_SOURCE_DIR}/external-deps/collada-dom/lib/linux/${ARCH_DIR}
     /usr/lib
 )
 

+ 23 - 7
gameplay-encoder/README.md

@@ -2,7 +2,7 @@
 Command-line tool for encoding games assets like true-type fonts and 3D scene files
 into a simple binary-based bundle file format for the gameplay 3D game framework runtime. 
 The 'bin' folder contains pre-built versions of the gameplay-encoder executables for 
-Windows 7, MacOS X and Linux (tested on Ubuntu 12) with support built-in support for:
+Windows 7, MacOS X and Linux Ubuntu 12 (32-bit) with support built-in support for:
 
 ## TrueType Font
 TrueType Fonts represent a standard in defining outline fonts and has become the 
@@ -20,8 +20,17 @@ between several Autodesk content creation packages
 Autodesk® Maya®, Autodesk® 3ds Max®, Autodesk® MotionBuilder®, Autodesk® Mudbox®, and Autodesk® Softimage®
 For more information goto "http://www.autodesk.com/fbx".
 
+## Running gameplay-encoder
+Simply execute the gameplay-encoder command-line executable:
+
+`Usage: gameplay-encoder [options] <file(s)>`
+
+Note: On Linux Ubuntu 12 (64-bit), you must first install the required 32-bit libs via:
+
+`sudo apt-get install ia32-libs`
+
 ## Building gameplay-encoder
-The gameplay-encoder comes pre-built for Windows 7, MacOS X and Linux x64 in the 'bin' folder.
+The gameplay-encoder comes pre-built for Windows 7, MacOS X and Linux Ubuntu 12 (32-bit) in the 'bin' folder.
 However, to build the gameplay-encoder yourself just open either the 
 Visual Studio 2010 project "gameplay-encoder.vccproj" on Windows 7 or
 XCode project "gameplay-encoder.xcodeproj" on MacOSX.
@@ -39,8 +48,8 @@ Uncomment the root CMakeList.txt for the gameplay-encoder and run standard cmake
   * Example: fbxsdk-2013.3-mdd.lib
 - Build gameplay-encoder
 
-### Building with FBX Support on Mac OS X using XCode 4.3.2+
-- Download and install the FBX SDK for Mac OS X (http://www.autodesk.com/fbx)
+### Building with FBX Support on MacOS X using XCode 4
+- Download and install the FBX SDK for MacOS X (http://www.autodesk.com/fbx)
 - Edit the project properties of target "gameplay-encoder".
 - Add Preprocessor Macro "USE_FBX" to both Debug/Release sections. (Build Settings)
 - Add the FBX include directory to Header Search Paths: (Build Settings)
@@ -49,8 +58,8 @@ Uncomment the root CMakeList.txt for the gameplay-encoder and run standard cmake
   * Example: /Applications/Autodesk/FBX SDK/2013.3/lib/gcc4/ub/libfbxsdk-2013.3-static.a  (Add Other)
 - Build gameplay-encoder
 
-### Building with FBX Support on Linux
-- Download and install the FBX SDK for Mac OS X (http://www.autodesk.com/fbx)
+### Building with FBX Support on Linux Ubuntu 12 (32-bit) using CMake
+- Download and install the FBX SDK for MacOS X (http://www.autodesk.com/fbx)
 - Edit the gameplay-encoder/CMakeLists.txt adding the following:
 - Add the FBX include directory to Header Search Paths: (Build Settings)
   * Example: /usr/include/fbxsdk
@@ -61,7 +70,14 @@ Uncomment the root CMakeList.txt for the gameplay-encoder and run standard cmake
   * Example: fbxsdk-2013.3-static
 - Add the FBX library to the library to the add_definitions(-l...) section of the CMakeLists.txt
   * Example -lfbxsdk-2013.3-static
-- Build gameplay-encoder via main cmake .. in build then make.
+- Build gameplay-encoder by uncommenting the last line in the gameplay/CMakeLists.txt and running the CMake build via:
+
+```
+mkdir build
+cd build
+cmake ..
+make
+ ```
 
 ## Bundle File Format
 The gameplay bundle file format is well defined in the gameplay-encoder/gameplay-bundle.txt file.

+ 6 - 2
gameplay-encoder/gameplay-encoder.vcxproj

@@ -31,6 +31,7 @@
     <ClCompile Include="src\GPBDecoder.cpp" />
     <ClCompile Include="src\Animations.cpp" />
     <ClCompile Include="src\Heightmap.cpp" />
+    <ClCompile Include="src\Image.cpp" />
     <ClCompile Include="src\Light.cpp" />
     <ClCompile Include="src\main.cpp" />
     <ClCompile Include="src\Material.cpp" />
@@ -41,6 +42,7 @@
     <ClCompile Include="src\MeshPart.cpp" />
     <ClCompile Include="src\MeshSkin.cpp" />
     <ClCompile Include="src\Node.cpp" />
+    <ClCompile Include="src\NormalMapGenerator.cpp" />
     <ClCompile Include="src\Object.cpp" />
     <ClCompile Include="src\Quaternion.cpp" />
     <ClCompile Include="src\Reference.cpp" />
@@ -76,6 +78,7 @@
     <ClInclude Include="src\GPBDecoder.h" />
     <ClInclude Include="src\Animations.h" />
     <ClInclude Include="src\Heightmap.h" />
+    <ClInclude Include="src\Image.h" />
     <ClInclude Include="src\Light.h" />
     <ClInclude Include="src\Material.h" />
     <ClInclude Include="src\MaterialParameter.h" />
@@ -85,6 +88,7 @@
     <ClInclude Include="src\MeshPart.h" />
     <ClInclude Include="src\MeshSkin.h" />
     <ClInclude Include="src\Node.h" />
+    <ClInclude Include="src\NormalMapGenerator.h" />
     <ClInclude Include="src\Object.h" />
     <ClInclude Include="src\Quaternion.h" />
     <ClInclude Include="src\Reference.h" />
@@ -159,7 +163,7 @@
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/windows;../external-deps/collada-dom/lib/windows;../external-deps/libpng/lib/windows;../external-deps/zlib/lib/windows</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/windows/x86;../external-deps/collada-dom/lib/windows/x86;../external-deps/libpng/lib/windows/x86;../external-deps/zlib/lib/windows/x86</AdditionalLibraryDirectories>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;libpng14.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <IgnoreSpecificDefaultLibraries>MSVCRT</IgnoreSpecificDefaultLibraries>
     </Link>
@@ -184,7 +188,7 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <AdditionalDependencies>freetype245.lib;libcollada14dom22-d.lib;libpng14.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/windows;../external-deps/collada-dom/lib/windows;../external-deps/libpng/lib/windows;../external-deps/zlib/lib/windows</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>../external-deps/freetype2/lib/windows/x86;../external-deps/collada-dom/lib/windows/x86;../external-deps/libpng/lib/windows/x86;../external-deps/zlib/lib/windows/x86</AdditionalLibraryDirectories>
       <IgnoreSpecificDefaultLibraries>
       </IgnoreSpecificDefaultLibraries>
     </Link>

+ 12 - 0
gameplay-encoder/gameplay-encoder.vcxproj.filters

@@ -130,6 +130,12 @@
     <ClCompile Include="src\Heightmap.cpp">
       <Filter>src</Filter>
     </ClCompile>
+    <ClCompile Include="src\Image.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\NormalMapGenerator.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\VertexElement.h">
@@ -261,6 +267,12 @@
     <ClInclude Include="src\Heightmap.h">
       <Filter>src</Filter>
     </ClInclude>
+    <ClInclude Include="src\Image.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\NormalMapGenerator.h">
+      <Filter>src</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="src\Vector2.inl">

+ 4 - 2
gameplay-encoder/gameplay-encoder.vcxproj.user

@@ -4,10 +4,12 @@
     <LocalDebuggerCommandArguments>
     </LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
-    <LocalDebuggerEnvironment>PATH=%PATH%;../bin/windows;</LocalDebuggerEnvironment>
+    <LocalDebuggerEnvironment>
+    </LocalDebuggerEnvironment>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;../bin/windows;</LocalDebuggerEnvironment>
+    <LocalDebuggerEnvironment>
+    </LocalDebuggerEnvironment>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
 </Project>

+ 12 - 0
gameplay-encoder/gameplay-encoder.xcodeproj/project.pbxproj

@@ -61,6 +61,8 @@
 		42D277591472EFA700D867A4 /* libpcre.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D277571472EFA700D867A4 /* libpcre.a */; };
 		42D2775A1472EFA700D867A4 /* libpcrecpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42D277581472EFA700D867A4 /* libpcrecpp.a */; };
 		5BCD0643152CFC3C0071FAB5 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BCD0642152CFC3C0071FAB5 /* libpng.a */; };
+		B661733F16A61CE40083A307 /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B661733D16A61CE40083A307 /* Image.cpp */; };
+		B661734316A61CFA0083A307 /* NormalMapGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B661734116A61CFA0083A307 /* NormalMapGenerator.cpp */; };
 		F18DCD0615D554B800DB35DB /* Heightmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F18DCD0315D554B800DB35DB /* Heightmap.cpp */; };
 /* End PBXBuildFile section */
 
@@ -179,6 +181,10 @@
 		42D277571472EFA700D867A4 /* libpcre.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcre.a; path = "../external-deps/pcre/lib/macosx/libpcre.a"; sourceTree = "<group>"; };
 		42D277581472EFA700D867A4 /* libpcrecpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpcrecpp.a; path = "../external-deps/pcre/lib/macosx/libpcrecpp.a"; sourceTree = "<group>"; };
 		5BCD0642152CFC3C0071FAB5 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "../external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
+		B661733D16A61CE40083A307 /* Image.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Image.cpp; path = src/Image.cpp; sourceTree = SOURCE_ROOT; };
+		B661733E16A61CE40083A307 /* Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Image.h; path = src/Image.h; sourceTree = SOURCE_ROOT; };
+		B661734116A61CFA0083A307 /* NormalMapGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NormalMapGenerator.cpp; path = src/NormalMapGenerator.cpp; sourceTree = SOURCE_ROOT; };
+		B661734216A61CFA0083A307 /* NormalMapGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NormalMapGenerator.h; path = src/NormalMapGenerator.h; sourceTree = SOURCE_ROOT; };
 		F18DCD0315D554B800DB35DB /* Heightmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Heightmap.cpp; path = src/Heightmap.cpp; sourceTree = SOURCE_ROOT; };
 		F18DCD0415D554B800DB35DB /* Heightmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Heightmap.h; path = src/Heightmap.h; sourceTree = SOURCE_ROOT; };
 		F18DCD0515D554B800DB35DB /* Thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Thread.h; path = src/Thread.h; sourceTree = SOURCE_ROOT; };
@@ -278,6 +284,8 @@
 				42C8EDD614724CD700E43619 /* GPBDecoder.h */,
 				42C8EDD714724CD700E43619 /* GPBFile.cpp */,
 				42C8EDD814724CD700E43619 /* GPBFile.h */,
+				B661733D16A61CE40083A307 /* Image.cpp */,
+				B661733E16A61CE40083A307 /* Image.h */,
 				42C8EDD914724CD700E43619 /* Light.cpp */,
 				42C8EDDA14724CD700E43619 /* Light.h */,
 				42C8EDDD14724CD700E43619 /* main.cpp */,
@@ -299,6 +307,8 @@
 				42C8EDED14724CD700E43619 /* Model.h */,
 				42C8EDEE14724CD700E43619 /* Node.cpp */,
 				42C8EDEF14724CD700E43619 /* Node.h */,
+				B661734116A61CFA0083A307 /* NormalMapGenerator.cpp */,
+				B661734216A61CFA0083A307 /* NormalMapGenerator.h */,
 				42C8EDF014724CD700E43619 /* Object.cpp */,
 				42C8EDF114724CD700E43619 /* Object.h */,
 				42C8EDF214724CD700E43619 /* Quaternion.cpp */,
@@ -444,6 +454,8 @@
 				42783423148D6F7500A6E27F /* FBXSceneEncoder.cpp in Sources */,
 				4251B12C152D044B002F6199 /* Curve.cpp in Sources */,
 				F18DCD0615D554B800DB35DB /* Heightmap.cpp in Sources */,
+				B661733F16A61CE40083A307 /* Image.cpp in Sources */,
+				B661734316A61CFA0083A307 /* NormalMapGenerator.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 5 - 0
gameplay-encoder/src/Base.h

@@ -20,6 +20,11 @@
 #include <algorithm>
 #include <sys/stat.h>
 
+using std::memcpy;
+using std::size_t;
+using std::min;
+using std::max;
+
 // PNG
 #include <png.h>
 

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

@@ -19,7 +19,7 @@ void DAEOptimizer::combineAnimations(const std::string& nodeId, const std::strin
 
     daeSIDResolver resolver(_dom, nodeId.c_str());
     daeElement* element = resolver.getElement();
-    if (element && element->typeID() == COLLADA_TYPE::NODE)
+    if (element && element->typeID() == domNode::ID())
     {
         domNodeRef node = daeSafeCast<domNode>(resolver.getElement());
         getAnimationChannels(node, channels);

+ 44 - 49
gameplay-encoder/src/DAESceneEncoder.cpp

@@ -889,59 +889,54 @@ void DAESceneEncoder::calcTransform(domNode* domNode, Matrix& dstTransform)
     for (size_t i = 0; i < childCount; ++i)
     {
         daeElementRef childElement = children[i];
-        switch (childElement->typeID())
+        daeInt typeID = childElement->typeID();
+        if (typeID == domTranslate::ID())
         {
-            case COLLADA_TYPE::TRANSLATE:
+            domTranslateRef translateNode = daeSafeCast<domTranslate>(childElement);
+            float x = (float)translateNode->getValue().get(0);
+            float y = (float)translateNode->getValue().get(1);
+            float z = (float)translateNode->getValue().get(2);
+            dstTransform.translate(x, y, z);
+        }
+        if (typeID == domRotate::ID())
+        {
+            domRotateRef rotateNode = daeSafeCast<domRotate>(childElement);
+            float x = (float)rotateNode->getValue().get(0);
+            float y = (float)rotateNode->getValue().get(1);
+            float z = (float)rotateNode->getValue().get(2);
+            float angle = MATH_DEG_TO_RAD((float)rotateNode->getValue().get(3)); // COLLADA uses degrees, gameplay uses radians
+            if (x == 1.0f && y == 0.0f && z == 0.0f)
             {
-                domTranslateRef translateNode = daeSafeCast<domTranslate>(childElement);
-                float x = (float)translateNode->getValue().get(0);
-                float y = (float)translateNode->getValue().get(1);
-                float z = (float)translateNode->getValue().get(2);
-                dstTransform.translate(x, y, z);
-                break;
+                dstTransform.rotateX(angle);
             }
-            case COLLADA_TYPE::ROTATE:
+            else if (x == 0.0f && y == 1.0f && z == 0.0f)
             {
-                domRotateRef rotateNode = daeSafeCast<domRotate>(childElement);
-                float x = (float)rotateNode->getValue().get(0);
-                float y = (float)rotateNode->getValue().get(1);
-                float z = (float)rotateNode->getValue().get(2);
-                float angle = MATH_DEG_TO_RAD((float)rotateNode->getValue().get(3)); // COLLADA uses degrees, gameplay uses radians
-                if (x == 1.0f && y == 0.0f && z == 0.0f)
-                {
-                    dstTransform.rotateX(angle);
-                }
-                else if (x == 0.0f && y == 1.0f && z == 0.0f)
-                {
-                    dstTransform.rotateY(angle);
-                }
-                else if (x == 0.0f && y == 0.0f && z == 1.0f)
-                {
-                    dstTransform.rotateZ(angle);
-                }
-                else
-                {
-                    dstTransform.rotate(x, y, z, angle);
-                }
-                break;
+                dstTransform.rotateY(angle);
             }
-            case COLLADA_TYPE::SCALE:
+            else if (x == 0.0f && y == 0.0f && z == 1.0f)
             {
-                domScaleRef scaleNode = daeSafeCast<domScale>(childElement);
-                float x = (float)scaleNode->getValue().get(0);
-                float y = (float)scaleNode->getValue().get(1);
-                float z = (float)scaleNode->getValue().get(2);
-                dstTransform.scale(x, y, z);
-                break;
+                dstTransform.rotateZ(angle);
             }
-            case COLLADA_TYPE::SKEW:
-                LOG(1, "Warning: Skew transform found but not supported.\n");
-                break;
-            case COLLADA_TYPE::LOOKAT:
-                LOG(1, "Warning: Lookat transform found but not supported.\n");
-                break;
-            default:
-                break;
+            else
+            {
+                dstTransform.rotate(x, y, z, angle);
+            }
+        }
+        if (typeID == domScale::ID())
+        {
+            domScaleRef scaleNode = daeSafeCast<domScale>(childElement);
+            float x = (float)scaleNode->getValue().get(0);
+            float y = (float)scaleNode->getValue().get(1);
+            float z = (float)scaleNode->getValue().get(2);
+            dstTransform.scale(x, y, z);
+        }
+        if (typeID == domSkew::ID())
+        {
+            LOG(1, "Warning: Skew transform found but not supported.\n");
+        }
+        if (typeID == domLookat::ID())
+        {
+            LOG(1, "Warning: Lookat transform found but not supported.\n");
         }
     }
 }
@@ -1286,7 +1281,7 @@ void DAESceneEncoder::loadSkeleton(domNode* rootNode, MeshSkin* skin)
         domNode* topLevelParent = rootNode;
         while (
             topLevelParent->getParent() &&
-            topLevelParent->getParent()->typeID() == COLLADA_TYPE::NODE &&
+            topLevelParent->getParent()->typeID() == domNode::ID() &&
             _gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID()) == NULL)
         {
             topLevelParent = (domNode*)topLevelParent->getParent();
@@ -1295,7 +1290,7 @@ void DAESceneEncoder::loadSkeleton(domNode* rootNode, MeshSkin* skin)
         // Is the parent of this node loaded yet?
         Node* parentNode = NULL;
         if (topLevelParent->getParent() &&
-            topLevelParent->getParent()->typeID() == COLLADA_TYPE::NODE &&
+            topLevelParent->getParent()->typeID() == domNode::ID() &&
             _gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID()) != NULL)
         {
             parentNode = (Node*)_gamePlayFile.getFromRefTable(topLevelParent->getParent()->getID());
@@ -1372,7 +1367,7 @@ Model* DAESceneEncoder::loadSkin(const domSkin* skinElement)
             {
                 daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
                 daeElement* element = resolver.getElement();
-                if (element && element->typeID() == COLLADA_TYPE::NODE)
+                if (element && element->typeID() == domNode::ID())
                 {
                     domNodeRef node = daeSafeCast<domNode>(element);
                     const char* nodeId = node->getId();

+ 16 - 16
gameplay-encoder/src/DAEUtil.cpp

@@ -54,7 +54,7 @@ void getAnimationChannels(const domNodeRef& node, std::list<domChannelRef>& chan
     for (size_t i = 0; i < childCount; ++i)
     {
         daeElementRef childElement = children[i];
-        if (childElement->typeID() == COLLADA_TYPE::NODE)
+        if (childElement->typeID() == domNode::ID())
         {
             domNodeRef childNode = daeSafeCast<domNode>(childElement);
             getAnimationChannels(childNode, channels);
@@ -115,7 +115,7 @@ void getJointNames(const domSkin* skin, std::vector<std::string>& list)
 domSource* getInputSource(const domChannelRef& channel)
 {
     daeElement* element = channel->getSource().getElement();
-    if (element && element->typeID() == COLLADA_TYPE::SAMPLER)
+    if (element && element->typeID() == domSampler::ID())
     {
         domSampler* sampler = daeSafeCast<domSampler>(element);
         const domInputLocal_Array& inputArray = sampler->getInput_array();
@@ -126,7 +126,7 @@ domSource* getInputSource(const domChannelRef& channel)
             if (strcmp(input->getSemantic(), "INPUT") == 0)
             {
                 daeElement* e = input->getSource().getElement();
-                if (e && e->typeID() == COLLADA_TYPE::SOURCE)
+                if (e && e->typeID() == domSource::ID())
                 {
                     domSource* source = daeSafeCast<domSource>(e);
                     assert(source);
@@ -142,7 +142,7 @@ const domSamplerRef getSampler(const domChannelRef& channel)
 {
     const domURIFragmentType& uri = channel->getSource();
     daeElementRef element = uri.getElement();
-    if (element && element->typeID() == COLLADA_TYPE::SAMPLER)
+    if (element && element->typeID() == domSampler::ID())
     {
         const domSamplerRef sampler = daeSafeCast<domSampler>(element);
         return sampler;
@@ -150,7 +150,7 @@ const domSamplerRef getSampler(const domChannelRef& channel)
     // resolve the source manually by searching for the sampler in the animation that the channel is a child of.
     const std::string& id = uri.id();
     const daeElementRef& parent = channel->getParent();
-    if (parent && parent->typeID() == COLLADA_TYPE::ANIMATION)
+    if (parent && parent->typeID() == domAnimation::ID())
     {
         const domAnimationRef animation = daeSafeCast<domAnimation>(parent);
         
@@ -172,7 +172,7 @@ const domSourceRef getSource(const domInputLocalRef& inputLocal, const domAnimat
 {
     const domURIFragmentType& uri = inputLocal->getSource();
     daeElementRef element = uri.getElement();
-    if (element && element->typeID() == COLLADA_TYPE::SAMPLER)
+    if (element && element->typeID() == domSampler::ID())
     {
         const domSourceRef source = daeSafeCast<domSource>(element);
         return source;
@@ -205,7 +205,7 @@ const domName_arrayRef getSourceNameArray(const domSourceRef& source)
     for (size_t i = 0; i < childCount; ++i)
     {
         const daeElementRef element = children.get(i);
-        if (element->typeID() == COLLADA_TYPE::NAME_ARRAY)
+        if (element->typeID() == domName_array::ID())
         {
             return daeSafeCast<domName_array>(element);
         }
@@ -229,7 +229,7 @@ const domInstance_controller::domSkeletonRef getSkeleton(const domInstance_contr
     // Find the skeleton element that points to the root most node.
     const domInstance_controller::domSkeletonRef& currentSkeleton = skeletonArray.get(0);
     const daeElementRef element = currentSkeleton->getValue().getElement();
-    if (element && element->typeID() == COLLADA_TYPE::NODE)
+    if (element && element->typeID() == domNode::ID())
     {
         domNode* node = daeSafeCast<domNode>(element);
         int index = 0;
@@ -237,7 +237,7 @@ const domInstance_controller::domSkeletonRef getSkeleton(const domInstance_contr
         do
         {
             daeElementRef parent = node->getParent();
-            if (parent && parent->typeID() == COLLADA_TYPE::NODE)
+            if (parent && parent->typeID() == domNode::ID())
             {
                 domNodeRef parentNode = daeSafeCast<domNode>(parent);
                 int result = getIndex(skeletonArray, parentNode);
@@ -266,7 +266,7 @@ domNode* getRootJointNode(const domSkin* skin)
     getJointNames(skin, names);
     daeSIDResolver resolver(const_cast<domSkin*>(skin)->getDocument()->getDomRoot(), names[0].c_str());
     daeElement* element = resolver.getElement();
-    if (element && element->typeID() == COLLADA_TYPE::NODE)
+    if (element && element->typeID() == domNode::ID())
     {
         domNode* node = daeSafeCast<domNode>(resolver.getElement());
         return node;
@@ -326,7 +326,7 @@ void moveChannelAndSouresToAnimation(domChannelRef& channel, domAnimationRef& an
             inputArray = sampler->getInput_array();
             const domInputLocalRef& input = inputArray.get(i);
             daeElementRef element = input->getSource().getElement();
-            if (element && element->typeID() == COLLADA_TYPE::SOURCE)
+            if (element && element->typeID() == domSource::ID())
             {
                 domSourceRef source = daeSafeCast<domSource>(element);
                 assert(source);
@@ -355,7 +355,7 @@ int getIndex(const domInstance_controller::domSkeleton_Array& skeletonArray, con
     {
         const domInstance_controller::domSkeletonRef& skeleton = skeletonArray.get(i);
         daeElementRef element = skeleton->getValue().getElement();
-        if (element->typeID() == COLLADA_TYPE::NODE)
+        if (element->typeID() == domNode::ID())
         {
             domNodeRef targetNode = daeSafeCast<domNode>(element);
             if (nodeId.compare(targetNode->getId()) == 0)
@@ -395,7 +395,7 @@ void getAnimationChannels(const domAnimationRef& animationRef, const std::string
 domVisual_scene* getVisualScene(const domCOLLADA::domSceneRef& domScene)
 {
     daeElement* scene = domScene->getInstance_visual_scene()->getUrl().getElement();
-    if (scene->typeID() == COLLADA_TYPE::VISUAL_SCENE)
+    if (scene->typeID() == domVisual_scene::ID())
     {
         return static_cast<domVisual_scene*>(scene);
     }
@@ -425,7 +425,7 @@ domVisual_scene* getVisualScene(const domCOLLADA::domSceneRef& domScene)
 domNode* getParent(domNodeRef node)
 {
     daeElement* parent = node->getParent();
-    if (parent && parent->typeID() == COLLADA_TYPE::NODE)
+    if (parent && parent->typeID() == domNode::ID())
     {
         domNodeRef parentNode = daeSafeCast<domNode>(parent);
         return parentNode.cast();
@@ -436,7 +436,7 @@ domNode* getParent(domNodeRef node)
 domAnimation* getAnimation(domChannelRef channel)
 {
     daeElement* parent = channel->getParent();
-    if (parent && parent->typeID() == COLLADA_TYPE::ANIMATION)
+    if (parent && parent->typeID() == domAnimation::ID())
     {
         domAnimationRef parentNode = daeSafeCast<domAnimation>(parent);
         return parentNode.cast();
@@ -542,7 +542,7 @@ void findChannelsTargetingJoints(const domSourceRef& source, std::list<domChanne
     {
         daeSIDResolver resolver(source->getDocument()->getDomRoot(), i->c_str());
         daeElement* element = resolver.getElement();
-        if (element && element->typeID() == COLLADA_TYPE::NODE)
+        if (element && element->typeID() == domNode::ID())
         {
             domNodeRef node = daeSafeCast<domNode>(element);
             nodes.push_back(node);

+ 193 - 48
gameplay-encoder/src/EncoderArguments.cpp

@@ -8,6 +8,8 @@
     #define realpath(A,B)    _fullpath(B,A,PATH_MAX)
 #endif
 
+#define MAX_HEIGHTMAP_SIZE 2049
+
 namespace gameplay
 {
 
@@ -17,6 +19,7 @@ extern int __logVerbosity = 1;
 
 EncoderArguments::EncoderArguments(size_t argc, const char** argv) :
     _fontSize(0),
+    _normalMap(false),
     _parseError(false),
     _fontPreview(false),
     _textOutput(false),
@@ -25,6 +28,8 @@ EncoderArguments::EncoderArguments(size_t argc, const char** argv) :
 {
     __instance = this;
 
+    memset(_heightmapResolution, 0, sizeof(int) * 2);
+
     if (argc > 1)
     {
         // read the options
@@ -91,27 +96,41 @@ std::string EncoderArguments::getOutputDirPath() const
     }
 }
 
+std::string EncoderArguments::getOutputFileExtension() const
+{
+    switch (getFileFormat())
+    {
+    case FILEFORMAT_PNG:
+    case FILEFORMAT_RAW:
+        if (_normalMap)
+            return ".png";
+
+    default:
+        return ".gpb";
+    }
+}
+
 std::string EncoderArguments::getOutputFilePath() const
 {
     if (_fileOutputPath.size() > 0)
     {
+        // Output file explicitly set
         return _fileOutputPath;
     }
     else
     {
+        // Generate an output file path
         int pos = _filePath.find_last_of('.');
-        if (pos > 0)
-        {
-            std::string outputFilePath(_filePath.substr(0, pos));
-            outputFilePath.append(".gpb");
-            return outputFilePath;
-        }
-        else
+        std::string outputFilePath(pos > 0 ? _filePath.substr(0, pos) : _filePath);
+
+        // Modify the original file name if the output extension can be the same as the input
+        if (_normalMap)
         {
-            std::string outputFilePath(_filePath);
-            outputFilePath.append(".gpb");
-            return outputFilePath;
+            outputFilePath.append("_normalmap");
         }
+
+        outputFilePath.append(getOutputFileExtension());
+        return outputFilePath;
     }
 }
 
@@ -152,6 +171,22 @@ const std::vector<EncoderArguments::HeightmapOption>& EncoderArguments::getHeigh
     return _heightmaps;
 }
 
+bool EncoderArguments::normalMapGeneration() const
+{
+    return _normalMap;
+}
+
+void EncoderArguments::getHeightmapResolution(int* x, int* y) const
+{
+    *x = _heightmapResolution[0];
+    *y = _heightmapResolution[1];
+}
+
+const Vector3& EncoderArguments::getHeightmapWorldSize() const
+{
+    return _heightmapWorldSize;
+}
+
 bool EncoderArguments::parseErrorOccured() const
 {
     return _parseError;
@@ -170,6 +205,21 @@ bool EncoderArguments::fileExists() const
     return false;
 }
 
+void splitString(const char* str, std::vector<std::string>* tokens)
+{
+    // Split node id list into tokens
+    unsigned int length = strlen(str);
+    char* temp = new char[length + 1];
+    strcpy(temp, str);
+    char* tok = strtok(temp, ",");
+    while (tok)
+    {
+        tokens->push_back(tok);
+        tok = strtok(NULL, ",");
+    }
+    delete[] temp;
+}
+
 void EncoderArguments::printUsage() const
 {
     LOG(1, "Usage: gameplay-encoder [options] <input filepath> <output filepath>\n\n");
@@ -191,13 +241,28 @@ void EncoderArguments::printUsage() const
         "\t\tremoving any channels that contain default/identity values\n" \
         "\t\tand removing any duplicate contiguous keyframes, which are common\n" \
         "\t\twhen exporting baked animation data.\n");
-    LOG(1, "  -h \"<node ids>\" <filename>\n" \
+    LOG(1, "  -h <size> \"<node ids>\" <filename>\n" \
         "\t\tGenerates a single heightmap image using meshes from the specified\n" \
-        "\t\tnodes. Node id list should be in quotes with a space between each id.\n" \
+        "\t\tnodes. <size> should be two comma-separated numbers in the format\n" \
+        "\t\t\"X,Y\", indicating the dimensions of the produced heightmap image.\n" \
+        "\t\t<node ids> should be in quotes with a space between each id.\n" \
         "\t\tFilename is the name of the image (PNG) to be saved.\n" \
         "\t\tMultiple -h arguments can be supplied to generate more than one heightmap.\n" \
         "\t\tFor 24-bit packed height data use -hp instead of -h.\n");
     LOG(1, "\n");
+    LOG(1, "Normal map generation options:\n" \
+        "  -n\t\tGenerate normal map (requires input file of type PNG or RAW)\n" \
+        "  -s\t\tSize/resolution of the input heightmap image (requried for RAW files)\n" \
+        "  -w <size>\tSpecifies the size of an input terran heightmap file in world\n" \
+        "\t\tunits, along the X, Y and Z axes. <size> should be three comma-separated\n" \
+        "\t\tnumbers in the format \"X,Y,Z\". The Y value represents the maximum\n" \
+        "\t\tpossible height value of a full intensity heightmap pixel.\n" \
+        "\n" \
+        "  Normal map generation can be used to create object-space normal maps from heightmap\n" \
+        "  images. Heightmaps must be in either PNG format (where the intensity of each pixel\n" \
+        "  represents a height value), or in RAW format (8 or 16-bit), which is a common\n" \
+        "  headerless format supported by most terran generation tools.\n");
+    LOG(1, "\n");
     LOG(1, "TTF file options:\n");
     LOG(1, "  -s <size>\tSize of the font.\n");
     LOG(1, "  -p\t\tOutput font preview.\n");
@@ -252,24 +317,34 @@ EncoderArguments::FileFormat EncoderArguments::getFileFormat() const
     {
         ext = _filePath.substr(pos + 1);
     }
+    for (size_t i = 0; i < ext.size(); ++i)
+        ext[i] = (char)tolower(ext[i]);
     
     // Match every supported extension with its format constant
-    if (ext.compare("dae") == 0 || ext.compare("DAE") == 0)
+    if (ext.compare("dae") == 0)
     {
         return FILEFORMAT_DAE;
     }
-    if (ext.compare("fbx") == 0 || ext.compare("FBX") == 0)
+    if (ext.compare("fbx") == 0)
     {
         return FILEFORMAT_FBX;
     }
-    if (ext.compare("ttf") == 0 || ext.compare("TTF") == 0)
+    if (ext.compare("ttf") == 0)
     {
         return FILEFORMAT_TTF;
     }
-    if (ext.compare("gpb") == 0 || ext.compare("GPB") == 0)
+    if (ext.compare("gpb") == 0)
     {
         return FILEFORMAT_GPB;
     }
+    if (ext.compare("png") == 0)
+    {
+        return FILEFORMAT_PNG;
+    }
+    if (ext.compare("raw") == 0)
+    {
+        return FILEFORMAT_RAW;
+    }
 
     return FILEFORMAT_UNKNOWN;
 }
@@ -342,25 +417,36 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
             if (str.compare("-heightmap") == 0 || str.compare("-h") == 0 || isHighPrecision)
             {
                 (*index)++;
-                if (*index < (options.size() + 1))
+                if (*index < (options.size() + 2))
                 {
                     _heightmaps.resize(_heightmaps.size() + 1);
                     HeightmapOption& heightmap = _heightmaps.back();
                     
                     heightmap.isHighPrecision = isHighPrecision;
 
-                    // Split node id list into tokens
-                    unsigned int length = options[*index].size() + 1;
-                    char* nodeIds = new char[length];
-                    strcpy(nodeIds, options[*index].c_str());
-                    nodeIds[length-1] = 0;
-                    char* id = strtok(nodeIds, " ");
-                    while (id)
+                    // Read heightmap size
+                    std::vector<std::string> parts;
+                    splitString(options[*index].c_str(), &parts);
+                    if (parts.size() != 2)
                     {
-                        heightmap.nodeIds.push_back(id);
-                        id = strtok(NULL, " ");
+                        LOG(1, "Error: invalid size argument for -h|-heightmap.\n");
+                        _parseError = true;
+                        return;
+                    }
+                    heightmap.width = atoi(parts[0].c_str());
+                    heightmap.height = atoi(parts[1].c_str());
+
+                    // Put some artificial bounds on heightmap dimensions
+                    if (heightmap.width <= 0 || heightmap.height <= 0 || heightmap.width > MAX_HEIGHTMAP_SIZE || heightmap.height > MAX_HEIGHTMAP_SIZE)
+                    {
+                        LOG(1, "Error: size argument for -h|-heightmap must be between (1,1) and (%d,%d).\n", (int)MAX_HEIGHTMAP_SIZE, (int)MAX_HEIGHTMAP_SIZE);
+                        _parseError = true;
+                        return;
                     }
-                    delete[] nodeIds;
+
+                    // Split node id list into tokens
+                    (*index)++;
+                    splitString(options[*index].c_str(), &heightmap.nodeIds);
 
                     // Store output filename
                     (*index)++;
@@ -391,34 +477,90 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
             }
         }
         break;
+    case 'n':
+        _normalMap = true;
+        break;
+    case 'w':
+        {
+            // Read world size
+            (*index)++;
+            if (*index >= options.size())
+            {
+                LOG(1, "Error: missing world size argument for -w.\n");
+                _parseError = true;
+                return;
+            }
+            std::vector<std::string> parts;
+            splitString(options[*index].c_str(), &parts);
+            if (parts.size() != 3)
+            {
+                LOG(1, "Error: invalid world size argument for -w.\n");
+                _parseError = true;
+                return;
+            }
+            _heightmapWorldSize.x = (float)atof(parts[0].c_str());
+            _heightmapWorldSize.y = (float)atof(parts[1].c_str());
+            _heightmapWorldSize.z = (float)atof(parts[2].c_str());
+            if (_heightmapWorldSize.x == 0 || _heightmapWorldSize.y == 0 || _heightmapWorldSize.z == 0)
+            {
+                LOG(1, "Error: invalid world size argument for -w.\n");
+                _parseError = true;
+                return;
+            }
+        }
+        break;
     case 'p':
         _fontPreview = true;
         break;
     case 's':
-        // Font Size
-
-        // old format was -s##
-        if (str.length() > 2)
+        if (_normalMap)
         {
-            char n = str[2];
-            if (n > '0' && n <= '9')
+            (*index)++;
+            if (*index >= options.size())
             {
-                const char* number = str.c_str() + 2;
-                _fontSize = atoi(number);
-                break;
+                LOG(1, "Error: missing argument for -s.\n");
+                _parseError = true;
+                return;
+            }
+            // Heightmap size
+            std::vector<std::string> parts;
+            splitString(options[*index].c_str(), &parts);
+            if (parts.size() != 2 ||
+                (_heightmapResolution[0] = atoi(parts[0].c_str())) <= 0 ||
+                (_heightmapResolution[1] = atoi(parts[1].c_str())) <= 0)
+            {
+                LOG(1, "Error: invalid argument for -s.\n");
+                _parseError = true;
+                return;
             }
-        }
-
-        (*index)++;
-        if (*index < options.size())
-        {
-            _fontSize = atoi(options[*index].c_str());
         }
         else
         {
-            LOG(1, "Error: missing arguemnt for -%c.\n", str[1]);
-            _parseError = true;
-            return;
+            // Font Size
+
+            // old format was -s##
+            if (str.length() > 2)
+            {
+                char n = str[2];
+                if (n > '0' && n <= '9')
+                {
+                    const char* number = str.c_str() + 2;
+                    _fontSize = atoi(number);
+                    break;
+                }
+            }
+
+            (*index)++;
+            if (*index < options.size())
+            {
+                _fontSize = atoi(options[*index].c_str());
+            }
+            else
+            {
+                LOG(1, "Error: missing arguemnt for -%c.\n", str[1]);
+                _parseError = true;
+                return;
+            }
         }
         break;
     case 't':
@@ -434,6 +576,7 @@ void EncoderArguments::readOption(const std::vector<std::string>& options, size_
             else if (__logVerbosity > 4)
                 __logVerbosity = 4;
         }
+        break;
     default:
         break;
     }
@@ -446,10 +589,12 @@ void EncoderArguments::setInputfilePath(const std::string& inputPath)
 
 void EncoderArguments::setOutputfilePath(const std::string& outputPath)
 {
+    std::string ext = getOutputFileExtension();
+
     if (outputPath.size() > 0 && outputPath[0] != '\0')
     {
         std::string realPath = getRealPath(outputPath);
-        if (endsWith(realPath.c_str(), ".gpb"))
+        if (endsWith(realPath.c_str(), ext.c_str()))
         {
             _fileOutputPath.assign(realPath);
         }
@@ -459,7 +604,7 @@ void EncoderArguments::setOutputfilePath(const std::string& outputPath)
 
             _fileOutputPath.assign(outputPath);
             _fileOutputPath.append(filenameNoExt);
-            _fileOutputPath.append(".gpb");
+            _fileOutputPath.append(ext);
         }
         else
         {
@@ -470,7 +615,7 @@ void EncoderArguments::setOutputfilePath(const std::string& outputPath)
                 _fileOutputPath = realPath.substr(0, pos);
                 _fileOutputPath.append("/");
                 _fileOutputPath.append(filenameNoExt);
-                _fileOutputPath.append(".gpb");
+                _fileOutputPath.append(ext);
             }
         }
     }

+ 42 - 1
gameplay-encoder/src/EncoderArguments.h

@@ -1,6 +1,8 @@
 #ifndef ENCODERARGUMENTS_H_
 #define ENCODERARGUMENTS_H_
 
+#include "Vector3.h"
+
 namespace gameplay
 {
 
@@ -17,7 +19,9 @@ public:
         FILEFORMAT_DAE,
         FILEFORMAT_FBX,
         FILEFORMAT_TTF,
-        FILEFORMAT_GPB
+        FILEFORMAT_GPB,
+        FILEFORMAT_PNG,
+        FILEFORMAT_RAW
     };
 
     struct HeightmapOption
@@ -25,6 +29,15 @@ public:
         std::vector<std::string> nodeIds;
         std::string filename;
         bool isHighPrecision;
+        int width;
+        int height;
+    };
+
+    struct NormalMapOption
+    {
+        std::string inputFile;
+        std::string outputFile;
+        Vector3 worldSize;
     };
 
     /**
@@ -74,6 +87,11 @@ public:
      */
     std::string getOutputFilePath() const;
 
+    /**
+     * Returns the output file extension.
+     */
+    std::string getOutputFileExtension() const;
+
     const std::vector<std::string>& getGroupAnimationNodeId() const;
     const std::vector<std::string>& getGroupAnimationAnimationId() const;
 
@@ -82,6 +100,25 @@ public:
 
     const std::vector<HeightmapOption>& getHeightmapOptions() const;
 
+    /**
+     * Returns true if normal map generation is turned on.
+     */
+    bool normalMapGeneration() const;
+    
+    /**
+     * Returns the supplied intput heightmap resolution.
+     *
+     * This option is only applicable for normal map generation.
+     */
+    void getHeightmapResolution(int* x, int* y) const;
+
+    /**
+     * Returns world size option.
+     *
+     * This option is only applicable for normal map generation.
+     */
+    const Vector3& getHeightmapWorldSize() const;
+    
     /**
      * Returns true if an error occurred while parsing the command line arguments.
      */
@@ -143,6 +180,10 @@ private:
 
     unsigned int _fontSize;
 
+    bool _normalMap;
+    Vector3 _heightmapWorldSize;
+    int _heightmapResolution[2];
+
     bool _parseError;
     bool _fontPreview;
     bool _textOutput;

+ 114 - 29
gameplay-encoder/src/FBXSceneEncoder.cpp

@@ -54,27 +54,30 @@ static void loadNormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex,
  * 
  * @param fbxMesh The mesh to load from.
  * @param vertexIndex The index of the vertex within fbxMesh.
+ * @param controlPointIndex The control point index.
  * @param vertex The vertex to copy to.
  */
-static void loadTangent(FbxMesh* fbxMesh, int vertexIndex, Vertex* vertex);
+static void loadTangent(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
 
 /**
  * Loads the binormal from the mesh and adds it to the given vertex.
  * 
  * @param fbxMesh The mesh to load from.
  * @param vertexIndex The index of the vertex within fbxMesh.
+ * @param controlPointIndex The control point index.
  * @param vertex The vertex to copy to.
  */
-static void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, Vertex* vertex);
+static void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
 
 /**
  * Loads the vertex diffuse color from the mesh and adds it to the given vertex.
  * 
  * @param fbxMesh The mesh to load from.
  * @param vertexIndex The index of the vertex within fbxMesh.
+ * @param controlPointIndex The control point index.
  * @param vertex The vertex to copy to.
  */
-static void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, Vertex* vertex);
+static void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex);
 
 /**
  * Loads the blend weight and blend indices data into the vertex.
@@ -309,8 +312,8 @@ void FBXSceneEncoder::loadScene(FbxScene* fbxScene)
 void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fbxNode, Animation* animation)
 {
     const char* name = fbxNode->GetName();
-    Node* node = _gamePlayFile.getNode(name);
-    
+    //Node* node = _gamePlayFile.getNode(name);
+
     // Determine which properties are animated on this node
     // Find the transform at each key frame
     // TODO: Ignore properties that are not animated (scale, rotation, translation)
@@ -466,6 +469,7 @@ void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fb
     assert(channelCount > 0);
 
     // Allocate channel list
+    int channelStart = animation->getAnimationChannelCount();
     for (unsigned int i = 0; i < channelCount; ++i)
     {
         AnimationChannel* channel = new AnimationChannel();
@@ -499,7 +503,7 @@ void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fb
         rotation.normalize();
 
         // Append keyframe data to all channels
-        for (unsigned int i = 0; i < channelCount; ++i)
+        for (unsigned int i = channelStart, channelEnd = channelStart + channelCount; i < channelEnd; ++i)
         {
             appendKeyFrame(fbxNode, animation->getAnimationChannel(i), time, scale, rotation, translation);
         }
@@ -517,18 +521,14 @@ void FBXSceneEncoder::loadAnimationLayer(FbxAnimLayer* fbxAnimLayer, FbxNode* fb
     bool animationGroupId = false;
     const char* name = fbxNode->GetName();
     // Check if this node's animations are supposed to be grouped
-    if (name)
+    if (name && arguments.containsGroupNodeId(name))
     {
-        std::string str = name;
-        if (arguments.containsGroupNodeId(str))
-        {
-            animationGroupId = true;
-            _groupAnimation = new Animation();
-            _groupAnimation->setId(arguments.getAnimationId(str));
-        }
+        animationGroupId = true;
+        _groupAnimation = new Animation();
+        _groupAnimation->setId(arguments.getAnimationId(name));
     }
     Animation* animation = _groupAnimation;
-    if (!_groupAnimation)
+    if (!animation)
     {
         animation = new Animation();
         animation->setId(name);
@@ -857,8 +857,7 @@ void FBXSceneEncoder::loadSkin(FbxMesh* fbxMesh, Model* model)
                 FbxCluster* cluster = fbxSkin->GetCluster(j);
                 assert(cluster);
                 FbxNode* linkedNode = cluster->GetLink();
-                assert(linkedNode);
-                if (linkedNode->GetSkeleton())
+                if (linkedNode && linkedNode->GetSkeleton())
                 {
                     const char* jointName = linkedNode->GetName();
                     assert(jointName);
@@ -946,9 +945,9 @@ Mesh* FBXSceneEncoder::loadMesh(FbxMesh* fbxMesh)
 
             // Load other data
             loadNormal(fbxMesh, vertexIndex, controlPointIndex, &vertex);
-            loadTangent(fbxMesh, vertexIndex, &vertex);
-            loadBinormal(fbxMesh, vertexIndex, &vertex);
-            loadVertexColor(fbxMesh, vertexIndex, &vertex);
+            loadTangent(fbxMesh, vertexIndex, controlPointIndex, &vertex);
+            loadBinormal(fbxMesh, vertexIndex, controlPointIndex, &vertex);
+            loadVertexColor(fbxMesh, vertexIndex, controlPointIndex, &vertex);
 
             if (hasSkin)
             {
@@ -1238,13 +1237,41 @@ void loadNormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex
     }
 }
 
-void loadTangent(FbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
+void loadTangent(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
 {
     if (fbxMesh->GetElementTangentCount() > 0)
     {
         // Get only the first tangent
         FbxGeometryElementTangent* tangent = fbxMesh->GetElementTangent(0);
-        if (tangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
+        FbxGeometryElement::EMappingMode mappingMode = tangent->GetMappingMode();
+        if (mappingMode == FbxGeometryElement::eByControlPoint)
+        {
+            switch (tangent->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(controlPointIndex);
+                    vertex->hasTangent = true;
+                    vertex->tangent.x = (float)vec4[0];
+                    vertex->tangent.y = (float)vec4[1];
+                    vertex->tangent.z = (float)vec4[2];
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = tangent->GetIndexArray().GetAt(controlPointIndex);
+                    FbxVector4 vec4 = tangent->GetDirectArray().GetAt(id);
+                    vertex->hasTangent = true;
+                    vertex->tangent.x = (float)vec4[0];
+                    vertex->tangent.y = (float)vec4[1];
+                    vertex->tangent.z = (float)vec4[2];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
         {
             switch (tangent->GetReferenceMode())
             {
@@ -1274,13 +1301,42 @@ void loadTangent(FbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
     }
 }
 
-void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
+void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
 {
     if (fbxMesh->GetElementBinormalCount() > 0)
     {
         // Get only the first binormal.
         FbxGeometryElementBinormal* binormal = fbxMesh->GetElementBinormal(0);
-        if (binormal->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
+        FbxGeometryElement::EMappingMode mappingMode = binormal->GetMappingMode();
+
+        if (mappingMode == FbxGeometryElement::eByControlPoint)
+        {
+            switch (binormal->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(controlPointIndex);
+                    vertex->hasBinormal = true;
+                    vertex->binormal.x = (float)vec4[0];
+                    vertex->binormal.y = (float)vec4[1];
+                    vertex->binormal.z = (float)vec4[2];
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = binormal->GetIndexArray().GetAt(controlPointIndex);
+                    FbxVector4 vec4 = binormal->GetDirectArray().GetAt(id);
+                    vertex->hasBinormal = true;
+                    vertex->binormal.x = (float)vec4[0];
+                    vertex->binormal.y = (float)vec4[1];
+                    vertex->binormal.z = (float)vec4[2];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
         {
             switch (binormal->GetReferenceMode())
             {
@@ -1310,13 +1366,45 @@ void loadBinormal(FbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
     }
 }
 
-void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, Vertex* vertex)
+void loadVertexColor(FbxMesh* fbxMesh, int vertexIndex, int controlPointIndex, Vertex* vertex)
 {
     if (fbxMesh->GetElementVertexColorCount() > 0)
     {
         // Get only the first vertex color.
         FbxGeometryElementVertexColor* vertexColor = fbxMesh->GetElementVertexColor(0);
-        if (vertexColor->GetMappingMode() == FbxGeometryElement::eByPolygonVertex)
+        FbxGeometryElement::EMappingMode mappingMode = vertexColor->GetMappingMode();
+        if (mappingMode == FbxGeometryElement::eByControlPoint)
+        {
+            switch (vertexColor->GetReferenceMode())
+            {
+            case FbxGeometryElement::eDirect:
+                {
+                    FbxColor color = vertexColor->GetDirectArray().GetAt(controlPointIndex);
+
+                    vertex->hasDiffuse = true;
+                    vertex->diffuse.x = (float)color.mRed;
+                    vertex->diffuse.y = (float)color.mGreen;
+                    vertex->diffuse.z = (float)color.mBlue;
+                    vertex->diffuse.w = (float)color.mAlpha;
+                }
+                break;
+            case FbxGeometryElement::eIndexToDirect:
+                {
+                    int id = vertexColor->GetIndexArray().GetAt(controlPointIndex);
+                    FbxColor color = vertexColor->GetDirectArray().GetAt(id);
+
+                    vertex->hasDiffuse = true;
+                    vertex->diffuse.x = (float)color.mRed;
+                    vertex->diffuse.y = (float)color.mGreen;
+                    vertex->diffuse.z = (float)color.mBlue;
+                    vertex->diffuse.w = (float)color.mAlpha;
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        else if (mappingMode == FbxGeometryElement::eByPolygonVertex)
         {
             switch (vertexColor->GetReferenceMode())
             {
@@ -1398,9 +1486,6 @@ bool loadBlendWeights(FbxMesh* fbxMesh, std::vector<std::vector<Vector2> >& weig
             {
                 FbxCluster* cluster = fbxSkin->GetCluster(j);
                 assert(cluster);
-                FbxNode* linkedNode = cluster->GetLink();
-                assert(linkedNode);
-
                 const int vertexIndexCount = cluster->GetControlPointIndicesCount();
                 for (int k = 0; k < vertexIndexCount; ++k)
                 {

+ 2 - 2
gameplay-encoder/src/FileIO.h

@@ -29,7 +29,7 @@ void fprintfElement(FILE* file, const char* elementName, const std::string& valu
 void fprintfElement(FILE* file, const char* elementName, const float values[], int length);
 
 template <class T>
-void fprintfElement(FILE* file, const char* format, const char* elementName, std::vector<T> list)
+void fprintfElement(FILE* file, const char* format, const char* elementName, std::vector<T>& list)
 {
     fprintf(file, "<%s count=\"%lu\">", elementName, list.size());
     typename std::vector<T>::const_iterator i;
@@ -41,7 +41,7 @@ void fprintfElement(FILE* file, const char* format, const char* elementName, std
 }
 
 template <class T>
-void fprintfElement(FILE* file, const char* format, const char* elementName, std::list<T> list)
+void fprintfElement(FILE* file, const char* format, const char* elementName, std::list<T>& list)
 {
     fprintf(file, "<%s count=\"%lu\">", elementName, list.size());
     typename std::list<T>::const_iterator i;

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

@@ -338,7 +338,7 @@ void GPBFile::adjust()
     const std::vector<EncoderArguments::HeightmapOption>& heightmaps = EncoderArguments::getInstance()->getHeightmapOptions();
     for (unsigned int i = 0, count = heightmaps.size(); i < count; ++i)
     {
-        Heightmap::generate(heightmaps[i].nodeIds, heightmaps[i].filename.c_str(), heightmaps[i].isHighPrecision);
+        Heightmap::generate(heightmaps[i].nodeIds, heightmaps[i].width, heightmaps[i].height, heightmaps[i].filename.c_str(), heightmaps[i].isHighPrecision);
     }
 }
 

+ 42 - 29
gameplay-encoder/src/Heightmap.cpp

@@ -1,3 +1,4 @@
+#include "Base.h"
 #include "Heightmap.h"
 #include "GPBFile.h"
 #include "Thread.h"
@@ -15,13 +16,17 @@ struct HeightmapThreadData
     const Vector3* rayDirection;        // [in]
     const std::vector<Mesh*>* meshes;   // [in]
     const BoundingVolume* bounds;       // [in]
-    int minX;                           // [in]
-    int maxX;                           // [in]
-    int minZ;                           // [in]
-    int maxZ;                           // [in]
+    float minX;                         // [in]
+    float maxX;                         // [in]
+    float minZ;                         // [in]
+    float maxZ;                         // [in]
+    float stepX;                        // [in]
+    float stepZ;                        // [in]
     float minHeight;                    // [out]
     float maxHeight;                    // [out]
     float* heights;                     // [in][out]
+    int width;                          // [in]
+    int height;                         // [in]
     int heightIndex;                    // [in]
 };
 
@@ -36,7 +41,7 @@ bool intersect(const Vector3& rayOrigin, const Vector3& rayDirection, const Vect
 int intersect_triangle(const float orig[3], const float dir[3], const float vert0[3], const float vert1[3], const float vert2[3], float *t, float *u, float *v);
 bool intersect(const Vector3& rayOrigin, const Vector3& rayDirection, const std::vector<Vertex>& vertices, const std::vector<MeshPart*>& parts, Vector3* point);
 
-void Heightmap::generate(const std::vector<std::string>& nodeIds, const char* filename, bool highP)
+void Heightmap::generate(const std::vector<std::string>& nodeIds, int width, int height, const char* filename, bool highP)
 {
     LOG(1, "Generating heightmap: %s...\n", filename);
 
@@ -92,12 +97,10 @@ void Heightmap::generate(const std::vector<std::string>& nodeIds, const char* fi
     Vector3 rayOrigin(0, bounds.max.y + 10, 0);
     Vector3 rayDirection(0, -1, 0);
 
-    int minX = (int)ceil(bounds.min.x);
-    int maxX = (int)floor(bounds.max.x);
-    int minZ = (int)ceil(bounds.min.z);
-    int maxZ = (int)floor(bounds.max.z);
-    int width = maxX - minX + 1;
-    int height = maxZ - minZ + 1;
+    float minX = bounds.min.x;
+    float maxX = bounds.max.x;
+    float minZ = bounds.min.z;
+    float maxZ = bounds.max.z;
     int size = width * height;
     float* heights = new float[size];
     float minHeight = FLT_MAX;
@@ -105,11 +108,14 @@ void Heightmap::generate(const std::vector<std::string>& nodeIds, const char* fi
 
     __totalHeightmapScanlines = height;
 
+    // Determine # of threads to spawn
+    int threadCount = min(THREAD_COUNT, height);
+
     // Split the work into separate threads to make max use of available cpu cores and speed up computation.
-    HeightmapThreadData threadData[THREAD_COUNT];
-    THREAD_HANDLE threads[THREAD_COUNT];
-    int stepSize = height / THREAD_COUNT;
-    for (int i = 0; i < THREAD_COUNT; ++i)
+    HeightmapThreadData* threadData = new HeightmapThreadData[threadCount];
+    THREAD_HANDLE* threads = new THREAD_HANDLE[threadCount];
+    int stepSize = height / threadCount;
+    for (int i = 0, remaining = height; i < threadCount; ++i, remaining -= stepSize)
     {
         HeightmapThreadData& data = threadData[i];
         data.rayHeight = rayOrigin.y;
@@ -120,9 +126,13 @@ void Heightmap::generate(const std::vector<std::string>& nodeIds, const char* fi
         data.maxX = maxX;
         data.minZ = minZ + (stepSize * i);
         data.maxZ = data.minZ + stepSize - 1;
-        if (i == THREAD_COUNT - 1)
+        if (i == threadCount - 1)
             data.maxZ = maxZ;
+        data.stepX = (maxX - minX) / width;
+        data.stepZ = (maxZ - minZ) / height;
         data.heights = heights;
+        data.width = width;
+        data.height = remaining > stepSize ? stepSize : remaining;
         data.heightIndex = width * (stepSize * i);
 
         // Start the processing thread
@@ -134,14 +144,14 @@ void Heightmap::generate(const std::vector<std::string>& nodeIds, const char* fi
     }
 
     // Wait for all threads to terminate
-    waitForThreads(THREAD_COUNT, threads);
+    waitForThreads(threadCount, threads);
 
     // Close all thread handles and free memory allocations.
-    for (int i = 0; i < THREAD_COUNT; ++i)
+    for (int i = 0; i < threadCount; ++i)
         closeThread(threads[i]);
 
     // Update min/max height from all completed threads
-    for (int i = 0; i < THREAD_COUNT; ++i)
+    for (int i = 0; i < threadCount; ++i)
     {
         if (threadData[i].minHeight < minHeight)
             minHeight = threadData[i].minHeight;
@@ -153,7 +163,7 @@ void Heightmap::generate(const std::vector<std::string>& nodeIds, const char* fi
 
     if (__failedRayCasts)
     {
-        LOG(1, "Warning: %d triangle intersections failed for heightmap: %s\n", __failedRayCasts, filename);
+        LOG(2, "Warning: %d triangle intersections failed for heightmap: %s\n", __failedRayCasts, filename);
 
         // Go through and clamp any height values that are set to -FLT_MAX to the min recorded height value
         // (otherwise the range of height values will be far too large).
@@ -234,6 +244,10 @@ void Heightmap::generate(const std::vector<std::string>& nodeIds, const char* fi
     LOG(1, "Saved heightmap: %s\n", filename);
 
 error:
+    if (threadData)
+        delete[] threadData;
+    if (threads)
+        delete[] threads;
     if (heights)
         delete[] heights;
     if (fp)
@@ -252,10 +266,6 @@ int generateHeightmapChunk(void* threadData)
 
     Vector3 rayOrigin(0, data->rayHeight, 0);
     const Vector3& rayDirection = *data->rayDirection;
-    int minX = data->minX;
-    int maxX = data->maxX;
-    int minZ = data->minZ;
-    int maxZ = data->maxZ;
     const std::vector<Mesh*>& meshes = *data->meshes;
     float* heights = data->heights;
 
@@ -264,15 +274,18 @@ int generateHeightmapChunk(void* threadData)
     float maxHeight = -FLT_MAX;
     int index = data->heightIndex;
 
-    for (int z = minZ; z <= maxZ; ++z)
+    int zi = 0;
+    for (float z = data->minZ; zi < data->height; z += data->stepZ, ++zi)
     {
         LOG(1, "\r\t%d%%", (int)(((float)__processedHeightmapScanLines / __totalHeightmapScanlines) * 100.0f));
 
-        rayOrigin.z = (float)z;
-        for (int x = minX; x <= maxX; ++x)
+        rayOrigin.z = z;
+
+        int xi = 0;
+        for (float x = data->minX; xi < data->width; x += data->stepX, ++xi)
         {
             float h = -FLT_MAX;
-            rayOrigin.x = (float)x;
+            rayOrigin.x = x;
 
             for (unsigned int i = 0, count = meshes.size(); i < count; ++i)
             {
@@ -283,7 +296,7 @@ int generateHeightmapChunk(void* threadData)
                 if (!intersect(rayOrigin, rayDirection, mesh->bounds.min, mesh->bounds.max))
                     continue;
 
-                // Computer intersection point of ray with mesh
+                // Compute the intersection point of ray with mesh
                 if (intersect(rayOrigin, rayDirection, mesh->vertices, mesh->parts, &intersectionPoint))
                 {
                     if (intersectionPoint.y > h)

+ 3 - 2
gameplay-encoder/src/Heightmap.h

@@ -14,11 +14,12 @@ public:
      * Generates heightmap data and saves the result to the specified filename (PNG file).
      *
      * @param nodeIds List of node ids to include in the heightmap generation.
+     * @param width Width of the produced heightmap image.
+     * @param height Height of the produced  heightmap image.
      * @param filename Output PNG file to write the heightmap image to.
      * @param highP Use packed 24-bit (RGB) instead of standard 8-bit grayscale.
      */
-    static void generate(const std::vector<std::string>& nodeIds, const char* filename, bool highP = false);
-
+    static void generate(const std::vector<std::string>& nodeIds, int width, int height, const char* filename, bool highP = false);
 
 };
 

+ 264 - 0
gameplay-encoder/src/Image.cpp

@@ -0,0 +1,264 @@
+#include "Image.h"
+#include "Base.h"
+
+namespace gameplay
+{
+
+Image::Image() :
+    _data(NULL), _format(RGBA), _width(0), _height(0), _bpp(0)
+{
+}
+
+Image::~Image()
+{
+    delete[] _data;
+}
+
+Image* Image::create(const char* path)
+{
+    // Open the file.
+    FILE* fp = fopen(path, "rb");
+    if (fp == NULL)
+    {
+        LOG(1, "Failed to open image file '%s'.\n", path);
+        return NULL;
+    }
+
+    // Verify PNG signature.
+    unsigned char sig[8];
+    if (fread(sig, 1, 8, fp) != 8 || png_sig_cmp(sig, 0, 8) != 0)
+    {
+        LOG(1, "Failed to load file '%s'; not a valid PNG.\n", path);
+        if (fclose(fp) != 0)
+        {
+            LOG(1, "Failed to close image file '%s'.\n", path);
+        }
+        return NULL;
+    }
+
+    // Initialize png read struct (last three parameters use stderr+longjump if NULL).
+    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (png == NULL)
+    {
+        LOG(1, "Failed to create PNG structure for reading PNG file '%s'.\n", path);
+        if (fclose(fp) != 0)
+        {
+            LOG(1, "Failed to close image file '%s'.\n", path);
+        }
+        return NULL;
+    }
+
+    // Initialize info struct.
+    png_infop info = png_create_info_struct(png);
+    if (info == NULL)
+    {
+        LOG(1, "Failed to create PNG info structure for PNG file '%s'.\n", path);
+        if (fclose(fp) != 0)
+        {
+            LOG(1, "Failed to close image file '%s'.\n", path);
+        }
+        png_destroy_read_struct(&png, NULL, NULL);
+        return NULL;
+    }
+
+    // Initialize file io.
+    png_init_io(png, fp);
+
+    // Indicate that we already read the first 8 bytes (signature).
+    png_set_sig_bytes(png, 8);
+
+    // Read the entire image into memory.
+    png_read_png(png, info, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL);
+
+    Image* image = new Image();
+    image->_width = png_get_image_width(png, info);
+    image->_height = png_get_image_height(png, info);
+
+    png_byte colorType = png_get_color_type(png, info);
+    switch (colorType)
+    {
+    case PNG_COLOR_TYPE_GRAY:
+        image->_bpp = 1;
+        image->_format = Image::LUMINANCE;
+        break;
+
+    case PNG_COLOR_TYPE_RGBA:
+        image->_bpp = 4;
+        image->_format = Image::RGBA;
+        break;
+
+    case PNG_COLOR_TYPE_RGB:
+        image->_bpp = 3;
+        image->_format = Image::RGB;
+        break;
+
+    default:
+        LOG(1, "Unsupported PNG color type (%d) for image file '%s'.\n", (int)colorType, path);
+        if (fclose(fp) != 0)
+        {
+            LOG(1, "Failed to close image file '%s'.\n", path);
+        }
+        png_destroy_read_struct(&png, &info, NULL);
+        return NULL;
+    }
+
+    size_t stride = png_get_rowbytes(png, info);
+
+    // Allocate image data.
+    image->_data = new unsigned char[stride * image->_height];
+
+    // Read rows into image data.
+    png_bytepp rows = png_get_rows(png, info);
+    for (unsigned int i = 0; i < image->_height; ++i)
+    {
+        memcpy(image->_data+(stride * i), rows[i], stride);
+    }
+
+    // Clean up.
+    png_destroy_read_struct(&png, &info, NULL);
+    if (fclose(fp) != 0)
+    {
+        LOG(1, "Failed to close image file '%s'.\n", path);
+    }
+
+    return image;
+}
+
+Image* Image::create(Format format, unsigned int width, unsigned int height)
+{
+    unsigned int bpp;
+    switch (format)
+    {
+    case LUMINANCE:
+        bpp = 1;
+        break;
+    case RGB:
+        bpp = 3;
+        break;
+    case RGBA:
+        bpp = 4;
+        break;
+    default:
+        LOG(1, "Invalid image format passed to create.\n");
+        return NULL;
+    }
+
+    Image* image = new Image();
+    image->_format = format;
+    image->_width = width;
+    image->_height = height;
+    image->_bpp = bpp;
+    image->_data = new unsigned char[width * height * bpp];
+    memset(image->_data, 0, width * height * bpp);
+    return image;
+}
+
+void* Image::getData() const
+{
+    return _data;
+}
+
+void Image::setData(void* data)
+{
+    memcpy(_data, data, _width * _height * _bpp);
+}
+
+Image::Format Image::getFormat() const
+{
+    return _format;
+}
+
+unsigned int Image::getHeight() const
+{
+    return _height;
+}
+        
+unsigned int Image::getWidth() const
+{
+    return _width;
+}
+
+unsigned int Image::getBpp() const
+{
+    return _bpp;
+}
+
+int getPNGColorType(Image::Format format)
+{
+    switch (format)
+    {
+    case Image::LUMINANCE:
+        return PNG_COLOR_TYPE_GRAY;
+    case Image::RGB:
+        return PNG_COLOR_TYPE_RGB;
+    case Image::RGBA:
+        return PNG_COLOR_TYPE_RGBA;
+    }
+
+    return PNG_COLOR_TYPE_RGBA;
+}
+
+void Image::save(const char* path)
+{
+    png_structp png_ptr = NULL;
+    png_infop info_ptr = NULL;
+    png_bytep row = NULL;
+    unsigned int stride;
+    int index;
+
+    FILE* fp = fopen(path, "wb");
+    if (fp == NULL)
+    {
+        LOG(1, "Error: Failed to open image for writing: %s\n", path);
+        goto error;
+    }
+
+    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (png_ptr == NULL)
+    {
+        LOG(1, "Error: Write struct creation failed: %s\n", path);
+        goto error;
+    }
+
+    info_ptr = png_create_info_struct(png_ptr);
+    if (info_ptr == NULL)
+    {
+        LOG(1, "Error: Info struct creation failed: %s\n", path);
+        goto error;
+    }
+
+    png_init_io(png_ptr, fp);
+
+    png_set_IHDR(png_ptr, info_ptr, _width, _height, 8, getPNGColorType(_format), PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+    png_write_info(png_ptr, info_ptr);
+
+    // Allocate memory for a single row of image data
+    stride = _bpp * _width * sizeof(png_byte);
+    row = (png_bytep)malloc(stride);
+
+    index = 0;
+    for (unsigned int y = 0; y < _height; ++y)
+    {
+        for (unsigned int x = 0; x < stride; ++x)
+        {
+            // Write data
+            row[x] = (png_byte)_data[index++];
+        }
+        png_write_row(png_ptr, row);
+    }
+
+    png_write_end(png_ptr, NULL);
+
+error:
+    if (fp)
+        fclose(fp);
+    if (row)
+        free(row);
+    if (info_ptr)
+        png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+    if (png_ptr)
+        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+}
+
+}

+ 123 - 0
gameplay-encoder/src/Image.h

@@ -0,0 +1,123 @@
+#ifndef IMAGE_H__
+#define IMAGE_H__
+
+namespace gameplay
+{
+
+/**
+ * Represents an image (currently only supports PNG files).
+ */
+class Image
+{
+public:
+
+    /**
+     * Defines the set of supported image formats.
+     */
+    enum Format
+    {
+        LUMINANCE,
+        RGB,
+        RGBA
+    };
+
+    /**
+     * Destructor.
+     */
+    ~Image();
+
+    /**
+     * Creates an image from the image file at the given path.
+     * 
+     * @param path The path to the image file.
+     * @return The newly created image.
+     */
+    static Image* create(const char* path);
+
+    /**
+     * Creates a new empty image of the given format and size.
+     *
+     * @param format Image format.
+     * @param width Image width.
+     * @param height Image height.
+     * @return The newly created image.
+     */
+    static Image* create(Format format, unsigned int width, unsigned int height);
+
+    /**
+     * Gets the image's raw pixel data.
+     * 
+     * @return The image's pixel data.
+     */
+    void* getData() const;
+
+    /** 
+     * Sets the image's raw pixel data.
+     *
+     * The passed in data MUST be at least width*height*bpp
+     * bytes of data.
+     */
+    void setData(void* data);
+
+    /**
+     * Gets the image's format.
+     * 
+     * @return The image's format.
+     */
+    Format getFormat() const;
+
+    /**
+     * Gets the height of the image.
+     * 
+     * @return The height of the image.
+     */
+    unsigned int getHeight() const;
+        
+    /**
+     * Gets the width of the image.
+     * 
+     * @return The width of the image.
+     */
+    unsigned int getWidth() const;
+
+    /**
+     * Returns the number of bytes per pixel for this image.
+     *
+     * @return The number of bytes per pixel.
+     */
+    unsigned int getBpp() const;
+
+    /**
+     * Saves the contents of the image as a PNG to the specified location.
+     *
+     * @param path Path to save to.
+     */
+    void save(const char* path);
+
+private:
+
+    /**
+     * Hidden constructor.
+     */
+    Image();
+
+    /**
+     * Hidden copy constructor.
+     */
+    Image(const Image&);
+
+    /**
+     * Hidden copy assignment operator.
+     */
+    Image& operator=(const Image&);
+
+    unsigned char* _data;
+    Format _format;
+    unsigned int _height;
+    unsigned int _width;
+    unsigned int _bpp;
+};
+
+}
+
+#endif

+ 329 - 0
gameplay-encoder/src/NormalMapGenerator.cpp

@@ -0,0 +1,329 @@
+#include "NormalMapGenerator.h"
+#include "Image.h"
+#include "Base.h"
+
+namespace gameplay
+{
+
+NormalMapGenerator::NormalMapGenerator(const char* inputFile, const char* outputFile, int resolutionX, int resolutionY, const Vector3& worldSize)
+    : _inputFile(inputFile), _outputFile(outputFile), _resolutionX(resolutionX), _resolutionY(resolutionY), _worldSize(worldSize)
+{
+}
+
+NormalMapGenerator::~NormalMapGenerator()
+{
+}
+
+bool equalsIgnoreCase(const std::string& s1, const std::string& s2)
+{
+    size_t l1 = s1.size();
+    size_t l2 = s2.size();
+    if (l1 != l2)
+        return false;
+
+    for (size_t i = 0; i < l1; ++i)
+    {
+        if (tolower(s1[i]) != tolower(s2[i]))
+            return false;
+    }
+
+    return true;
+}
+
+float getHeight(float* heights, int width, int height, int x, int y)
+{
+    if (x < 0)
+        x = 0;
+    else if (x >= width)
+        x = width-1;
+    if (y < 0)
+        y = 0;
+    else if (y >= height)
+        y = height-1;
+    return heights[y*width+x];
+}
+
+void calculateNormal(
+    float x1, float y1, float z1,
+    float x2, float y2, float z2,
+    float x3, float y3, float z3,
+    Vector3* normal)
+{
+    Vector3 E(x1, y1, z1);
+    Vector3 F(x2, y2, z2);
+    Vector3 G(x3, y3, z3);
+
+    Vector3 P, Q;
+    Vector3::subtract(F, E, &P);
+    Vector3::subtract(G, E, &Q);
+
+    Vector3::cross(Q, P, normal);
+}
+
+float normalizedHeightPacked(float r, float g, float b)
+{
+    // This formula is intended for 24-bit packed heightmap images (that are generated
+    // with gameplay-encoder. However, it is also compatible with normal grayscale 
+    // heightmap images, with an error of approximately 0.4%. This can be seen by
+    // setting r=g=b=x and comparing the grayscale height expression to the packed
+    // height expression: the error is 2^-8 + 2^-16 which is just under 0.4%.
+    return (256.0f*r + g + 0.00390625f*b) / 65536.0f;
+}
+
+void NormalMapGenerator::generate()
+{
+    // Load the input heightmap
+    float* heights = NULL;
+    size_t pos = _inputFile.find_last_of('.');
+    std::string ext = pos == std::string::npos ? "" : _inputFile.substr(pos, _inputFile.size()-pos);
+    if (equalsIgnoreCase(ext, ".png"))
+    {
+        // Load heights from PNG image
+        Image* image = Image::create(_inputFile.c_str());
+        if (image == NULL)
+        {
+            LOG(1, "Failed to load input heightmap PNG: %s.\n", _inputFile.c_str());
+            return;
+        }
+
+        _resolutionX = image->getWidth();
+        _resolutionY = image->getHeight();
+        int size = _resolutionX * _resolutionY;
+        heights = new float[size];
+        unsigned char* data = (unsigned char*)image->getData();
+        for (int i = 0; i < size; ++i)
+        {
+            switch (image->getFormat())
+            {
+            case Image::LUMINANCE:
+                heights[i] = data[i] / 255.0f;
+                break;
+            case Image::RGB:
+            case Image::RGBA:
+                {
+                    int pos = i * image->getBpp();
+                    heights[i] = normalizedHeightPacked(data[pos], data[pos+1], data[pos+2]);
+                }
+                break;
+            default:
+                heights[i] = 0.0f;
+                break;
+            }
+            heights[i] = heights[i] * _worldSize.y;
+        }
+        SAFE_DELETE(image);
+    }
+    else if (equalsIgnoreCase(ext, ".raw"))
+    {
+        // Load heights from RAW 8 or 16-bit file
+        if (_resolutionX <= 0 || _resolutionY <= 0)
+        {
+            LOG(1, "Missing resolution argument - must be explicitly specified for RAW heightmap files: %s.\n", _inputFile.c_str());
+            return;
+        }
+
+        // Read all data from file
+        FILE* fp = fopen(_inputFile.c_str(), "rb");
+        if (fp == NULL)
+        {
+            LOG(1, "Failed to open input file: %s.\n", _inputFile.c_str());
+            return;
+        }
+
+        fseek(fp, 0, SEEK_END);
+        long fileSize = ftell(fp);
+        fseek(fp, 0, SEEK_SET);
+
+        unsigned char* data = new unsigned char[fileSize];
+        if (fread(data, 1, fileSize, fp) != (size_t)fileSize)
+        {
+            fclose(fp);
+            delete[] data;
+            LOG(1, "Failed to read bytes from input file: %s.\n", _inputFile.c_str());
+            return;
+        }
+        fclose(fp);
+
+        // Determine if the RAW file is 8-bit or 16-bit based on file size.
+        int bits = (fileSize / (_resolutionX * _resolutionY)) * 8;
+        if (bits != 8 && bits != 16)
+        {
+            LOG(1, "Invalid RAW file - must be 8-bit or 16-bit, but found neither: %s.", _inputFile.c_str());
+            delete[] data;
+            return;
+        }
+
+        int size = _resolutionX * _resolutionY;
+        heights = new float[size];
+        if (bits == 16)
+        {
+            // 16-bit (0-65535)
+            int idx;
+            for (unsigned int y = 0, i = 0; y < (unsigned int)_resolutionY; ++y)
+            {
+                for (unsigned int x = 0; x < (unsigned int)_resolutionX; ++x, ++i)
+                {
+                    idx = (y * _resolutionX + x) << 1;
+                    heights[i] = ((data[idx] | (int)data[idx+1] << 8) / 65535.0f) * _worldSize.y;
+                }
+            }
+        }
+        else
+        {
+            // 8-bit (0-255)
+            for (unsigned int y = 0, i = 0; y < (unsigned int)_resolutionY; ++y)
+            {
+                for (unsigned int x = 0; x < (unsigned int)_resolutionX; ++x, ++i)
+                {
+                    heights[i] = (data[y * _resolutionX + x] / 255.0f) * _worldSize.y;
+                }
+            }
+        }
+
+        delete[] data;
+    }
+    else
+    {
+        LOG(1, "Unsupported input heightmap file (must be a valid PNG or RAW file: %s.\n", _inputFile.c_str());
+        return;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // NOTE: This method assumes the heightmap geometry is generated as follows.
+    //
+    //   -----------
+    //  | / | / | / |
+    //  |-----------|
+    //  | / | / | / |
+    //  |-----------|
+    //  | / | / | / |
+    //   -----------
+    //
+    ///////////////////////////////////////////////////////////////////////////////////////////////
+
+    struct NormalPixel
+    {
+        unsigned char r, g, b;
+    };
+    NormalPixel* normalPixels = new NormalPixel[_resolutionX * _resolutionY];
+
+    struct Face
+    {
+        Vector3 normal1;
+        Vector3 normal2;
+    };
+
+    int progressMax = (_resolutionX-1) * (_resolutionY-1) + _resolutionX * _resolutionY;
+    int progress = 0;
+
+    Vector2 scale(_worldSize.x / (_resolutionX-1), _worldSize.z / (_resolutionY-1));
+
+    // First calculate all face normals for the heightmap
+    LOG(1, "Calculating normals... 0%%");
+    Face* faceNormals = new Face[(_resolutionX - 1) * (_resolutionY - 1)];
+    Vector3 v1, v2;
+    for (int z = 0; z < _resolutionY-1; z++)
+    {
+        for (int x = 0; x < _resolutionX-1; x++)
+        {
+            float topLeftHeight = getHeight(heights, _resolutionX, _resolutionY, x, z);
+            float bottomLeftHeight = getHeight(heights, _resolutionX, _resolutionY, x, z + 1);
+            float bottomRightHeight = getHeight(heights, _resolutionX, _resolutionY, x + 1, z + 1);
+            float topRightHeight = getHeight(heights, _resolutionX, _resolutionY, x + 1, z);
+
+            // Triangle 1
+            calculateNormal(
+                (float)x*scale.x, bottomLeftHeight, (float)(z + 1)*scale.y,
+                (float)x*scale.x, topLeftHeight, (float)z*scale.y,
+                (float)(x + 1)*scale.x, topRightHeight, (float)z*scale.y,
+                &faceNormals[z*(_resolutionX-1)+x].normal1);
+
+            // Triangle 2
+            calculateNormal(
+                (float)x*scale.x, bottomLeftHeight, (float)(z + 1)*scale.y,
+                (float)(x + 1)*scale.x, topRightHeight, (float)z*scale.y,
+                (float)(x + 1)*scale.x, bottomRightHeight, (float)(z + 1)*scale.y,
+                &faceNormals[z*(_resolutionX-1)+x].normal2);
+
+            ++progress;
+            LOG(1, "\rCalculating normals... %d%%", (int)(((float)progress / progressMax) * 100));
+        }
+    }
+
+    // Free height array
+    delete[] heights;
+    heights = NULL;
+
+    // Smooth normals by taking an average for each vertex
+    Vector3 normal;
+    for (int z = 0; z < _resolutionY; z++)
+    {
+        for (int x = 0; x < _resolutionX; x++)
+        {
+            // Reset normal sum
+            normal.set(0, 0, 0);
+
+            if (x > 0)
+            {
+                if (z > 0)
+                {
+                    // Top left
+                    normal.add(faceNormals[(z-1)*(_resolutionX-1) + (x-1)].normal2);
+                }
+
+                if (z < (_resolutionY - 1))
+                {
+                    // Bottom left
+                    normal.add(faceNormals[z*(_resolutionX-1) + (x - 1)].normal1);
+                    normal.add(faceNormals[z*(_resolutionX-1) + (x - 1)].normal2);
+                }
+            }
+
+            if (x < (_resolutionX - 1))
+            {
+                if (z > 0)
+                {
+                    // Top right
+                    normal.add(faceNormals[(z-1)*(_resolutionX-1) + x].normal1);
+                    normal.add(faceNormals[(z-1)*(_resolutionX-1) + x].normal2);
+                }
+
+                if (z < (_resolutionY - 1))
+                {
+                    // Bottom right
+                    normal.add(faceNormals[z*(_resolutionX-1) + x].normal1);
+                }
+            }
+
+            // We don't have to worry about weighting the normals by
+            // the surface area of the triangles since a heightmap 
+            // guarantees that all triangles have the same surface area.
+            normal.normalize();
+
+            // Store this vertex normal
+            NormalPixel& pixel = normalPixels[z*_resolutionX + x];
+            pixel.r = (unsigned char)((normal.x + 1.0f) * 0.5f * 255.0f);
+            pixel.g = (unsigned char)((normal.y + 1.0f) * 0.5f * 255.0f);
+            pixel.b = (unsigned char)((normal.z + 1.0f) * 0.5f * 255.0f);
+
+            ++progress;
+            LOG(1, "\rCalculating normals... %d%%", (int)(((float)progress / progressMax) * 100));
+        }
+    }
+
+    LOG(1, "\rCalculating normals... Done.\n");
+
+    // Create and save an image for the normal map
+    Image* normalMap = Image::create(Image::RGB, _resolutionX, _resolutionY);
+    normalMap->setData(normalPixels);
+    normalMap->save(_outputFile.c_str());
+
+    LOG(1, "Normal map saved to '%s'.\n", _outputFile.c_str());
+
+    // Free temp data
+    delete[] normalPixels;
+    normalPixels = NULL;
+}
+
+}

+ 35 - 0
gameplay-encoder/src/NormalMapGenerator.h

@@ -0,0 +1,35 @@
+#ifndef NORMALMAPGENERATOR_H_
+#define NORMALMAPGENERATOR_H_
+
+#include "Vector3.h"
+
+namespace gameplay
+{
+
+class NormalMapGenerator
+{
+
+public:
+
+    NormalMapGenerator(const char* inputFile, const char* outputFile, int resolutionX, int resolutionY, const Vector3& worldSize);
+    ~NormalMapGenerator();
+
+    void generate();
+
+private:
+
+    // Hidden copy/assignment
+    NormalMapGenerator(const NormalMapGenerator&);
+    NormalMapGenerator& operator=(const NormalMapGenerator&);
+
+    std::string _inputFile;
+    std::string _outputFile;
+    int _resolutionX;
+    int _resolutionY;
+    Vector3 _worldSize;
+
+};
+
+}
+
+#endif

+ 1 - 1
gameplay-encoder/src/Scene.h

@@ -59,7 +59,7 @@ private:
 
     /**
      * Recursively calculates the ambient color of the scene starting at the given node.
-     * The ambient light color is added to the givne float array.
+     * The ambient light color is added to the given float array.
      * 
      * @param node The node in this scene to traverse from.
      * @param values Pointer to 3 floats that contains the calculated ambient color.

+ 18 - 0
gameplay-encoder/src/main.cpp

@@ -4,6 +4,7 @@
 #include "TTFFontEncoder.h"
 #include "GPBDecoder.h"
 #include "EncoderArguments.h"
+#include "NormalMapGenerator.h"
 
 using namespace gameplay;
 
@@ -102,6 +103,23 @@ int main(int argc, const char** argv)
             decoder.readBinary(realpath);
             break;
         }
+    case EncoderArguments::FILEFORMAT_PNG:
+    case EncoderArguments::FILEFORMAT_RAW:
+        {
+            if (arguments.normalMapGeneration())
+            {
+                int x, y;
+                arguments.getHeightmapResolution(&x, &y);
+                NormalMapGenerator generator(arguments.getFilePath().c_str(), arguments.getOutputFilePath().c_str(), x, y, arguments.getHeightmapWorldSize());
+                generator.generate();
+            }
+            else
+            {
+                LOG(1, "Error: Nothing to do for specified file format. Did you forget an option?\n");
+                return -1;
+            }
+            break;
+        }
    default:
         {
             LOG(1, "Error: Unsupported file format: %s\n", arguments.getFilePathPointer());

+ 52 - 0
gameplay-luagen/CMakeLists.txt

@@ -0,0 +1,52 @@
+
+include_directories( 
+    ${CMAKE_SOURCE_DIR}/external-deps/lua/include
+    ${CMAKE_SOURCE_DIR}/external-deps/tinyxml2/include
+    /usr/include
+)
+
+add_definitions(-D__linux__)
+
+link_directories(
+    ${CMAKE_SOURCE_DIR}/external-deps/lua/lib/linux/${ARCH_DIR}
+    ${CMAKE_SOURCE_DIR}/external-deps/tinyxml2/lib/linux
+    /usr/lib
+)
+
+set(APP_LIBRARIES
+    lua
+    tinyxml2
+) 
+
+add_definitions(-lstdc++ -llua -ltinyxml2)
+
+set( APP_NAME gameplay-luagen )
+
+set(APP_SRC
+	src/Base.h
+	src/ClassBinding.cpp
+	src/ClassBinding.h
+	src/DebugNew.cpp
+	src/DebugNew.h
+	src/EnumBinding.h
+	src/FunctionBinding.cpp
+	src/FunctionBinding.h
+	src/Generator.cpp
+	src/Generator.h
+    src/main.cpp
+    src/TypedefBinding.h
+)
+
+add_executable(${APP_NAME}
+    ${APP_SRC}
+)
+
+target_link_libraries(${APP_NAME} ${APP_LIBRARIES})
+
+set_target_properties(${APP_NAME} PROPERTIES
+    OUTPUT_NAME "${APP_NAME}"
+    CLEAN_DIRECT_OUTPUT 1
+)
+
+source_group(src FILES ${APP_SRC})
+

+ 0 - 15
gameplay-luagen/gameplay-api/xml/combine.xslt

@@ -1,15 +0,0 @@
-<!-- XSLT script to combine the generated output into a single file. 
-     If you have xsltproc you could use:
-     xsltproc combine.xslt index.xml >all.xml
--->
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-  <xsl:output method="xml" version="1.0" indent="no" standalone="yes" />
-  <xsl:template match="/">
-    <doxygen version="{doxygenindex/@version}">
-      <!-- Load all doxgen generated xml files -->
-      <xsl:for-each select="doxygenindex/compound">
-        <xsl:copy-of select="document( concat( @refid, '.xml' ) )/doxygen/*" />
-      </xsl:for-each>
-    </doxygen>
-  </xsl:template>
-</xsl:stylesheet>

+ 0 - 832
gameplay-luagen/gameplay-api/xml/compound.xsd

@@ -1,832 +0,0 @@
-<?xml version='1.0' encoding='utf-8' ?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-  <xsd:element name="doxygen" type="DoxygenType"/>
-
-  <!-- Complex types -->
-
-  <xsd:complexType name="DoxygenType">
-    <xsd:sequence maxOccurs="unbounded">
-      <xsd:element name="compounddef" type="compounddefType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="version" type="DoxVersionNumber" use="required" />
-  </xsd:complexType>
-
-  <xsd:complexType name="compounddefType">
-    <xsd:sequence>
-      <xsd:element name="compoundname" type="xsd:string"/>
-      <xsd:element name="title" type="xsd:string" minOccurs="0" />
-      <xsd:element name="basecompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="derivedcompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="includes" type="incType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="includedby" type="incType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="incdepgraph" type="graphType" minOccurs="0" />
-      <xsd:element name="invincdepgraph" type="graphType" minOccurs="0" />
-      <xsd:element name="innerdir" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innerfile" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innerclass" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innernamespace" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innerpage" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="innergroup" type="refType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
-      <xsd:element name="sectiondef" type="sectiondefType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="inheritancegraph" type="graphType" minOccurs="0" />
-      <xsd:element name="collaborationgraph" type="graphType" minOccurs="0" />
-      <xsd:element name="programlisting" type="listingType" minOccurs="0" />
-      <xsd:element name="location" type="locationType" minOccurs="0" />
-      <xsd:element name="listofallmembers" type="listofallmembersType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-    <xsd:attribute name="kind" type="DoxCompoundKind" />
-    <xsd:attribute name="prot" type="DoxProtectionKind" />
-  </xsd:complexType>
-
-  <xsd:complexType name="listofallmembersType">
-    <xsd:sequence>
-      <xsd:element name="member" type="memberRefType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="memberRefType">
-    <xsd:sequence>
-      <xsd:element name="scope" />
-      <xsd:element name="name" />
-    </xsd:sequence>
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="prot" type="DoxProtectionKind" />
-    <xsd:attribute name="virt" type="DoxVirtualKind" />
-    <xsd:attribute name="ambiguityscope" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="compoundRefType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-        <xsd:attribute name="refid" type="xsd:string" use="optional" />
-        <xsd:attribute name="prot" type="DoxProtectionKind" />
-        <xsd:attribute name="virt" type="DoxVirtualKind" />
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="reimplementType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-        <xsd:attribute name="refid" type="xsd:string" />
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="incType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-        <xsd:attribute name="refid" type="xsd:string" />
-        <xsd:attribute name="local" type="DoxBool" />
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="refType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-        <xsd:attribute name="refid" type="xsd:string" />
-        <xsd:attribute name="prot" type="DoxProtectionKind" use="optional"/>
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="refTextType">
-    <xsd:simpleContent>
-      <xsd:extension base="xsd:string">
-       <xsd:attribute name="refid" type="xsd:string" />
-       <xsd:attribute name="kindref" type="DoxRefKind" />
-       <xsd:attribute name="external" type="xsd:string" use="optional"/>
-       <xsd:attribute name="tooltip" type="xsd:string" use="optional"/>
-      </xsd:extension>
-    </xsd:simpleContent>
-  </xsd:complexType>
-
-  <xsd:complexType name="sectiondefType">
-    <xsd:sequence>
-      <xsd:element name="header" type="xsd:string" minOccurs="0" />
-      <xsd:element name="description" type="descriptionType" minOccurs="0" />
-      <xsd:element name="memberdef" type="memberdefType" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="kind" type="DoxSectionKind" />
-  </xsd:complexType>
-
-  <xsd:complexType name="memberdefType">
-    <xsd:sequence>
-      <xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
-      <xsd:element name="type" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="definition" minOccurs="0" />
-      <xsd:element name="argsstring" minOccurs="0" />
-      <xsd:element name="name" />
-      <xsd:element name="read" minOccurs="0" />
-      <xsd:element name="write" minOccurs="0" />
-      <xsd:element name="bitfield" minOccurs="0" />
-      <xsd:element name="reimplements" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="reimplementedby" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="enumvalue" type="enumvalueType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="exceptions" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="inbodydescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="location" type="locationType" />
-      <xsd:element name="references" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="referencedby" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="kind" type="DoxMemberKind" />
-    <xsd:attribute name="id" type="xsd:string" />
-    <xsd:attribute name="prot" type="DoxProtectionKind" />
-    <xsd:attribute name="static" type="DoxBool" />
-    <xsd:attribute name="const" type="DoxBool" />
-    <xsd:attribute name="explicit" type="DoxBool" />
-    <xsd:attribute name="inline" type="DoxBool" />
-    <xsd:attribute name="virt" type="DoxVirtualKind" />
-    <xsd:attribute name="volatile" type="DoxBool" />
-    <xsd:attribute name="mutable" type="DoxBool" />
-    <!-- Qt property -->
-    <xsd:attribute name="readable" type="DoxBool" use="optional"/>
-    <xsd:attribute name="writable" type="DoxBool" use="optional"/>
-    <!-- C++/CLI variable -->
-    <xsd:attribute name="initonly" type="DoxBool" use="optional"/>
-    <!-- C++/CLI and C# property -->
-    <xsd:attribute name="settable" type="DoxBool" use="optional"/>
-    <xsd:attribute name="gettable" type="DoxBool" use="optional"/>
-    <!-- C++/CLI function -->
-    <xsd:attribute name="final" type="DoxBool" use="optional"/>
-    <xsd:attribute name="sealed" type="DoxBool" use="optional"/>
-    <xsd:attribute name="new" type="DoxBool" use="optional"/>
-    <!-- C++/CLI event -->
-    <xsd:attribute name="add" type="DoxBool" use="optional"/>
-    <xsd:attribute name="remove" type="DoxBool" use="optional"/>
-    <xsd:attribute name="raise" type="DoxBool" use="optional"/>
-    <!-- Objective-C 2.0 protocol method -->
-    <xsd:attribute name="optional" type="DoxBool" use="optional"/>
-    <xsd:attribute name="required" type="DoxBool" use="optional"/>
-    <!-- Objective-C 2.0 property accessor -->
-    <xsd:attribute name="accessor" type="DoxAccessor" use="optional"/>
-  </xsd:complexType>
-
-  <xsd:complexType name="descriptionType" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" minOccurs="0"/>	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalType" minOccurs="0" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="enumvalueType" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="name" />
-      <xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
-      <xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-    <xsd:attribute name="prot" type="DoxProtectionKind" />
-  </xsd:complexType>
-
-  <xsd:complexType name="templateparamlistType">
-    <xsd:sequence>
-      <xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="paramType">
-    <xsd:sequence>
-      <xsd:element name="type" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="declname" minOccurs="0" />
-      <xsd:element name="defname" minOccurs="0" />
-      <xsd:element name="array" minOccurs="0" />
-      <xsd:element name="defval" type="linkedTextType" minOccurs="0" />
-      <xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="linkedTextType" mixed="true">
-    <xsd:sequence>
-    <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="graphType">
-    <xsd:sequence>
-      <xsd:element name="node" type="nodeType" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="nodeType">
-    <xsd:sequence>
-      <xsd:element name="label" />
-      <xsd:element name="link" type="linkType" minOccurs="0" />
-      <xsd:element name="childnode" type="childnodeType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="childnodeType">
-    <xsd:sequence>
-      <xsd:element name="edgelabel" minOccurs="0" maxOccurs="unbounded"/>
-    </xsd:sequence>
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="relation" type="DoxGraphRelation" />
-  </xsd:complexType>
-
-  <xsd:complexType name="linkType">
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="external" type="xsd:string" use="optional"/>
-  </xsd:complexType>
-
-  <xsd:complexType name="listingType">
-    <xsd:sequence>
-      <xsd:element name="codeline" type="codelineType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="codelineType">
-    <xsd:sequence>
-      <xsd:element name="highlight" type="highlightType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="lineno" type="xsd:integer" />
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="refkind" type="DoxRefKind" />
-    <xsd:attribute name="external" type="DoxBool" />
-  </xsd:complexType>
-
-  <xsd:complexType name="highlightType" mixed="true">
-    <xsd:choice minOccurs="0" maxOccurs="unbounded">
-      <xsd:element name="sp" />
-      <xsd:element name="ref" type="refTextType" />
-    </xsd:choice>
-    <xsd:attribute name="class" type="DoxHighlightClass" />
-  </xsd:complexType>
-
-  <xsd:complexType name="referenceType" mixed="true">
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="compoundref" type="xsd:string" use="optional" />
-    <xsd:attribute name="startline" type="xsd:integer" />
-    <xsd:attribute name="endline" type="xsd:integer" />
-  </xsd:complexType>
-
-  <xsd:complexType name="locationType">
-    <xsd:attribute name="file" type="xsd:string" />
-    <xsd:attribute name="line" type="xsd:integer" />
-    <xsd:attribute name="bodyfile" type="xsd:string" />
-    <xsd:attribute name="bodystart" type="xsd:integer" />
-    <xsd:attribute name="bodyend" type="xsd:integer" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docSect1Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" />	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalS1Type" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docSect2Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" />	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalS2Type" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docSect3Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" />	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect4" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalS3Type" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docSect4Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="title" type="xsd:string" />	    
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalS4Type" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalType" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalS1Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalS2Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalS3Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect3" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docInternalS4Type" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="para"  type="docParaType"  minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
- 
-  <xsd:group name="docTitleCmdGroup">
-    <xsd:choice>
-      <xsd:element name="ulink" type="docURLLink" />
-      <xsd:element name="bold" type="docMarkupType" />
-      <xsd:element name="emphasis" type="docMarkupType" />
-      <xsd:element name="computeroutput" type="docMarkupType" />
-      <xsd:element name="subscript" type="docMarkupType" />
-      <xsd:element name="superscript" type="docMarkupType" />
-      <xsd:element name="center" type="docMarkupType" />
-      <xsd:element name="small" type="docMarkupType" />
-      <xsd:element name="htmlonly" type="xsd:string" />
-      <xsd:element name="manonly" type="xsd:string" />
-      <xsd:element name="xmlonly" type="xsd:string" />
-      <xsd:element name="rtfonly" type="xsd:string" />
-      <xsd:element name="latexonly" type="xsd:string" />
-      <xsd:element name="dot" type="xsd:string" />
-      <xsd:element name="anchor" type="docAnchorType" />
-      <xsd:element name="formula" type="docFormulaType" />
-      <xsd:element name="ref" type="docRefTextType" />
-      <xsd:element name="copy" type="docEmptyType" />
-      <xsd:element name="trademark" type="docEmptyType" />
-      <xsd:element name="registered" type="docEmptyType" />
-      <xsd:element name="lsquo" type="docEmptyType" />
-      <xsd:element name="rsquo" type="docEmptyType" />
-      <xsd:element name="ldquo" type="docEmptyType" />
-      <xsd:element name="rdquo" type="docEmptyType" />
-      <xsd:element name="ndash" type="docEmptyType" />
-      <xsd:element name="mdash" type="docEmptyType" />
-      <xsd:element name="umlaut" type="docCharType" />
-      <xsd:element name="acute" type="docCharType" />
-      <xsd:element name="grave" type="docCharType" />
-      <xsd:element name="circ" type="docCharType" />
-      <xsd:element name="slash" type="docCharType" />
-      <xsd:element name="tilde" type="docCharType" />
-      <xsd:element name="cedil" type="docCharType" />
-      <xsd:element name="ring" type="docCharType" />
-      <xsd:element name="szlig" type="docEmptyType" />
-      <xsd:element name="nonbreakablespace" type="docEmptyType" />
-    </xsd:choice>
-  </xsd:group>
-
-  <xsd:complexType name="docTitleType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-  </xsd:complexType>
-
-  <xsd:group name="docCmdGroup">
-    <xsd:choice>
-      <xsd:group ref="docTitleCmdGroup"/>
-      <xsd:element name="linebreak" type="docEmptyType" />
-      <xsd:element name="hruler" type="docEmptyType" />
-      <xsd:element name="preformatted" type="docMarkupType" />
-      <xsd:element name="programlisting" type="listingType" />
-      <xsd:element name="verbatim" type="xsd:string" />
-      <xsd:element name="indexentry" type="docIndexEntryType" />
-      <xsd:element name="orderedlist" type="docListType" />
-      <xsd:element name="itemizedlist" type="docListType" />
-      <xsd:element name="simplesect" type="docSimpleSectType" />
-      <xsd:element name="title" type="docTitleType" />
-      <xsd:element name="variablelist" type="docVariableListType" />
-      <xsd:element name="table" type="docTableType" />
-      <xsd:element name="heading" type="docHeadingType" />
-      <xsd:element name="image" type="docImageType" />
-      <xsd:element name="dotfile" type="docDotFileType" />
-      <xsd:element name="toclist" type="docTocListType" />
-      <xsd:element name="language" type="docLanguageType" />
-      <xsd:element name="parameterlist" type="docParamListType" />
-      <xsd:element name="xrefsect" type="docXRefSectType" />
-      <xsd:element name="copydoc" type="docCopyType" />
-      <xsd:element name="blockquote" type="docBlockQuoteType" />
-    </xsd:choice>
-  </xsd:group>
-
-  <xsd:complexType name="docParaType" mixed="true">
-    <xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docMarkupType" mixed="true">
-    <xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docURLLink" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="url" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docAnchorType" mixed="true">
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docFormulaType" mixed="true">
-    <xsd:attribute name="id" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docIndexEntryType">
-    <xsd:sequence>
-      <xsd:element name="primaryie" type="xsd:string" />
-      <xsd:element name="secondaryie" type="xsd:string" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docListType">
-    <xsd:sequence>
-      <xsd:element name="listitem" type="docListItemType" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docListItemType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docSimpleSectType">
-    <xsd:sequence>
-      <xsd:element name="title" type="docTitleType" minOccurs="0" />
-      <xsd:sequence minOccurs="0" maxOccurs="unbounded">
-        <xsd:element name="para" type="docParaType" minOccurs="1" maxOccurs="unbounded" />
-        <xsd:element name="simplesectsep" type="docEmptyType" minOccurs="0"/>
-      </xsd:sequence>
-    </xsd:sequence>
-    <xsd:attribute name="kind" type="DoxSimpleSectKind" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docVarListEntryType">
-    <xsd:sequence>
-      <xsd:element name="term" type="docTitleType" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:group name="docVariableListGroup">
-    <xsd:sequence>
-      <xsd:element name="varlistentry" type="docVarListEntryType" />
-      <xsd:element name="listitem" type="docListItemType" />
-    </xsd:sequence>
-  </xsd:group>
-
-  <xsd:complexType name="docVariableListType">
-    <xsd:sequence>
-      <xsd:group ref="docVariableListGroup" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docRefTextType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="refid" type="xsd:string" />
-    <xsd:attribute name="kindref" type="DoxRefKind" />
-    <xsd:attribute name="external" type="xsd:string" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docTableType">
-    <xsd:sequence>
-      <xsd:element name="row" type="docRowType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="caption" type="docCaptionType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="rows" type="xsd:integer" />
-    <xsd:attribute name="cols" type="xsd:integer" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docRowType">
-    <xsd:sequence>
-      <xsd:element name="entry" type="docEntryType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docEntryType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="thead" type="DoxBool" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docCaptionType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docHeadingType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="level" type="xsd:integer" /> <!-- todo: range 1-6 -->
-  </xsd:complexType>
-
-  <xsd:complexType name="docImageType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="type" type="DoxImageKind" /> 
-    <xsd:attribute name="name" type="xsd:string" /> 
-    <xsd:attribute name="width" type="xsd:string" /> 
-    <xsd:attribute name="height" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docDotFileType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="name" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docTocItemType" mixed="true">
-    <xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
-    <xsd:attribute name="id" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docTocListType">
-    <xsd:sequence>
-      <xsd:element name="tocitem" type="docTocItemType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docLanguageType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="langid" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamListType">
-    <xsd:sequence>
-      <xsd:element name="parameteritem" type="docParamListItem" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-    <xsd:attribute name="kind" type="DoxParamListKind" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamListItem">
-    <xsd:sequence>
-      <xsd:element name="parameternamelist" type="docParamNameList" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="parameterdescription" type="descriptionType" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamNameList">
-    <xsd:sequence>
-      <xsd:element name="parametertype" type="docParamType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="parametername" type="docParamName" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamType" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docParamName" mixed="true">
-    <xsd:sequence>
-      <xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
-    </xsd:sequence>
-    <xsd:attribute name="direction" type="DoxParamDir" use="optional" />
-  </xsd:complexType>
-
-  <xsd:complexType name="docXRefSectType">
-    <xsd:sequence>
-      <xsd:element name="xreftitle" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="xrefdescription" type="descriptionType" />
-    </xsd:sequence>
-    <xsd:attribute name="id" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docCopyType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
-      <xsd:element name="internal" type="docInternalType" minOccurs="0" />
-    </xsd:sequence>
-    <xsd:attribute name="link" type="xsd:string" /> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docBlockQuoteType">
-    <xsd:sequence>
-      <xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
-    </xsd:sequence>
-  </xsd:complexType>
-
-  <xsd:complexType name="docCharType">
-    <xsd:attribute name="char" type="DoxCharRange"/> 
-  </xsd:complexType>
-
-  <xsd:complexType name="docEmptyType"/>
-
-  <!-- Simple types -->
-
-  <xsd:simpleType name="DoxBool">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="yes" />
-      <xsd:enumeration value="no" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxGraphRelation">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="include" />
-      <xsd:enumeration value="usage" />
-      <xsd:enumeration value="template-instance" />
-      <xsd:enumeration value="public-inheritance" />
-      <xsd:enumeration value="protected-inheritance" />
-      <xsd:enumeration value="private-inheritance" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxRefKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="compound" />
-      <xsd:enumeration value="member" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxMemberKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="define" />
-      <xsd:enumeration value="property" />
-      <xsd:enumeration value="event" />
-      <xsd:enumeration value="variable" />
-      <xsd:enumeration value="typedef" />
-      <xsd:enumeration value="enum" />
-      <xsd:enumeration value="function" />
-      <xsd:enumeration value="signal" />
-      <xsd:enumeration value="prototype" />
-      <xsd:enumeration value="friend" />
-      <xsd:enumeration value="dcop" />
-      <xsd:enumeration value="slot" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxProtectionKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="public" />
-      <xsd:enumeration value="protected" />
-      <xsd:enumeration value="private" />
-      <xsd:enumeration value="package" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxVirtualKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="non-virtual" />
-      <xsd:enumeration value="virtual" />
-      <xsd:enumeration value="pure-virtual" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxCompoundKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="class" />
-      <xsd:enumeration value="struct" />
-      <xsd:enumeration value="union" />
-      <xsd:enumeration value="interface" />
-      <xsd:enumeration value="protocol" />
-      <xsd:enumeration value="category" />
-      <xsd:enumeration value="exception" />
-      <xsd:enumeration value="file" />
-      <xsd:enumeration value="namespace" />
-      <xsd:enumeration value="group" />
-      <xsd:enumeration value="page" />
-      <xsd:enumeration value="example" />
-      <xsd:enumeration value="dir" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxSectionKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="user-defined" />
-      <xsd:enumeration value="public-type" />
-      <xsd:enumeration value="public-func" />
-      <xsd:enumeration value="public-attrib" />
-      <xsd:enumeration value="public-slot" />
-      <xsd:enumeration value="signal" />
-      <xsd:enumeration value="dcop-func" />
-      <xsd:enumeration value="property" />
-      <xsd:enumeration value="event" />
-      <xsd:enumeration value="public-static-func" />
-      <xsd:enumeration value="public-static-attrib" />
-      <xsd:enumeration value="protected-type" />
-      <xsd:enumeration value="protected-func" />
-      <xsd:enumeration value="protected-attrib" />
-      <xsd:enumeration value="protected-slot" />
-      <xsd:enumeration value="protected-static-func" />
-      <xsd:enumeration value="protected-static-attrib" />
-      <xsd:enumeration value="package-type" />
-      <xsd:enumeration value="package-func" />
-      <xsd:enumeration value="package-attrib" />
-      <xsd:enumeration value="package-static-func" />
-      <xsd:enumeration value="package-static-attrib" />
-      <xsd:enumeration value="private-type" />
-      <xsd:enumeration value="private-func" />
-      <xsd:enumeration value="private-attrib" />
-      <xsd:enumeration value="private-slot" />
-      <xsd:enumeration value="private-static-func" />
-      <xsd:enumeration value="private-static-attrib" />
-      <xsd:enumeration value="friend" />
-      <xsd:enumeration value="related" />
-      <xsd:enumeration value="define" />
-      <xsd:enumeration value="prototype" />
-      <xsd:enumeration value="typedef" />
-      <xsd:enumeration value="enum" />
-      <xsd:enumeration value="func" />
-      <xsd:enumeration value="var" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxHighlightClass">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="comment" />
-      <xsd:enumeration value="normal" />
-      <xsd:enumeration value="preprocessor" />
-      <xsd:enumeration value="keyword" />
-      <xsd:enumeration value="keywordtype" />
-      <xsd:enumeration value="keywordflow" />
-      <xsd:enumeration value="stringliteral" />
-      <xsd:enumeration value="charliteral" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxSimpleSectKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="see" />
-      <xsd:enumeration value="return" />
-      <xsd:enumeration value="author" />
-      <xsd:enumeration value="authors" />
-      <xsd:enumeration value="version" />
-      <xsd:enumeration value="since" />
-      <xsd:enumeration value="date" />
-      <xsd:enumeration value="note" />
-      <xsd:enumeration value="warning" />
-      <xsd:enumeration value="pre" />
-      <xsd:enumeration value="post" />
-      <xsd:enumeration value="copyright" />
-      <xsd:enumeration value="invariant" />
-      <xsd:enumeration value="remark" />
-      <xsd:enumeration value="attention" />
-      <xsd:enumeration value="par" />
-      <xsd:enumeration value="rcs" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxVersionNumber">
-    <xsd:restriction base="xsd:string">
-      <xsd:pattern value="\d+\.\d+.*" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxImageKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="html" />
-      <xsd:enumeration value="latex" />
-      <xsd:enumeration value="rtf" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxParamListKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="param" />
-      <xsd:enumeration value="retval" />
-      <xsd:enumeration value="exception" />
-      <xsd:enumeration value="templateparam" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxCharRange">
-    <xsd:restriction base="xsd:string">
-      <xsd:pattern value="[aeiouncAEIOUNC]" />
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxParamDir">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="in"/>
-      <xsd:enumeration value="out"/>
-      <xsd:enumeration value="inout"/>
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="DoxAccessor">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="retain"/>
-      <xsd:enumeration value="copy"/>
-      <xsd:enumeration value="assign"/>
-    </xsd:restriction>
-  </xsd:simpleType>
-
-</xsd:schema>
-

+ 0 - 3
gameplay-luagen/gameplay-api/xml/index.xml

@@ -1,3 +0,0 @@
-<?xml version='1.0' encoding='UTF-8' standalone='no'?>
-<doxygenindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="index.xsd" version="1.8.1">
-</doxygenindex>

+ 0 - 66
gameplay-luagen/gameplay-api/xml/index.xsd

@@ -1,66 +0,0 @@
-<?xml version='1.0' encoding='utf-8' ?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-  <xsd:element name="doxygenindex" type="DoxygenType"/>
-
-  <xsd:complexType name="DoxygenType">
-    <xsd:sequence>
-      <xsd:element name="compound" type="CompoundType" minOccurs="0" maxOccurs="unbounded"/>
-    </xsd:sequence>
-    <xsd:attribute name="version" type="xsd:string" use="required"/>
-  </xsd:complexType>
-
-  <xsd:complexType name="CompoundType">
-    <xsd:sequence>
-      <xsd:element name="name" type="xsd:string"/>
-      <xsd:element name="member" type="MemberType" minOccurs="0" maxOccurs="unbounded"/>
-    </xsd:sequence>
-    <xsd:attribute name="refid" type="xsd:string" use="required"/>
-    <xsd:attribute name="kind" type="CompoundKind" use="required"/>
-  </xsd:complexType>
-
-  <xsd:complexType name="MemberType">
-    <xsd:sequence>
-      <xsd:element name="name" type="xsd:string"/>
-    </xsd:sequence>
-    <xsd:attribute name="refid" type="xsd:string" use="required"/>
-    <xsd:attribute name="kind" type="MemberKind" use="required"/>
-  </xsd:complexType>
-  
-  <xsd:simpleType name="CompoundKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="class"/>
-      <xsd:enumeration value="struct"/>
-      <xsd:enumeration value="union"/>
-      <xsd:enumeration value="interface"/>
-      <xsd:enumeration value="protocol"/>
-      <xsd:enumeration value="category"/>
-      <xsd:enumeration value="exception"/>
-      <xsd:enumeration value="file"/>
-      <xsd:enumeration value="namespace"/>
-      <xsd:enumeration value="group"/>
-      <xsd:enumeration value="page"/>
-      <xsd:enumeration value="example"/>
-      <xsd:enumeration value="dir"/>
-    </xsd:restriction>
-  </xsd:simpleType>
-
-  <xsd:simpleType name="MemberKind">
-    <xsd:restriction base="xsd:string">
-      <xsd:enumeration value="define"/>
-      <xsd:enumeration value="property"/>
-      <xsd:enumeration value="event"/>
-      <xsd:enumeration value="variable"/>
-      <xsd:enumeration value="typedef"/>
-      <xsd:enumeration value="enum"/>
-      <xsd:enumeration value="enumvalue"/>
-      <xsd:enumeration value="function"/>
-      <xsd:enumeration value="signal"/>
-      <xsd:enumeration value="prototype"/>
-      <xsd:enumeration value="friend"/>
-      <xsd:enumeration value="dcop"/>
-      <xsd:enumeration value="slot"/>
-    </xsd:restriction>
-  </xsd:simpleType>
-
-</xsd:schema>
-

+ 4 - 4
gameplay-luagen/gameplay-luagen.vcxproj

@@ -78,7 +78,7 @@
     <Link>
       <SubSystem>Console</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalLibraryDirectories>..\external-deps\tinyxml2\lib\windows;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\external-deps\tinyxml2\lib\windows\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>tinyxml2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <PreBuildEvent>
@@ -110,7 +110,7 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalLibraryDirectories>..\external-deps\tinyxml2\lib\windows;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\external-deps\tinyxml2\lib\windows\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>tinyxml2.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <PreBuildEvent>
@@ -126,10 +126,10 @@
       </Message>
     </CustomBuildStep>
     <PostBuildEvent>
-      <Command>copy $(TargetPath) $(ProjectDir)..\bin\win32\$(TargetFileName)</Command>
+      <Command>copy $(TargetPath) $(ProjectDir)..\bin\windows\$(TargetFileName)</Command>
     </PostBuildEvent>
     <PostBuildEvent>
-      <Message>Copying executable to bin/win32 folder ...</Message>
+      <Message>Copying executable to bin/windows folder ...</Message>
     </PostBuildEvent>
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 5 - 0
gameplay-luagen/src/Base.h

@@ -2,6 +2,7 @@
 #include <cassert>
 #include <fstream>
 #include <iostream>
+#include <sstream>
 #include <map>
 #include <set>
 #include <string>
@@ -42,6 +43,10 @@ using namespace std;
 
 extern void printError(const char* format, ...);
 
+extern void writeFile(const string& path, const string& text);
+
+extern std::vector<string> generatedFiles;
+
 // Current function macro.
 #ifdef WIN32
 #define __current__func__ __FUNCTION__

+ 6 - 4
gameplay-luagen/src/ClassBinding.cpp

@@ -88,7 +88,7 @@ void ClassBinding::write(string dir, const set<string>& includes, string* bindin
     // Write out the header.
     {
         string path = dir + string("lua_") + uniquename + string(".h");
-        ofstream o(path.c_str());
+        ostringstream o;
         if (!o)
         {
             GP_ERROR("Failed to open file '%s' for generating Lua bindings.", path.c_str());
@@ -122,13 +122,14 @@ void ClassBinding::write(string dir, const set<string>& includes, string* bindin
         if (bindingNS)
             o << "}\n\n";
         o << "#endif\n";
-        o.close();
+
+        writeFile(path, o.str());
     }
 
     // Write out the implementation.
     {
         string path = dir + string("lua_") + uniquename + string(".cpp");
-        ofstream o(path.c_str());
+        ostringstream o;
         if (!o)
         {
             GP_ERROR("Failed to open file '%s' for generating Lua bindings.", path.c_str());
@@ -288,7 +289,8 @@ void ClassBinding::write(string dir, const set<string>& includes, string* bindin
 
         if (bindingNS)
             o << "}\n";
-        o.close();
+
+        writeFile(path, o.str());
     }
 
     SAFE_DELETE(constructorUniqueName);

+ 145 - 92
gameplay-luagen/src/FunctionBinding.cpp

@@ -7,14 +7,14 @@ static inline void outputLuaTypeCheckInstance(ostream& o);
 static inline void outputLuaTypeCheck(ostream& o, int index, const FunctionBinding::Param& p = 
     FunctionBinding::Param(FunctionBinding::Param::TYPE_OBJECT, FunctionBinding::Param::KIND_POINTER));
 static inline void indent(ostream& o, int indentLevel);
-static inline void outputBindingInvocation(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel);
-static inline void outputGetParam(ostream& o, const FunctionBinding::Param& p, int i, int indentLevel, bool offsetIndex = false);
-static inline void outputMatchedBinding(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel);
+static inline void outputBindingInvocation(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel, int numBindings);
+static inline void outputGetParam(ostream& o, const FunctionBinding::Param& p, int i, int indentLevel, bool offsetIndex, int numBindings);
+static inline void outputMatchedBinding(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel, int numBindings);
 static inline void outputReturnValue(ostream& o, const FunctionBinding& b, int indentLevel);
 static inline std::string getTypeName(const FunctionBinding::Param& param);
 
 FunctionBinding::Param::Param(FunctionBinding::Param::Type type, Kind kind, const string& info) : 
-    type(type), kind(kind), info(info), hasDefaultValue(false)
+    type(type), kind(kind), info(info), hasDefaultValue(false), levelsOfIndirection(0)
 {
 }
 
@@ -76,6 +76,11 @@ void FunctionBinding::write(ostream& o, const vector<FunctionBinding>& bindings)
 {
     GP_ASSERT(bindings.size() > 0);
 
+    if (bindings[0].getFunctionName() == "lua_AudioListener_static_getInstance")
+    {
+        int i = 0;
+    }
+
     // Print the function signature.
     o << "int " << bindings[0].getFunctionName() << "(lua_State* state)\n";
     o << "{\n";
@@ -94,7 +99,7 @@ void FunctionBinding::write(ostream& o, const vector<FunctionBinding>& bindings)
         o << "    " << bindings[0].classname << "* instance = getInstance(state);\n";
         o << "    if (lua_gettop(state) == 2)\n";
         o << "    {\n";
-        outputGetParam(o, bindings[0].returnParam, 1, 2);
+        outputGetParam(o, bindings[0].returnParam, 1, 2, false, 1);
 
         if (bindings[0].returnParam.kind == FunctionBinding::Param::KIND_POINTER &&
             bindings[0].returnParam.type != FunctionBinding::Param::TYPE_OBJECT &&
@@ -161,7 +166,7 @@ void FunctionBinding::write(ostream& o, const vector<FunctionBinding>& bindings)
         // Get or set the static variable depending on the number of parameters.
         o << "    if (lua_gettop(state) == 1)\n";
         o << "    {\n";
-        outputGetParam(o, bindings[0].returnParam, 0, 2);
+        outputGetParam(o, bindings[0].returnParam, 0, 2, false, 1);
 
         if (bindings[0].returnParam.kind == FunctionBinding::Param::KIND_POINTER &&
             bindings[0].returnParam.type != FunctionBinding::Param::TYPE_OBJECT &&
@@ -359,27 +364,17 @@ void FunctionBinding::write(ostream& o, const vector<FunctionBinding>& bindings)
                 if (iter->first > 0)
                     indent(o, 3);
 
-                if (i > 0)
-                {                    
-                    o << "else ";
-                }
-                outputMatchedBinding(o, *(iter->second[i]), iter->first, 3);
+                outputMatchedBinding(o, *(iter->second[i]), iter->first, 3, bindings.size());
             }
 
             // Only print an else clause with error report if there are parameters.
             if (iter->first > 0)
             {
                 indent(o, 3);
-                o << "else\n";
-                indent(o, 3);
-                o << "{\n";
-                indent(o, 4);
                 o << "lua_pushstring(state, \"" << bindings[0].getFunctionName();
                 o << " - Failed to match the given parameters to a valid function signature.\");\n";
-                indent(o, 4);
-                o << "lua_error(state);\n";
                 indent(o, 3);
-                o << "}\n";
+                o << "lua_error(state);\n";
             }
             
             o << "            break;\n";
@@ -501,7 +496,10 @@ ostream& operator<<(ostream& o, const FunctionBinding::Param& param)
     o << getTypeName(param);
 
     if (param.kind == FunctionBinding::Param::KIND_POINTER)
-        o << "*";
+    {
+        for (int i = 0; i < param.levelsOfIndirection; ++i)
+            o << "*";
+    }
 
     return o;
 }
@@ -575,14 +573,14 @@ static inline void indent(ostream& o, int indentLevel)
         o << "    ";
 }
 
-static inline void outputBindingInvocation(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel)
+static inline void outputBindingInvocation(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel, int numBindings)
 {
-    bool isNormalMember = (b.type == FunctionBinding::MEMBER_FUNCTION && b.returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR);
+    bool isNonStatic = (b.type == FunctionBinding::MEMBER_FUNCTION && b.returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR);
 
     // Get the passed in parameters.
-    for (unsigned int i = 0, count = paramCount - (isNormalMember ? 1 : 0); i < count; i++)
+    for (unsigned int i = 0, count = paramCount - (isNonStatic ? 1 : 0); i < count; i++)
     {
-        outputGetParam(o, b.paramTypes[i], i, indentLevel, isNormalMember);
+        outputGetParam(o, b.paramTypes[i], i, indentLevel, isNonStatic, numBindings);
     }
 
     // Get the instance for member functions.
@@ -680,7 +678,7 @@ static inline void outputBindingInvocation(ostream& o, const FunctionBinding& b,
         }
 
         // Pass the arguments.
-        for (unsigned int i = 0, count = paramCount - ((isNormalMember) ? 1 : 0); i < count; i++)
+        for (unsigned int i = 0, count = paramCount - ((isNonStatic) ? 1 : 0); i < count; i++)
         {
             if (b.paramTypes[i].type == FunctionBinding::Param::TYPE_OBJECT && b.paramTypes[i].kind != FunctionBinding::Param::KIND_POINTER)
                 o << "*";
@@ -700,125 +698,158 @@ static inline void outputBindingInvocation(ostream& o, const FunctionBinding& b,
     outputReturnValue(o, b, indentLevel);
 }
 
-static inline void outputGetParam(ostream& o, const FunctionBinding::Param& p, int i, int indentLevel, bool offsetIndex)
+void writeObjectTemplateType(ostream& o, const FunctionBinding::Param& p)
+{
+    o << getTypeName(p);
+    for (int i = 0; i < p.levelsOfIndirection-1; ++i)
+        o << "*";
+}
+
+void writePointerParameter(ostream& o, const char* primitiveType, const FunctionBinding::Param& p, int paramNum, int luaParamIndex, int indentLevel)
+{
+    o << "ScriptUtil::LuaArray<";
+    writeObjectTemplateType(o, p);
+    //o << "> param" << paramNum << "Pointer = ScriptUtil::get" << primitiveType << "Pointer(" << luaParamIndex << ");\n";
+    o << "> param" << paramNum << " = ScriptUtil::get" << primitiveType << "Pointer(" << luaParamIndex << ");\n";
+    //indent(o, indentLevel);
+    //o << p << " param" << paramNum << " = (" << p << ")param" << paramNum << "Pointer;\n";
+}
+
+static inline void outputGetParam(ostream& o, const FunctionBinding::Param& p, int i, int indentLevel, bool offsetIndex, int numBindings)
 {
     indent(o, indentLevel);
     o << "// Get parameter " << i + 1 << " off the stack.\n";
 
-    switch (p.type)
-    {
-    case FunctionBinding::Param::TYPE_UNRECOGNIZED:
-        indent(o, indentLevel);
-        o << "GP_WARN(\"Attempting to get parameter " << i + 1 << " with unrecognized type " << p.info << " as an unsigned integer.\");\n";
-    case FunctionBinding::Param::TYPE_BOOL:
-    case FunctionBinding::Param::TYPE_CHAR:
-    case FunctionBinding::Param::TYPE_SHORT:
-    case FunctionBinding::Param::TYPE_INT:
-    case FunctionBinding::Param::TYPE_LONG:
-    case FunctionBinding::Param::TYPE_UCHAR:
-    case FunctionBinding::Param::TYPE_USHORT:
-    case FunctionBinding::Param::TYPE_UINT:
-    case FunctionBinding::Param::TYPE_ULONG:
-    case FunctionBinding::Param::TYPE_FLOAT:
-    case FunctionBinding::Param::TYPE_DOUBLE:
-    case FunctionBinding::Param::TYPE_STRING:
-    case FunctionBinding::Param::TYPE_ENUM:
-        indent(o, indentLevel);
-        if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::LuaArray<" << getTypeName(p) << ">";
-        else
-            o << p;
-        o << " param" << i + 1 << " = ";
-        break;
-    default:
-        // Ignore these cases.
-        break;
-    }
-
     int paramIndex = (offsetIndex) ? i + 2 : i + 1;
+
     switch (p.type)
     {
     case FunctionBinding::Param::TYPE_BOOL:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getBoolPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "Bool", p, i+1, paramIndex, indentLevel);
         else
-            o << "ScriptUtil::luaCheckBool(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = ScriptUtil::luaCheckBool(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_CHAR:
-        o << "(char)luaL_checkint(state, " << paramIndex << ");\n";
+        indent(o, indentLevel);
+        o << p << " param" << i+1 << " = (char)luaL_checkint(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_SHORT:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getShortPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "Short", p, i+1, paramIndex, indentLevel);
         else
-            o << "(short)luaL_checkint(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (short)luaL_checkint(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_INT:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getIntPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "Int", p, i+1, paramIndex, indentLevel);
         else
-            o << "(int)luaL_checkint(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (int)luaL_checkint(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_LONG:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getLongPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "Long", p, i+1, paramIndex, indentLevel);
         else
-            o << "(long)luaL_checklong(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (long)luaL_checklong(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_UCHAR:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getUnsignedCharPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "UnsignedChar", p, i+1, paramIndex, indentLevel);
         else
-            o << "(unsigned char)luaL_checkunsigned(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (unsigned char)luaL_checkunsigned(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_USHORT:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getUnsignedShortPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "UnsignedShort", p, i+1, paramIndex, indentLevel);
         else
-            o << "(unsigned short)luaL_checkunsigned(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (unsigned short)luaL_checkunsigned(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_UINT:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getUnsignedIntPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "UnsignedInt", p, i+1, paramIndex, indentLevel);
         else
-            o << "(unsigned int)luaL_checkunsigned(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (unsigned int)luaL_checkunsigned(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_ULONG:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getUnsignedLongPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "UnsignedLong", p, i+1, paramIndex, indentLevel);
         else
-            o << "(unsigned long)luaL_checkunsigned(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (unsigned long)luaL_checkunsigned(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_FLOAT:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getFloatPointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "Float", p, i+1, paramIndex, indentLevel);
         else
-            o << "(float)luaL_checknumber(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (float)luaL_checknumber(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_DOUBLE:
+        indent(o, indentLevel);
         if (p.kind == FunctionBinding::Param::KIND_POINTER)
-            o << "ScriptUtil::getDoublePointer(" << paramIndex << ");\n";
+            writePointerParameter(o, "Double", p, i+1, paramIndex, indentLevel);
         else
-            o << "(double)luaL_checknumber(state, " << paramIndex << ");\n";
+            o << p << " param" << i+1 << " = (double)luaL_checknumber(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_STRING:
-        o << "ScriptUtil::getString(" << paramIndex << ", " << ((p.info == "string") ? "true" : "false") << ");\n";
+        indent(o, indentLevel);
+        o << p << " param" << i+1 << " = ScriptUtil::getString(" << paramIndex << ", " << ((p.info == "string") ? "true" : "false") << ");\n";
         break;
     case FunctionBinding::Param::TYPE_ENUM:
-        o << "(" << p << ")lua_enumFromString_" << Generator::getInstance()->getUniqueNameFromRef(p.info) << "(luaL_checkstring(state, " << paramIndex << "));\n";
+        indent(o, indentLevel);
+        o << p << " param" << i+1 << " = (" << p << ")lua_enumFromString_" << Generator::getInstance()->getUniqueNameFromRef(p.info) << "(luaL_checkstring(state, " << paramIndex << "));\n";
         break;
     case FunctionBinding::Param::TYPE_UNRECOGNIZED:
         // Attempt to retrieve the unrecognized type as an unsigned integer.
-        o << "(" << p.info << ")luaL_checkunsigned(state, " << paramIndex << ");\n";
+        indent(o, indentLevel);
+        o << "GP_WARN(\"Attempting to get parameter " << i + 1 << " with unrecognized type " << p.info << " as an unsigned integer.\");\n";
+        indent(o, indentLevel);
+        o << p << " param" << i+1 << " = (" << p.info << ")luaL_checkunsigned(state, " << paramIndex << ");\n";
         break;
     case FunctionBinding::Param::TYPE_OBJECT:
-        indent(o, indentLevel);
-        o << "ScriptUtil::LuaArray<" << getTypeName(p) << ">";
-        o << " param" << i + 1 << " = ";
-        o << "ScriptUtil::getObjectPointer<";
-        o << Generator::getInstance()->getIdentifier(p.info) << ">(" << paramIndex;
-        o << ", \"" << Generator::getInstance()->getUniqueNameFromRef(p.info) << "\", ";
-        o << ((p.kind != FunctionBinding::Param::KIND_POINTER) ? "true" : "false") << ");\n";
+        {
+            indent(o, indentLevel);
+            o << "bool param" << i + 1 << "Valid;\n";
+            indent(o, indentLevel);
+            o << "ScriptUtil::LuaArray<";
+            writeObjectTemplateType(o, p);
+            //o << "> param" << i+1 << "Pointer = ScriptUtil::getObjectPointer<";
+            o << "> param" << i+1 << " = ScriptUtil::getObjectPointer<";
+            writeObjectTemplateType(o, p);
+            o << ">(" << paramIndex;
+            o << ", \"" << Generator::getInstance()->getUniqueNameFromRef(p.info) << "\", ";
+            o << ((p.kind != FunctionBinding::Param::KIND_POINTER) ? "true" : "false") << ", &param" << i + 1 << "Valid);\n";
+            indent(o, indentLevel);
+            //writeObjectTemplateType(o, p);
+            //o << "* param" << i+1 << " = (";
+            //writeObjectTemplateType(o, p);
+            //o << "*)param" << i+1 << "Pointer;\n";
+            //indent(o, indentLevel);
+            o << "if (!param" << i + 1 << "Valid)\n";
+            if (numBindings > 1)
+            {
+                indent(o, indentLevel + 1);
+                o << "break;\n";
+            }
+            else
+            {
+                indent(o, indentLevel);
+                o << "{\n";
+                indent(o, indentLevel + 1);
+                o << "lua_pushstring(state, \"Failed to convert parameter " << i + 1 << " to type '" << getTypeName(p) << "'.\");\n";
+                indent(o, indentLevel + 1);
+                o << "lua_error(state);\n";
+                indent(o, indentLevel);
+                o << "}\n";
+            }
+        }
         break;
     case FunctionBinding::Param::TYPE_CONSTRUCTOR:
     case FunctionBinding::Param::TYPE_DESTRUCTOR:
@@ -831,14 +862,14 @@ static inline void outputGetParam(ostream& o, const FunctionBinding::Param& p, i
     o << "\n";
 }
 
-static inline void outputMatchedBinding(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel)
+static inline void outputMatchedBinding(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel, int numBindings)
 {
-    bool isNormalMember = (b.type == FunctionBinding::MEMBER_FUNCTION && b.returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR);
+    bool isNonStatic = (b.type == FunctionBinding::MEMBER_FUNCTION && b.returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR);
 
     // If the current invocation of the function takes zero parameters, then invoke the binding.
     if (paramCount == 0)
     {
-        outputBindingInvocation(o, b, paramCount, indentLevel);
+        outputBindingInvocation(o, b, paramCount, indentLevel, numBindings);
     }
     else
     {
@@ -848,13 +879,27 @@ static inline void outputMatchedBinding(ostream& o, const FunctionBinding& b, un
         // when the user in fact wanted to call the version with more precision.
         // (this will only happen for overloaded functions).
 
+        if (numBindings > 1)
+        {
+            o << "do\n";
+            indent(o, indentLevel);
+            o << "{\n";
+            indent(o, ++indentLevel);
+        }
+
         o << "if (";
         for (unsigned int i = 0, count = paramCount; i < count; i++)
         {
-            if (isNormalMember && i == 0)
+            if (isNonStatic && i == 0)
+            {
+                // This is always the "this / self" pointer for a member function
                 outputLuaTypeCheckInstance(o);
+            }
             else
-                outputLuaTypeCheck(o, i + 1, b.paramTypes[(isNormalMember ? i - 1 : i)]);
+            {
+                // Function parameter
+                outputLuaTypeCheck(o, i + 1, b.paramTypes[(isNonStatic ? i - 1 : i)]);
+            }
 
             if (i == count - 1)
                 o << ")\n";
@@ -867,10 +912,18 @@ static inline void outputMatchedBinding(ostream& o, const FunctionBinding& b, un
         indent(o, indentLevel);
         o << "{\n";
             
-        outputBindingInvocation(o, b, paramCount, indentLevel + 1);
+        outputBindingInvocation(o, b, paramCount, indentLevel + 1, numBindings);
 
         indent(o, indentLevel);
         o << "}\n";
+
+        if (numBindings > 1)
+        {
+            indent(o, --indentLevel);
+            o << "} while (0);\n";
+        }
+
+        o << "\n";
     }
 }
 

+ 2 - 0
gameplay-luagen/src/FunctionBinding.h

@@ -99,6 +99,8 @@ struct FunctionBinding
         string info;
         /** Whether the parameter has a default value. */
         bool hasDefaultValue;
+        /** For pointer types, the number of levels of indirection */
+        int levelsOfIndirection;
     };
 
     /**

+ 46 - 26
gameplay-luagen/src/Generator.cpp

@@ -9,7 +9,7 @@ static bool __printOperatorWarning = false;
 
 // Utility functions (local to this file).
 static string trim(const string& str);
-static string stripTypeQualifiers(const string& typeStr, FunctionBinding::Param::Kind& kind);
+static string stripTypeQualifiers(const string& typeStr, FunctionBinding::Param::Kind& kind, int& levelsOfIndirection);
 static inline bool isWantedFileNormal(const string& s);
 static inline bool isNamespaceFile(const string& s);
 static inline bool isGeneratedBindingFile(const string& s);
@@ -171,13 +171,6 @@ void Generator::run(string inDir, string outDir, string* bindingNS)
     vector<string> oldBindingsFiles;
     getFileList(outDir, oldBindingsFiles, isGeneratedBindingFile);
 
-    // Delete the old bindings.
-    for (unsigned int i = 0; i < oldBindingsFiles.size(); i++)
-    {
-        remove(oldBindingsFiles[i].c_str());
-    }
-
-
     // Get a list of the Doxygen XML files that specify a namespace.
     // Note: we must do this before adding the normal files so that
     // when we process the files sequentially, we process the namespaces
@@ -278,6 +271,16 @@ void Generator::run(string inDir, string outDir, string* bindingNS)
         GP_WARN("Detected the use of variable argument lists; this feature of C++ is not supported.");
     if (__printOperatorWarning)
         GP_WARN("Detected the use of operator overloading; this feature of C++ is not supported.");
+
+    // Delete files that are no longer needed and print warnings for them
+    for (unsigned int i = 0; i < oldBindingsFiles.size(); i++)
+    {
+        if (std::find(generatedFiles.begin(), generatedFiles.end(), oldBindingsFiles[i]) == generatedFiles.end())
+        {
+            GP_WARN("Deleting unused file: %s", oldBindingsFiles[i].c_str());
+            remove(oldBindingsFiles[i].c_str());
+        }
+    }
 }
 
 Generator::Generator()
@@ -443,6 +446,11 @@ void Generator::getClass(XMLElement* classNode, const string& name)
             if (_classes.find(parentClassName) != _classes.end())
                 classBinding.include = _classes[parentClassName].include;
         }
+        else
+        {
+            // Attempt to guess the name of the header.
+            classBinding.include = classBinding.classname + ".h";
+        }
     }
 
     // Track whether the class has any pure virtual functions.
@@ -970,6 +978,7 @@ FunctionBinding::Param Generator::getParam(XMLElement* e, bool isVariable, strin
         // Get the type string without const or reference qualifiers (and trim whitespace).
         string refId = "";
         string typeStr = "";
+        int levelsOfIndirection = 0;
         FunctionBinding::Param::Kind kind;
         {
             // Attempt to process the type as reference (i.e. class, struct, enum, typedef, etc.) type.
@@ -989,7 +998,7 @@ FunctionBinding::Param Generator::getParam(XMLElement* e, bool isVariable, strin
                 node = node->NextSibling();
             }
 
-            typeStr = stripTypeQualifiers(typeStr, kind);
+            typeStr = stripTypeQualifiers(typeStr, kind, levelsOfIndirection);
         }
 
         if (typeStr == "void")
@@ -1062,6 +1071,7 @@ FunctionBinding::Param Generator::getParam(XMLElement* e, bool isVariable, strin
         {
             p = FunctionBinding::Param(FunctionBinding::Param::TYPE_UNRECOGNIZED, kind, (refId.size() > 0) ? refId : typeStr);
         }
+        p.levelsOfIndirection = levelsOfIndirection;
 
         // Check if the type is a pointer declared with square brackets (i.e. float x[4]).
         XMLElement* arrayElement = NULL;
@@ -1075,6 +1085,7 @@ FunctionBinding::Param Generator::getParam(XMLElement* e, bool isVariable, strin
             if (i != arrayString.npos && k != arrayString.npos)
             {
                 p.kind = FunctionBinding::Param::KIND_POINTER;
+                p.levelsOfIndirection = 1;
                 if (i != k - 1)
                     p.info = arrayString.substr(i + 1, k - (i + 1));
             }
@@ -1370,14 +1381,14 @@ void Generator::generateBindings(string* bindingNS)
         generatingGameplay = true;
 
     string luaAllHStr = _outDir + string(LUA_ALL_BINDINGS_FILENAME) + string(".h");
-    ofstream luaAllH(luaAllHStr.c_str());
+    ostringstream luaAllH;
     string includeGuard = string(LUA_ALL_BINDINGS_FILENAME) + string("_H_");
     transform(includeGuard.begin(), includeGuard.end(), includeGuard.begin(), ::toupper);
     luaAllH << "#ifndef " << includeGuard << "\n";
     luaAllH << "#define " << includeGuard << "\n\n";
     
     string luaAllCppStr = _outDir + string(LUA_ALL_BINDINGS_FILENAME) + string(".cpp");
-    ofstream luaAllCpp(luaAllCppStr.c_str());
+    ostringstream luaAllCpp;
     luaAllCpp << "#include \"Base.h\"\n";
     luaAllCpp << "#include \"" << string(LUA_ALL_BINDINGS_FILENAME) << ".h\"\n\n";
     if (bindingNS)
@@ -1425,7 +1436,7 @@ void Generator::generateBindings(string* bindingNS)
 
                 // Header.
                 string enumHStr = _outDir + string("lua_") + getUniqueName(iter->first) + string(".h");
-                ofstream enumH(enumHStr.c_str());
+                ostringstream enumH;
                 includeGuard = string("lua_") + getUniqueName(iter->first) + string("_H_");
                 transform(includeGuard.begin(), includeGuard.end(), includeGuard.begin(), ::toupper);
                 enumH << "#ifndef " << includeGuard << "\n";
@@ -1448,11 +1459,12 @@ void Generator::generateBindings(string* bindingNS)
                 }
 
                 enumH << "#endif\n";
-                enumH.close();
+
+                writeFile(enumHStr, enumH.str());
 
                 // Implementation.
                 string enumCppStr = _outDir + string("lua_") + getUniqueName(iter->first) + string(".cpp"); 
-                ofstream enumCpp(enumCppStr.c_str());
+                ostringstream enumCpp(enumCppStr.c_str());
                 enumCpp << "#include \"Base.h\"\n";
                 enumCpp << "#include \"lua_" << getUniqueName(iter->first) << ".h\"\n\n";
 
@@ -1534,7 +1546,8 @@ void Generator::generateBindings(string* bindingNS)
                 {
                     enumCpp << "}\n\n";
                 }
-                enumCpp.close();
+
+                writeFile(enumCppStr, enumCpp.str());
             }
         }
     }
@@ -1574,7 +1587,7 @@ void Generator::generateBindings(string* bindingNS)
         // Write out the header file.
         {
             string path = _outDir + string(LUA_GLOBAL_FILENAME) + string(".h");
-            ofstream global(path.c_str());
+            ostringstream global;
             includeGuard = string(LUA_GLOBAL_FILENAME) + string("_H_");
             transform(includeGuard.begin(), includeGuard.end(), includeGuard.begin(), ::toupper);
             global << "#ifndef " << includeGuard << "\n";
@@ -1621,13 +1634,14 @@ void Generator::generateBindings(string* bindingNS)
             if (bindingNS)
                 global << "}\n\n";
             global << "#endif\n";
-            global.close();
+
+            writeFile(path, global.str());
         }
 
         // Write out the implementation.
         {
             string path = _outDir + string(LUA_GLOBAL_FILENAME) + string(".cpp");
-            ofstream global(path.c_str());            
+            ostringstream global;
             global << "#include \"ScriptController.h\"\n";
             global << "#include \"" << LUA_GLOBAL_FILENAME << ".h\"\n";
             map<string, set<string> >::iterator iter = _includes.find(string(LUA_GLOBAL_FILENAME) + string(".h"));
@@ -1742,14 +1756,16 @@ void Generator::generateBindings(string* bindingNS)
 
             if (bindingNS)
                 global << "}\n";
-            global.close();
+
+            writeFile(path, global.str());
         }
     }
 
     luaAllCpp << "}\n\n";
     if (bindingNS)
         luaAllCpp << "}\n\n";
-    luaAllCpp.close();
+
+    writeFile(luaAllCppStr, luaAllCpp.str());
 
     if (bindingNS)
     {
@@ -1760,7 +1776,8 @@ void Generator::generateBindings(string* bindingNS)
     if (bindingNS)
         luaAllH<< "}\n\n";
     luaAllH << "#endif\n";
-    luaAllH.close();
+
+    writeFile(luaAllHStr, luaAllH.str());
 }
 
 void Generator::getAllDerived(set<string>& derived, string classname)
@@ -1805,8 +1822,10 @@ static string trim(const string& str)
     return s;
 }
 
-static string stripTypeQualifiers(const string& typeStr, FunctionBinding::Param::Kind& kind)
+static string stripTypeQualifiers(const string& typeStr, FunctionBinding::Param::Kind& kind, int& levelsOfIndirection)
 {
+    levelsOfIndirection = 0;
+
     string type = typeStr;
     kind = FunctionBinding::Param::KIND_VALUE;
 
@@ -1819,11 +1838,12 @@ static string stripTypeQualifiers(const string& typeStr, FunctionBinding::Param:
     }
 
     // Check if the type is a pointer.
-    i = type.find("*");
-    if (i != type.npos)
+    while ((i = type.find("*")) != std::string::npos)
     {
         kind = FunctionBinding::Param::KIND_POINTER;
         type.erase(type.begin() + i);
+        ++levelsOfIndirection;
+        int j = 0;
     }
 
     // Ignore const qualifiers.
@@ -1889,7 +1909,7 @@ static bool getFileList(string directory, vector<string>& files, bool (*isWanted
 
             if (isWantedFile(filename))
             {
-                filename = string(directory) + string("/") + filename;
+                filename = string(directory) + filename;
                 files.push_back(filename);
             }
         }
@@ -1920,7 +1940,7 @@ static bool getFileList(string directory, vector<string>& files, bool (*isWanted
                 string filename = dp->d_name;
                 if (isWantedFile(filename))
                 {
-                    filename = string(directory) + string("/") + filename;
+                    filename = string(directory) + filename;
                     files.push_back(filename);
                 }
             }

+ 42 - 1
gameplay-luagen/src/main.cpp

@@ -3,6 +3,9 @@
 
 //TRACK_MEMORY();
 
+// Generated file list (extern from Base.h)
+std::vector<string> generatedFiles;
+
 void printError(const char* format, ...)
 {
     va_list argptr;
@@ -23,12 +26,47 @@ void printError(const char* format, ...)
     va_end(argptr);
 }
 
+void writeFile(const std::string& path, const std::string& text)
+{
+    generatedFiles.push_back(path);
+
+    // Read in content of path to compare before writing
+    bool changed = true;
+    ifstream in(path.c_str());
+    if (in.is_open())
+    {
+        changed = false;
+        istringstream textStream(text, istringstream::in);
+        string line1, line2;
+        while (in.good() && textStream.good())
+        {
+            getline(in, line1);
+            getline(textStream, line2);
+            if (line1 != line2 || in.good() != textStream.good())
+            {
+                // Files differ
+                changed = true;
+                break;
+            }
+        }
+        in.close();
+    }
+
+    if (changed)
+    {
+        ofstream o(path.c_str());
+        o << text;
+        o.close();
+    }
+}
+
 int main(int argc, char** argv)
 {
     // Ensure the user is calling the program correctly.
     if (argc < 2 || argc > 4)
     {
-        GP_ERROR("Usage: gameplay-luagen <doxygen-xml-input-directory> [output-directory] [binding-namespace]");
+        printf("Usage: gameplay-luagen <doxygen-xml-input-directory> [output-directory] [binding-namespace]\n");
+        exit(0);
     }
 
     // Generate the bindings.
@@ -37,6 +75,9 @@ int main(int argc, char** argv)
     Generator::releaseInstance();
     SAFE_DELETE(bindingNS);
 
+#ifdef WIN32
     system("pause");
+#endif
+    
     return 0;
 }

+ 8 - 2
gameplay-newproject.bat

@@ -171,7 +171,7 @@ copy gameplay-template\gameplay-template.vcxproj.user "%projPath%\%projName%.vcx
 call:replace "%projPath%\%projName%.vcxproj.user" GAMEPLAY_PATH "%gpPath%"
 
 REM Copy Apple XCode project files
-mkdir "%projPath%\%projName%.xcodeproj"
+mkdir "%projPath%\%projName%.xcodeproj"
 copy gameplay-template\gameplay-template.xcodeproj\project.pbxproj "%projPath%\%projName%.xcodeproj\project.pbxproj"
 call:replace "%projPath%\%projName%.xcodeproj\project.pbxproj" GAMEPLAY_PATH "%gpPath%"
 call:replace "%projPath%\%projName%.xcodeproj\project.pbxproj" TemplateGame "%className%"
@@ -181,7 +181,8 @@ copy gameplay-template\TEMPLATE_PROJECT-macosx.plist "%projPath%\%projName%-maco
 call:replace "%projPath%\%projName%-macosx.plist" TEMPLATE_UUID "%uuid%"
 call:replace "%projPath%\%projName%-macosx.plist" TEMPLATE_AUTHOR "%author%"
 
-copy gameplay-template\TEMPLATE_PROJECT-ios.plist "%projPath%\%projName%-ios.plist"
+copy gameplay-template\TEMPLATE_PROJECT-ios.plist "%projPath%\%projName%-ios.plist"
+copy gameplay-template\[email protected] "%projPath%\[email protected]"
 call:replace "%projPath%\%projName%-ios.plist" TEMPLATE_TITLE "%title%"
 call:replace "%projPath%\%projName%-ios.plist" TEMPLATE_UUID "%uuid%"
 call:replace "%projPath%\%projName%-ios.plist" TEMPLATE_AUTHOR "%author%"
@@ -230,6 +231,11 @@ mkdir "%projPath%\android\res\values"
 copy gameplay-template\android\res\values\template.strings.xml "%projPath%\android\res\values\strings.xml"
 call:replace "%projPath%\android\res\values\strings.xml" TEMPLATE_TITLE "%title%"
 
+mkdir "%projPath%\build"
+copy "gameplay-template\gameplay-template-CMakeLists.txt" "%projPath%\CMakeLists.txt"
+call:replace "%projPath%\CMakeLists.txt" TEMPLATE_PROJECT %projName%
+call:replace "%projPath%\CMakeLists.txt" TemplateGame %className%
+call:replace "%projPath%\CMakeLists.txt" GAMEPLAY_PATH %gpPath%
 
 REM Copy source files
 copy gameplay-template\src\TemplateGame.h "%projPath%\src\%className%.h"

+ 15 - 11
gameplay-newproject.sh

@@ -16,10 +16,10 @@
 #Find out which OS we're on. 
 unamestr=$(uname)
 
-#Switch-on alias expansion within the script (see http://chiefsandendians.blogspot.co.uk/2010/07/linux-scripts-and-alias.html)
+# Switch-on alias expansion within the script 
 shopt -s expand_aliases
 
-#alias the sed in-place command for OSX and Linux - incompatibilities between BSD and Linux sed args
+#Alias the sed in-place command for OSX and Linux - incompatibilities between BSD and Linux sed args
 if [[ "$unamestr" == "Darwin" ]]; then
 	alias aliassedinplace='sed -i ""'
 else
@@ -43,7 +43,6 @@ if [[ "$projName" == "" ]]; then
 	exit -1;
 fi
 echo 
-
 echo
 echo "2. Enter a game title."
 echo
@@ -117,7 +116,6 @@ if [[ "$className" == "" ]]; then
 fi
 echo 
 
-
 echo
 echo "7. Enter the project path."
 echo
@@ -159,7 +157,7 @@ gpPathAbs=`pwd`
 common_path=$projPath
 back=
 while [ "${gpPathAbs#$common_path}" = "${gpPathAbs}" ]; do
-	common_path=$(dirname $common_path)
+	common_path=$(dirname "$common_path")
 	if [ -z "$back" ]; then
 		back=".."
 	else
@@ -171,12 +169,11 @@ if [[ ${gpPathAbs} == ${common_path} ]]; then
 	gpPath=${back}
 fi
 
-
 #############################################
 # Copy Microsoft Visual Studio project files
 #############################################
 cp "gameplay-template/gameplay-template.vcxproj" "$projPath/$projName.vcxproj"
-aliassedinplace "s*TEMPLATE_PROJECT*$projectName*g" "$projPath/$projName.vcxproj"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/$projName.vcxproj"
 aliassedinplace "s*TemplateGame*$className*g" "$projPath/$projName.vcxproj"
 aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.vcxproj"
 
@@ -201,6 +198,7 @@ aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/$projName-macosx.plist"
 aliassedinplace "s*TEMPLATE_AUTHOR*$author*g" "$projPath/$projName-macosx.plist"
 
 cp "gameplay-template/TEMPLATE_PROJECT-ios.plist" "$projPath/$projName-ios.plist"
+cp "gameplay-template/[email protected]" "$projPath/[email protected]"
 aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/$projName-ios.plist"
 aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/$projName-ios.plist"
 aliassedinplace "s*TEMPLATE_AUTHOR*$author*g" "$projPath/$projName-ios.plist"
@@ -239,17 +237,23 @@ cp "gameplay-template/android/template.build.xml" "$projPath/android/build.xml"
 aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/build.xml"
 
 cp "gameplay-template/android/jni/Application.mk" "$projPath/android/jni/Application.mk"
-
 cp "gameplay-template/android/jni/template.Android.mk" "$projPath/android/jni/Android.mk"
 aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/jni/Android.mk"
 aliassedinplace "s*TemplateGame*$className*g" "$projPath/android/jni/Android.mk"
 aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/android/jni/Android.mk"
 
-
 cp "gameplay-template/icon.png" "$projPath/android/res/drawable/icon.png"
 cp "gameplay-template/android/res/values/template.strings.xml" "$projPath/android/res/values/strings.xml"
 aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/android/res/values/strings.xml"
 
+#############################################
+# Copy CMake files
+#############################################
+mkdir -p "$projPath/build"
+cp "gameplay-template/gameplay-template-CMakeLists.txt" "$projPath/CMakeLists.txt"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/CMakeLists.txt"
+aliassedinplace "s*TemplateGame*$className*g" "$projPath/CMakeLists.txt"
+aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/CMakeLists.txt"
 
 #############################################
 # Copy source files
@@ -271,9 +275,9 @@ aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/game.config"
 
 # Open the new project folder, use xdg-open on Linux
 if [[ "$unamestr" == "Linux" ]]; then
-	xdg-open $projPath
+	xdg-open "$projPath"
 else
-	open $projPath
+	open "$projPath"
 fi
 
 exit 0

BIN
gameplay-template/[email protected]


+ 31 - 31
gameplay-template/android/template.AndroidManifest.xml

@@ -1,32 +1,32 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="TEMPLATE_UUID"
-        android:versionCode="1"
-        android:versionName="1.0">
-
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-        
-    <!-- This is the platform API where the app was introduced. -->
-    <uses-sdk android:minSdkVersion="9" />
-	<uses-feature android:glEsVersion="0x00020000"/>
-
-    <application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="true">
-
-        <!-- Our activity is the built-in NativeActivity framework class.
-             This will take care of integrating with our NDK code. -->
-        <activity android:name="android.app.NativeActivity"
-                android:label="@string/app_name"
-                android:configChanges="orientation|keyboardHidden"
-				android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-				android:screenOrientation="landscape">
-            <!-- Tell NativeActivity the name of or .so -->
-            <meta-data android:name="android.app.lib_name"
-                    android:value="TEMPLATE_PROJECT" />
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="TEMPLATE_UUID"
+        android:versionCode="1"
+        android:versionName="1.0">
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+        
+    <!-- This is the platform API where the app was introduced. -->
+    <uses-sdk android:minSdkVersion="9" />
+	<uses-feature android:glEsVersion="0x00020000"/>
+
+    <application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="true">
+
+        <!-- Our activity is the built-in NativeActivity framework class.
+             This will take care of integrating with our NDK code. -->
+        <activity android:name="android.app.NativeActivity"
+                android:label="@string/app_name"
+                android:configChanges="orientation|keyboardHidden"
+				android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+				android:screenOrientation="landscape">
+            <!-- Tell NativeActivity the name of or .so -->
+            <meta-data android:name="android.app.lib_name"
+                    android:value="TEMPLATE_PROJECT" />
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
 </manifest> 

+ 3 - 4
gameplay-template/android/template.build.xml

@@ -62,10 +62,9 @@
        If this is not done in place, override ${out.dex.input.absolute.dir} */
        -->
     <target name="-post-compile">
-        <copy file="../res/box.gpb" tofile="assets/res/box.gpb"/>
-        <copy file="../res/box.material" tofile="assets/res/box.material"/>
-        <copy file="../res/colored.vert" tofile="assets/res/colored.vert"/>
-        <copy file="../res/colored.frag" tofile="assets/res/colored.frag"/>
+        <copy todir="assets/res">
+            <fileset dir="../res" />
+        </copy>
     </target>
 
     <!-- Import the actual build file.

+ 113 - 0
gameplay-template/gameplay-template-CMakeLists.txt

@@ -0,0 +1,113 @@
+cmake_minimum_required(VERSION 2.7)
+PROJECT(TEMPLATE_PROJECT)
+
+set(GAME_NAME TEMPLATE_PROJECT)
+
+if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+    set(ARCH_DIR "x64" )
+else( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+    set(ARCH_DIR "x86" )
+endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+
+set(GAMEPLAY_SRC_PATH "GAMEPLAY_PATH") 
+set(GAMEPLAY_EXT_LIBS_PATH "${GAMEPLAY_SRC_PATH}/external-deps")
+
+set(TARGET_OS "LINUX")
+set(TARGET_OS_DIR "linux")
+
+set(GAME_OUTPUT_DIR "${CMAKE_SOURCE_DIR}/bin/${TARGET_OS_DIR}")
+
+macro (append_gameplay_lib listToAppend)
+    set(libName gameplay)
+    find_library(FOUND_LIB_${libName} ${libName} HINTS
+        "${GAMEPLAY_SRC_PATH}/cmake/gameplay" "${GAMEPLAY_SRC_PATH}/build/gameplay" "${GAMEPLAY_SRC_PATH}/gameplay/src")
+    set(${listToAppend} ${${listToAppend}} ${FOUND_LIB_${libName}})
+endmacro(append_gameplay_lib)
+
+macro (append_gameplay_ext_lib listToAppend libName libDirName)
+    IF("${libDirName}" STREQUAL "")
+        find_library(FOUND_LIB_${libName} ${libName})
+    ELSE("${libDirName}" STREQUAL "")
+        set(pathToSearch
+            "${GAMEPLAY_EXT_LIBS_PATH}/${libDirName}/lib/${TARGET_OS_DIR}/${ARCH_DIR}")
+        find_library(FOUND_LIB_${libName} ${libName} HINTS ${pathToSearch})
+    ENDIF("${libDirName}" STREQUAL "")
+
+    set(${listToAppend} ${${listToAppend}} ${FOUND_LIB_${libName}})
+    message(STATUS "Library Found: ${libName} Path: ${FOUND_LIB_${libName}}")
+endmacro (append_gameplay_ext_lib)
+
+macro(copy_files TARGET_NAME GLOBPAT SOURCE DESTINATION)
+  file(GLOB_RECURSE COPY_FILES
+    RELATIVE ${SOURCE}
+    "${SOURCE}/${GLOBPAT}")
+  add_custom_target(${TARGET_NAME} ALL
+    COMMENT "Copying files: ${SOURCE}/${GLOBPAT}")
+
+  foreach(FILENAME ${COPY_FILES})
+    set(SRC "${SOURCE}/${FILENAME}")
+    set(DST "${DESTINATION}/${FILENAME}")
+
+    add_custom_command(
+      TARGET ${TARGET_NAME}
+      COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SRC} ${DST}
+      )
+  endforeach(FILENAME)
+endmacro(copy_files)
+
+include_directories( 
+    ${GAMEPLAY_SRC_PATH}/gameplay/src
+    ${GAMEPLAY_SRC_PATH}/external-deps/lua/include
+    ${GAMEPLAY_SRC_PATH}/external-deps/bullet/include
+    ${GAMEPLAY_SRC_PATH}/external-deps/libpng/include
+    ${GAMEPLAY_SRC_PATH}/external-deps/oggvorbis/include
+    ${GAMEPLAY_SRC_PATH}/external-deps/zlib/include
+    ${GAMEPLAY_SRC_PATH}/external-deps/openal/include
+    ${GAMEPLAY_SRC_PATH}/external-deps/glew/include
+)
+
+append_gameplay_lib(GAMEPLAY_LIBRARIES)
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "m" "" )
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "lua" "lua")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "png" "libpng")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "z" "zlib")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "vorbis" "oggvorbis")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "ogg" "oggvorbis")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "BulletDynamics" "bullet")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "BulletCollision" "bullet")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "LinearMath" "bullet")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "openal" "openal")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "GLEW" "glew")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "GL" "")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "rt" "" )
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "dl" "")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "X11" "")
+append_gameplay_ext_lib(GAMEPLAY_LIBRARIES "pthread" "" )
+
+add_definitions(-D__linux__)
+
+source_group(res FILES ${GAME_RES} ${GAMEPLAY_RES} ${GAME_RES_SHADERS} ${GAME_RES_SHADERS_LIB})
+source_group(src FILES ${GAME_SRC})
+
+set(GAME_SRC
+	src/TemplateGame.cpp
+	src/TemplateGame.h
+)
+
+add_executable(${GAME_NAME}
+    ${GAME_SRC}
+)
+
+target_link_libraries(${GAME_NAME} ${GAMEPLAY_LIBRARIES})
+
+set_target_properties(${GAME_NAME} PROPERTIES
+    OUTPUT_NAME "${GAME_NAME}"
+    RUNTIME_OUTPUT_DIRECTORY "${GAME_OUTPUT_DIR}"
+    LIBRARY_OUTPUT_DIRECTORY "${GAME_OUTPUT_DIR}"
+)
+
+#TODO: Copy res files to the bin dir, it is done that way so we can make post
+#processing to the the res files in the future like zipping or preparation to
+#per platfom format.
+copy_files(CopyRes * "${CMAKE_SOURCE_DIR}/res" "${GAME_OUTPUT_DIR}/res")
+copy_files(CopyConfig *.config "${CMAKE_SOURCE_DIR}" "${GAME_OUTPUT_DIR}")

+ 155 - 7
gameplay-template/gameplay-template.vcxproj

@@ -5,14 +5,26 @@
       <Configuration>DebugMem</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMem|x64">
+      <Configuration>DebugMem</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <Keyword>Win32Proj</Keyword>
@@ -24,29 +36,54 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
@@ -55,18 +92,35 @@
     <CustomBuildBeforeTargets>
     </CustomBuildBeforeTargets>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets />
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
     <LinkIncremental>true</LinkIncremental>
     <OutDir>$(Configuration)\</OutDir>
     <ExecutablePath>$(ExecutablePath)</ExecutablePath>
     <CustomBuildBeforeTargets />
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
+    <CustomBuildBeforeTargets />
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
     <OutDir>$(Configuration)\</OutDir>
     <CustomBuildBeforeTargets>
     </CustomBuildBeforeTargets>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(Configuration)\</OutDir>
+    <CustomBuildBeforeTargets />
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>
@@ -82,7 +136,37 @@
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows;GAMEPLAY_PATH/external-deps/bullet/lib/windows;GAMEPLAY_PATH/external-deps/openal/lib/windows;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows;GAMEPLAY_PATH/external-deps/glew/lib/windows;GAMEPLAY_PATH/external-deps/libpng/lib/windows;GAMEPLAY_PATH/external-deps/zlib/lib/windows;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows/x86;GAMEPLAY_PATH/external-deps/bullet/lib/windows/x86;GAMEPLAY_PATH/external-deps/openal/lib/windows/x86;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows/x86;GAMEPLAY_PATH/external-deps/glew/lib/windows/x86;GAMEPLAY_PATH/external-deps/libpng/lib/windows/x86;GAMEPLAY_PATH/external-deps/zlib/lib/windows/x86;GAMEPLAY_PATH/gameplay/windows/x86/$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH/external-deps/lua/include;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>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows/x64;GAMEPLAY_PATH/external-deps/bullet/lib/windows/x64;GAMEPLAY_PATH/external-deps/openal/lib/windows/x64;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows/x64;GAMEPLAY_PATH/external-deps/glew/lib/windows/x64;GAMEPLAY_PATH/external-deps/libpng/lib/windows/x64;GAMEPLAY_PATH/external-deps/zlib/lib/windows/x64;GAMEPLAY_PATH/gameplay/windows/x64/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
       <Command>
@@ -114,7 +198,39 @@
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows;GAMEPLAY_PATH/external-deps/bullet/lib/windows;GAMEPLAY_PATH/external-deps/openal/lib/windows;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows;GAMEPLAY_PATH/external-deps/glew/lib/windows;GAMEPLAY_PATH/external-deps/libpng/lib/windows;GAMEPLAY_PATH/external-deps/zlib/lib/windows;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows/x86;GAMEPLAY_PATH/external-deps/bullet/lib/windows/x86;GAMEPLAY_PATH/external-deps/openal/lib/windows/x86;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows/x86;GAMEPLAY_PATH/external-deps/glew/lib/windows/x86;GAMEPLAY_PATH/external-deps/libpng/lib/windows/x86;GAMEPLAY_PATH/external-deps/zlib/lib/windows/x86;GAMEPLAY_PATH/gameplay/windows/x86/$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;GAMEPLAY_MEM_LEAK_DETECTION;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH/external-deps/lua/include;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>
+      <ShowIncludes>false</ShowIncludes>
+      <PreprocessToFile>false</PreprocessToFile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows/x64;GAMEPLAY_PATH/external-deps/bullet/lib/windows/x64;GAMEPLAY_PATH/external-deps/openal/lib/windows/x64;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows/x64;GAMEPLAY_PATH/external-deps/glew/lib/windows/x64;GAMEPLAY_PATH/external-deps/libpng/lib/windows/x64;GAMEPLAY_PATH/external-deps/zlib/lib/windows/x64;GAMEPLAY_PATH/gameplay/windows/x64/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
       <Command>
@@ -146,7 +262,39 @@
       <EnableCOMDATFolding>true</EnableCOMDATFolding>
       <OptimizeReferences>true</OptimizeReferences>
       <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows;GAMEPLAY_PATH/external-deps/bullet/lib/windows;GAMEPLAY_PATH/external-deps/openal/lib/windows;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows;GAMEPLAY_PATH/external-deps/glew/lib/windows;GAMEPLAY_PATH/external-deps/libpng/lib/windows;GAMEPLAY_PATH/external-deps/zlib/lib/windows;GAMEPLAY_PATH/gameplay/$(Configuration)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows/x86;GAMEPLAY_PATH/external-deps/bullet/lib/windows/x86;GAMEPLAY_PATH/external-deps/openal/lib/windows/x86;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows/x86;GAMEPLAY_PATH/external-deps/glew/lib/windows/x86;GAMEPLAY_PATH/external-deps/libpng/lib/windows/x86;GAMEPLAY_PATH/external-deps/zlib/lib/windows/x86;GAMEPLAY_PATH/gameplay/windows/x86/$(Configuration)</AdditionalLibraryDirectories>
+    </Link>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+    <CustomBuildStep>
+      <Command>
+      </Command>
+      <Message>
+      </Message>
+      <Outputs>
+      </Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>GAMEPLAY_PATH/external-deps/lua/include;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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>lua.lib;OpenAL32.lib;OpenGL32.lib;GLU32.lib;glew32.lib;libpng14.lib;zlib.lib;gameplay.lib;BulletDynamics.lib;BulletCollision.lib;LinearMath.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>GAMEPLAY_PATH/external-deps/lua/lib/windows/x64;GAMEPLAY_PATH/external-deps/bullet/lib/windows/x64;GAMEPLAY_PATH/external-deps/openal/lib/windows/x64;GAMEPLAY_PATH/external-deps/oggvorbis/lib/windows/x64;GAMEPLAY_PATH/external-deps/glew/lib/windows/x64;GAMEPLAY_PATH/external-deps/libpng/lib/windows/x64;GAMEPLAY_PATH/external-deps/zlib/lib/windows/x64;GAMEPLAY_PATH/gameplay/windows/x64/$(Configuration)</AdditionalLibraryDirectories>
     </Link>
     <PostBuildEvent>
       <Command>
@@ -162,17 +310,17 @@
     </CustomBuildStep>
   </ItemDefinitionGroup>
   <ItemGroup>
-    <None Include="bar-descriptor.xml" >
-        <SubType>Designer</SubType>
+    <None Include="bar-descriptor.xml">
+      <SubType>Designer</SubType>
     </None>
     <None Include="game.config" />
-	<None Include="icon.png" />
+    <None Include="icon.png" />
     <None Include="res\box.dae" />
     <None Include="res\box.gpb" />
     <None Include="res\box.material" />
     <None Include="res\colored.frag" />
     <None Include="res\colored.vert" />
-  </ItemGroup> 
+  </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\TemplateGame.cpp" />
   </ItemGroup>

+ 15 - 3
gameplay-template/gameplay-template.vcxproj.user

@@ -1,15 +1,27 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows/x86;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows/x64;</LocalDebuggerEnvironment>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-	<LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
     <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
-	<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <LocalDebuggerEnvironment>PATH=%PATH%;GAMEPLAY_PATH/bin/windows;</LocalDebuggerEnvironment>
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
   </PropertyGroup>
 </Project>

+ 146 - 92
gameplay-template/gameplay-template.xcodeproj/project.pbxproj

@@ -7,9 +7,32 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
-		428F7BDE15CB131A009ED24C /* game.config in Resources */ = {isa = PBXBuildFile; fileRef = 428F7BDD15CB131A009ED24C /* game.config */; };
+		42049B5816ADBB61005DD1F9 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5216ADBB61005DD1F9 /* CoreMotion.framework */; };
+		42049B5916ADBB61005DD1F9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5316ADBB61005DD1F9 /* Foundation.framework */; };
+		42049B5A16ADBB61005DD1F9 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5416ADBB61005DD1F9 /* OpenAL.framework */; };
+		42049B5B16ADBB61005DD1F9 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5516ADBB61005DD1F9 /* OpenGLES.framework */; };
+		42049B5C16ADBB61005DD1F9 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5616ADBB61005DD1F9 /* QuartzCore.framework */; };
+		42049B5D16ADBB61005DD1F9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5716ADBB61005DD1F9 /* UIKit.framework */; };
+		42049B5F16ADBBF5005DD1F9 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B5E16ADBBF5005DD1F9 /* libz.dylib */; };
+		42049B6116ADBC0F005DD1F9 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6016ADBC0F005DD1F9 /* libbullet.a */; };
+		42049B6316ADBC30005DD1F9 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6216ADBC30005DD1F9 /* libbullet.a */; };
+		42049B6516ADBC47005DD1F9 /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6416ADBC47005DD1F9 /* liblua.a */; };
+		42049B6A16ADBC63005DD1F9 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6616ADBC63005DD1F9 /* libogg.a */; };
+		42049B6B16ADBC63005DD1F9 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6716ADBC63005DD1F9 /* libvorbis.a */; };
+		42049B6C16ADBC63005DD1F9 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6816ADBC63005DD1F9 /* libvorbisenc.a */; };
+		42049B6D16ADBC63005DD1F9 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6916ADBC63005DD1F9 /* libvorbisfile.a */; };
+		42049B6F16ADBC7A005DD1F9 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B6E16ADBC7A005DD1F9 /* libpng.a */; };
+		42049B7116ADBC8B005DD1F9 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7016ADBC8B005DD1F9 /* libpng.a */; };
+		42049B7316ADBCAB005DD1F9 /* liblua.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7216ADBCAB005DD1F9 /* liblua.a */; };
+		42049B7816ADBCC3005DD1F9 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7416ADBCC3005DD1F9 /* libogg.a */; };
+		42049B7916ADBCC3005DD1F9 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7516ADBCC3005DD1F9 /* libvorbis.a */; };
+		42049B7A16ADBCC3005DD1F9 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7616ADBCC3005DD1F9 /* libvorbisenc.a */; };
+		42049B7B16ADBCC3005DD1F9 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42049B7716ADBCC3005DD1F9 /* libvorbisfile.a */; };
+		42049B7D16ADBCDB005DD1F9 /* [email protected] in Resources */ = {isa = PBXBuildFile; fileRef = 42049B7C16ADBCDB005DD1F9 /* [email protected] */; };
+		421539CA16ADC583001308A3 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 421539C916ADC583001308A3 /* libgameplay.a */; };
+		421539CD16ADC592001308A3 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 421539CC16ADC592001308A3 /* libgameplay.a */; };
 		424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 424CC03B161FCBDD00577827 /* IOKit.framework */; };
+		428F7BDE15CB131A009ED24C /* game.config in Resources */ = {isa = PBXBuildFile; fileRef = 428F7BDD15CB131A009ED24C /* game.config */; };
 		42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C932C01491A0DB0098216A /* Cocoa.framework */; };
 		42C932EE1491A4CB0098216A /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		42C932F11491A5160098216A /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
@@ -17,36 +40,39 @@
 		42C933171491A5EB0098216A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933161491A5EB0098216A /* OpenGL.framework */; };
 		42C9331D1491A6750098216A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9331C1491A6750098216A /* QuartzCore.framework */; };
 		42C9331F1491A67F0098216A /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9331E1491A67F0098216A /* OpenAL.framework */; };
-		42C933211491A6C70098216A /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933201491A6C70098216A /* libbullet.a */; };
-		42C933261491A6E50098216A /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933221491A6E50098216A /* libogg.a */; };
-		42C933271491A6E50098216A /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933231491A6E50098216A /* libvorbis.a */; };
-		42C933281491A6E50098216A /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933241491A6E50098216A /* libvorbisenc.a */; };
-		42C933291491A6E50098216A /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933251491A6E50098216A /* libvorbisfile.a */; };
-		42C9332C1491A7680098216A /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332A1491A7390098216A /* libpng.a */; };
 		42C9332F1491A78D0098216A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332D1491A7810098216A /* libz.dylib */; };
 		5B61611614CCC24C0073B857 /* TemplateGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42C932EF1491A5160098216A /* TemplateGame.cpp */; };
-		5B61611814CCC24C0073B857 /* libgameplay.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42438B521491AD2000D218B8 /* libgameplay.a */; };
-		5B61611914CCC24C0073B857 /* libbullet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933201491A6C70098216A /* libbullet.a */; };
-		5B61611A14CCC24C0073B857 /* libogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933221491A6E50098216A /* libogg.a */; };
-		5B61611B14CCC24C0073B857 /* libvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933231491A6E50098216A /* libvorbis.a */; };
-		5B61611C14CCC24C0073B857 /* libvorbisenc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933241491A6E50098216A /* libvorbisenc.a */; };
-		5B61611D14CCC24C0073B857 /* libvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C933251491A6E50098216A /* libvorbisfile.a */; };
-		5B61611E14CCC24C0073B857 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332A1491A7390098216A /* libpng.a */; };
-		5B61611F14CCC24C0073B857 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 42C9332D1491A7810098216A /* libz.dylib */; };
 		5B61612614CCC24C0073B857 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 42C932ED1491A4CB0098216A /* icon.png */; };
 		5B61612714CCC24C0073B857 /* res in Resources */ = {isa = PBXBuildFile; fileRef = 42C932F21491A53E0098216A /* res */; };
-		5BAF206D152F2DDD003E2AC3 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2067152F2DDD003E2AC3 /* CoreMotion.framework */; };
-		5BAF206E152F2DDD003E2AC3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2068152F2DDD003E2AC3 /* Foundation.framework */; };
-		5BAF206F152F2DDD003E2AC3 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF2069152F2DDD003E2AC3 /* OpenAL.framework */; };
-		5BAF2070152F2DDD003E2AC3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206A152F2DDD003E2AC3 /* OpenGLES.framework */; };
-		5BAF2071152F2DDD003E2AC3 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206B152F2DDD003E2AC3 /* QuartzCore.framework */; };
-		5BAF2072152F2DDD003E2AC3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5BAF206C152F2DDD003E2AC3 /* UIKit.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
-		428F7BDD15CB131A009ED24C /* game.config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = game.config; sourceTree = "<group>"; };
-		42438B521491AD2000D218B8 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug/libgameplay.a"; sourceTree = "<group>"; };
+		42049B5216ADBB61005DD1F9 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5316ADBB61005DD1F9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5416ADBB61005DD1F9 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5516ADBB61005DD1F9 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5616ADBB61005DD1F9 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5716ADBB61005DD1F9 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+		42049B5E16ADBBF5005DD1F9 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
+		42049B6016ADBC0F005DD1F9 /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "GAMEPLAY_PATH/external-deps/bullet/lib/ios/armv7/libbullet.a"; sourceTree = "<group>"; };
+		42049B6216ADBC30005DD1F9 /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "GAMEPLAY_PATH/external-deps/bullet/lib/macosx/libbullet.a"; sourceTree = "<group>"; };
+		42049B6416ADBC47005DD1F9 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "GAMEPLAY_PATH/external-deps/lua/lib/macosx/liblua.a"; sourceTree = "<group>"; };
+		42049B6616ADBC63005DD1F9 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libogg.a"; sourceTree = "<group>"; };
+		42049B6716ADBC63005DD1F9 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbis.a"; sourceTree = "<group>"; };
+		42049B6816ADBC63005DD1F9 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbisenc.a"; sourceTree = "<group>"; };
+		42049B6916ADBC63005DD1F9 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbisfile.a"; sourceTree = "<group>"; };
+		42049B6E16ADBC7A005DD1F9 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "GAMEPLAY_PATH/external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
+		42049B7016ADBC8B005DD1F9 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "GAMEPLAY_PATH/external-deps/libpng/lib/ios/armv7/libpng.a"; sourceTree = "<group>"; };
+		42049B7216ADBCAB005DD1F9 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "GAMEPLAY_PATH/external-deps/lua/lib/ios/armv7/liblua.a"; sourceTree = "<group>"; };
+		42049B7416ADBCC3005DD1F9 /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/armv7/libogg.a"; sourceTree = "<group>"; };
+		42049B7516ADBCC3005DD1F9 /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/armv7/libvorbis.a"; sourceTree = "<group>"; };
+		42049B7616ADBCC3005DD1F9 /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/armv7/libvorbisenc.a"; sourceTree = "<group>"; };
+		42049B7716ADBCC3005DD1F9 /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/armv7/libvorbisfile.a"; sourceTree = "<group>"; };
+		42049B7C16ADBCDB005DD1F9 /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
+		421539C916ADC583001308A3 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug/libgameplay.a"; sourceTree = "<group>"; };
+		421539CC16ADC592001308A3 /* libgameplay.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgameplay.a; path = "~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug-iphoneos/libgameplay.a"; sourceTree = "<group>"; };
 		424CC03B161FCBDD00577827 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
+		428F7BDD15CB131A009ED24C /* game.config */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = game.config; sourceTree = "<group>"; };
 		42C932BC1491A0DB0098216A /* TEMPLATE_PROJECT-macosx.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-macosx.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		42C932C01491A0DB0098216A /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
 		42C932ED1491A4CB0098216A /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = "<group>"; };
@@ -56,22 +82,10 @@
 		42C933161491A5EB0098216A /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		42C9331C1491A6750098216A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
 		42C9331E1491A67F0098216A /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
-		42C933201491A6C70098216A /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "GAMEPLAY_PATH/external-deps/bullet/lib/macosx/libbullet.a"; sourceTree = "<group>"; };
-		42C933221491A6E50098216A /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libogg.a"; sourceTree = "<group>"; };
-		42C933231491A6E50098216A /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbis.a"; sourceTree = "<group>"; };
-		42C933241491A6E50098216A /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbisenc.a"; sourceTree = "<group>"; };
-		42C933251491A6E50098216A /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx/libvorbisfile.a"; sourceTree = "<group>"; };
-		42C9332A1491A7390098216A /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "GAMEPLAY_PATH/external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
 		42C9332D1491A7810098216A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
 		5B61611214CCC2200073B857 /* TEMPLATE_PROJECT-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TEMPLATE_PROJECT-macosx.plist"; sourceTree = "<group>"; };
 		5B61612C14CCC24C0073B857 /* TEMPLATE_PROJECT-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "TEMPLATE_PROJECT-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
 		5B61612E14CCC24D0073B857 /* TEMPLATE_PROJECT-ios.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TEMPLATE_PROJECT-ios.plist"; sourceTree = "<group>"; };
-		5BAF2067152F2DDD003E2AC3 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2068152F2DDD003E2AC3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF2069152F2DDD003E2AC3 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF206A152F2DDD003E2AC3 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF206B152F2DDD003E2AC3 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
-		5BAF206C152F2DDD003E2AC3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
 		5BC4E77F150F879E00CBE1C0 /* gameplay.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gameplay.xcodeproj; path = GAMEPLAY_PATH/gameplay/gameplay.xcodeproj; sourceTree = SOURCE_ROOT; };
 		5BC4E849150F911D00CBE1C0 /* shaders */ = {isa = PBXFileReference; lastKnownFileType = text; name = shaders; path = GAMEPLAY_PATH/gameplay/res/shaders; sourceTree = SOURCE_ROOT; };
 /* End PBXFileReference section */
@@ -81,13 +95,14 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				42438B531491AD2000D218B8 /* libgameplay.a in Frameworks */,
-				42C933211491A6C70098216A /* libbullet.a in Frameworks */,
-				42C933261491A6E50098216A /* libogg.a in Frameworks */,
-				42C933271491A6E50098216A /* libvorbis.a in Frameworks */,
-				42C933281491A6E50098216A /* libvorbisenc.a in Frameworks */,
-				42C933291491A6E50098216A /* libvorbisfile.a in Frameworks */,
-				42C9332C1491A7680098216A /* libpng.a in Frameworks */,
+				421539CA16ADC583001308A3 /* libgameplay.a in Frameworks */,
+				42049B6316ADBC30005DD1F9 /* libbullet.a in Frameworks */,
+				42049B6516ADBC47005DD1F9 /* liblua.a in Frameworks */,
+				42049B6F16ADBC7A005DD1F9 /* libpng.a in Frameworks */,
+				42049B6A16ADBC63005DD1F9 /* libogg.a in Frameworks */,
+				42049B6B16ADBC63005DD1F9 /* libvorbis.a in Frameworks */,
+				42049B6C16ADBC63005DD1F9 /* libvorbisenc.a in Frameworks */,
+				42049B6D16ADBC63005DD1F9 /* libvorbisfile.a in Frameworks */,
 				42C9332F1491A78D0098216A /* libz.dylib in Frameworks */,
 				424CC03C161FCBDD00577827 /* IOKit.framework in Frameworks */,
 				42C932C11491A0DB0098216A /* Cocoa.framework in Frameworks */,
@@ -101,20 +116,21 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				5BAF206D152F2DDD003E2AC3 /* CoreMotion.framework in Frameworks */,
-				5BAF206E152F2DDD003E2AC3 /* Foundation.framework in Frameworks */,
-				5BAF206F152F2DDD003E2AC3 /* OpenAL.framework in Frameworks */,
-				5BAF2070152F2DDD003E2AC3 /* OpenGLES.framework in Frameworks */,
-				5BAF2071152F2DDD003E2AC3 /* QuartzCore.framework in Frameworks */,
-				5BAF2072152F2DDD003E2AC3 /* UIKit.framework in Frameworks */,
-				5B61611814CCC24C0073B857 /* libgameplay.a in Frameworks */,
-				5B61611914CCC24C0073B857 /* libbullet.a in Frameworks */,
-				5B61611A14CCC24C0073B857 /* libogg.a in Frameworks */,
-				5B61611B14CCC24C0073B857 /* libvorbis.a in Frameworks */,
-				5B61611C14CCC24C0073B857 /* libvorbisenc.a in Frameworks */,
-				5B61611D14CCC24C0073B857 /* libvorbisfile.a in Frameworks */,
-				5B61611E14CCC24C0073B857 /* libpng.a in Frameworks */,
-				5B61611F14CCC24C0073B857 /* libz.dylib in Frameworks */,
+				421539CD16ADC592001308A3 /* libgameplay.a in Frameworks */,
+				42049B6116ADBC0F005DD1F9 /* libbullet.a in Frameworks */,
+				42049B7316ADBCAB005DD1F9 /* liblua.a in Frameworks */,
+				42049B7116ADBC8B005DD1F9 /* libpng.a in Frameworks */,
+				42049B7816ADBCC3005DD1F9 /* libogg.a in Frameworks */,
+				42049B7916ADBCC3005DD1F9 /* libvorbis.a in Frameworks */,
+				42049B7A16ADBCC3005DD1F9 /* libvorbisenc.a in Frameworks */,
+				42049B7B16ADBCC3005DD1F9 /* libvorbisfile.a in Frameworks */,
+				42049B5F16ADBBF5005DD1F9 /* libz.dylib in Frameworks */,
+				42049B5816ADBB61005DD1F9 /* CoreMotion.framework in Frameworks */,
+				42049B5916ADBB61005DD1F9 /* Foundation.framework in Frameworks */,
+				42049B5A16ADBB61005DD1F9 /* OpenAL.framework in Frameworks */,
+				42049B5B16ADBB61005DD1F9 /* OpenGLES.framework in Frameworks */,
+				42049B5C16ADBB61005DD1F9 /* QuartzCore.framework in Frameworks */,
+				42049B5D16ADBB61005DD1F9 /* UIKit.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -124,6 +140,7 @@
 		42C932B11491A0DB0098216A = {
 			isa = PBXGroup;
 			children = (
+				42049B7C16ADBCDB005DD1F9 /* [email protected] */,
 				5B61611214CCC2200073B857 /* TEMPLATE_PROJECT-macosx.plist */,
 				5B61612E14CCC24D0073B857 /* TEMPLATE_PROJECT-ios.plist */,
 				42C932ED1491A4CB0098216A /* icon.png */,
@@ -148,7 +165,6 @@
 		42C932BF1491A0DB0098216A /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
-				5BC4E825150F8CE600CBE1C0 /* GamePlay */,
 				5B61613A14CCC3590073B857 /* MacOSX */,
 				5B61613914CCC3560073B857 /* iOS */,
 			);
@@ -167,14 +183,9 @@
 		42C932DD1491A1050098216A /* Libraries */ = {
 			isa = PBXGroup;
 			children = (
-				42438B521491AD2000D218B8 /* libgameplay.a */,
-				42C933201491A6C70098216A /* libbullet.a */,
-				42C933221491A6E50098216A /* libogg.a */,
-				42C933231491A6E50098216A /* libvorbis.a */,
-				42C933241491A6E50098216A /* libvorbisenc.a */,
-				42C933251491A6E50098216A /* libvorbisfile.a */,
-				42C9332A1491A7390098216A /* libpng.a */,
-				42C9332D1491A7810098216A /* libz.dylib */,
+				5BC4E825150F8CE600CBE1C0 /* GamePlay */,
+				F1F49B8516AD8C22008715A2 /* MacOSX */,
+				F1F49B8716AD8C30008715A2 /* iOS */,
 			);
 			name = Libraries;
 			sourceTree = "<group>";
@@ -182,12 +193,12 @@
 		5B61613914CCC3560073B857 /* iOS */ = {
 			isa = PBXGroup;
 			children = (
-				5BAF2067152F2DDD003E2AC3 /* CoreMotion.framework */,
-				5BAF2068152F2DDD003E2AC3 /* Foundation.framework */,
-				5BAF2069152F2DDD003E2AC3 /* OpenAL.framework */,
-				5BAF206A152F2DDD003E2AC3 /* OpenGLES.framework */,
-				5BAF206B152F2DDD003E2AC3 /* QuartzCore.framework */,
-				5BAF206C152F2DDD003E2AC3 /* UIKit.framework */,
+				42049B5216ADBB61005DD1F9 /* CoreMotion.framework */,
+				42049B5316ADBB61005DD1F9 /* Foundation.framework */,
+				42049B5416ADBB61005DD1F9 /* OpenAL.framework */,
+				42049B5516ADBB61005DD1F9 /* OpenGLES.framework */,
+				42049B5616ADBB61005DD1F9 /* QuartzCore.framework */,
+				42049B5716ADBB61005DD1F9 /* UIKit.framework */,
 			);
 			name = iOS;
 			sourceTree = "<group>";
@@ -207,12 +218,44 @@
 		5BC4E825150F8CE600CBE1C0 /* GamePlay */ = {
 			isa = PBXGroup;
 			children = (
-				5BC4E849150F911D00CBE1C0 /* shaders */,
 				5BC4E77F150F879E00CBE1C0 /* gameplay.xcodeproj */,
+				5BC4E849150F911D00CBE1C0 /* shaders */,
 			);
 			name = GamePlay;
 			sourceTree = "<group>";
 		};
+		F1F49B8516AD8C22008715A2 /* MacOSX */ = {
+			isa = PBXGroup;
+			children = (
+				421539C916ADC583001308A3 /* libgameplay.a */,
+				42049B6216ADBC30005DD1F9 /* libbullet.a */,
+				42049B6416ADBC47005DD1F9 /* liblua.a */,
+				42049B6616ADBC63005DD1F9 /* libogg.a */,
+				42049B6716ADBC63005DD1F9 /* libvorbis.a */,
+				42049B6816ADBC63005DD1F9 /* libvorbisenc.a */,
+				42049B6916ADBC63005DD1F9 /* libvorbisfile.a */,
+				42049B6E16ADBC7A005DD1F9 /* libpng.a */,
+				42C9332D1491A7810098216A /* libz.dylib */,
+			);
+			name = MacOSX;
+			sourceTree = "<group>";
+		};
+		F1F49B8716AD8C30008715A2 /* iOS */ = {
+			isa = PBXGroup;
+			children = (
+				421539CC16ADC592001308A3 /* libgameplay.a */,
+				42049B6016ADBC0F005DD1F9 /* libbullet.a */,
+				42049B7216ADBCAB005DD1F9 /* liblua.a */,
+				42049B7016ADBC8B005DD1F9 /* libpng.a */,
+				42049B7416ADBCC3005DD1F9 /* libogg.a */,
+				42049B7516ADBCC3005DD1F9 /* libvorbis.a */,
+				42049B7616ADBCC3005DD1F9 /* libvorbisenc.a */,
+				42049B7716ADBCC3005DD1F9 /* libvorbisfile.a */,
+				42049B5E16ADBBF5005DD1F9 /* libz.dylib */,
+			);
+			name = iOS;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -258,7 +301,7 @@
 		42C932B31491A0DB0098216A /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 0420;
+				LastUpgradeCheck = 0450;
 			};
 			buildConfigurationList = 42C932B61491A0DB0098216A /* Build configuration list for PBXProject "gameplay-template" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -295,6 +338,7 @@
 			files = (
 				5B61612614CCC24C0073B857 /* icon.png in Resources */,
 				5B61612714CCC24C0073B857 /* res in Resources */,
+				42049B7D16ADBCDB005DD1F9 /* [email protected] in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -404,22 +448,25 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				COMBINE_HIDPI_IMAGES = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
 					GAMEPLAY_PATH/gameplay/src,
-					"GAMEPLAY_PATH/external-deps/libpng/include",
 					"GAMEPLAY_PATH/external-deps/bullet/include",
-					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
+					"GAMEPLAY_PATH/external-deps/libpng/include",
+					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-macosx.plist";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/lua/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
+					"\"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug\"",
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
@@ -431,22 +478,25 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				COMBINE_HIDPI_IMAGES = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
 					GAMEPLAY_PATH/gameplay/src,
-					"GAMEPLAY_PATH/external-deps/libpng/include",
 					"GAMEPLAY_PATH/external-deps/bullet/include",
-					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
+					"GAMEPLAY_PATH/external-deps/libpng/include",
+					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-macosx.plist";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/lua/lib/macosx\"",
+					"\"GAMEPLAY_PATH/external-deps/libpng/lib/macosx\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/macosx\"",
+					"\"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug\"",
 				);
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
@@ -457,28 +507,30 @@
 		5B61612A14CCC24C0073B857 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-                ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
 					GAMEPLAY_PATH/gameplay/src,
-					"GAMEPLAY_PATH/external-deps/libpng/include",
 					"GAMEPLAY_PATH/external-deps/bullet/include",
-					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
+					"GAMEPLAY_PATH/external-deps/libpng/include",
+					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-ios.plist";
-                IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/lua/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
+					"\"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug-iphoneos\"",
 				);
 				SDKROOT = iphoneos;
-                TARGETED_DEVICE_FAMILY = "1,2";
+				TARGETED_DEVICE_FAMILY = "1,2";
 				USER_HEADER_SEARCH_PATHS = "";
 				WRAPPER_EXTENSION = app;
 			};
@@ -487,28 +539,30 @@
 		5B61612B14CCC24C0073B857 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-                ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				GCC_PRECOMPILE_PREFIX_HEADER = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_UNUSED_VARIABLE = NO;
 				HEADER_SEARCH_PATHS = (
 					GAMEPLAY_PATH/gameplay/src,
-					"GAMEPLAY_PATH/external-deps/libpng/include",
 					"GAMEPLAY_PATH/external-deps/bullet/include",
-					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 					"GAMEPLAY_PATH/external-deps/lua/include",
+					"GAMEPLAY_PATH/external-deps/libpng/include",
+					"GAMEPLAY_PATH/external-deps/oggvorbis/include",
 				);
 				INFOPLIST_FILE = "TEMPLATE_PROJECT-ios.plist";
-                IPHONEOS_DEPLOYMENT_TARGET = 5.1;
+				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
-					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/bullet/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/lua/lib/ios/$(CURRENT_ARCH)\"",
+					"\"GAMEPLAY_PATH/external-deps/libpng/lib/ios/$(CURRENT_ARCH)\"",
 					"\"GAMEPLAY_PATH/external-deps/oggvorbis/lib/ios/$(CURRENT_ARCH)\"",
+					"\"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug-iphoneos\"",
 				);
 				SDKROOT = iphoneos;
-                TARGETED_DEVICE_FAMILY = "1,2";
+				TARGETED_DEVICE_FAMILY = "1,2";
 				USER_HEADER_SEARCH_PATHS = "";
 				WRAPPER_EXTENSION = app;
 			};

+ 1 - 1
gameplay-template/res/colored.vert

@@ -4,7 +4,7 @@ attribute vec3 a_normal;                            // Vertex Normal (x, y, z)
 
 // Uniforms
 uniform mat4 u_worldViewProjectionMatrix;           // Matrix to transform a position to clip space.
-uniform mat4 u_inverseTransposeWorldViewMatrix;     // Matrix to transform a normal to view space.
+uniform mat4 u_inverseTransposeWorldViewMatrix;         // Matrix to transform a normal to view space.
 
 // Outputs
 varying vec3 v_normalVector;                        // Normal vector in view space.

+ 6 - 12
gameplay-template/template.bar-descriptor.xml

@@ -24,20 +24,14 @@
          <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
     <buildId>1</buildId>
 
-    <!-- A string value (such as "v1", "2.5", or "Alpha 1") that represents the version of the application, as it should be shown to users. Optional. -->
-    <!-- <versionLabel></versionLabel> -->
-
     <!-- Description, displayed in the BlackBerry Tablet OS application installer.
          May have multiple values for each language. See samples or xsd schema file. Optional. -->
     <description>TEMPLATE_DESCRIPTION</description>
-    
-    <!-- Copyright information. Optional. -->
-    <!-- <copyright></copyright> -->
 
-    <!--  Name of author which is used for signing. Must match the developer name of your development certificate. -->
+    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
     <author>TEMPLATE_AUTHOR</author>
 
-    <!--  Unique author ID assigned by signing authority. Required if using debug tokens. -->
+    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
     <!-- <authorId>gYAAgPkLP1tZlyYP1wiMaRFFNMw</authorId> -->
 
     <initialWindow>
@@ -47,7 +41,7 @@
         <transparent>false</transparent>
     </initialWindow>
 
-    <!--  The category where the application appears. Either core.games or core.media. -->
+    <!-- The category where the application appears. Either core.games or core.media. -->
     <category>core.games</category>
 
     <asset path="icon.png">icon.png</asset>
@@ -82,18 +76,18 @@
        <asset path="Simulator-Coverage/TEMPLATE_PROJECT" entry="true" type="Qnx/Elf">TEMPLATE_PROJECT</asset>
     </configuration>
 
-    <!--  The icon for the application, which should be 86x86. -->
+    <!-- The icon for the application, which should be 150x150. -->
     <icon>
         <image>icon.png</image>
     </icon>
 
-    <!--  The splash screen that will appear when your application is launching. Should be 1024x600. -->
+    <!-- The splash screen that will appear when your application is launching. Should be 1280x768. -->
     <!-- <splashscreen></splashscreen> -->
 
     <!-- Request permission to execute native code.  Required for native applications. -->
     <action system="true">run_native</action>
 
-    <!--  The permissions requested by your application. -->
+    <!-- The permissions requested by your application. -->
     <!--  <action>access_shared</action> -->
     <!--  <action>record_audio</action> -->
     <!--  <action>read_geolocation</action> -->

+ 1 - 1
gameplay.doxyfile

@@ -32,7 +32,7 @@ PROJECT_NAME           = gameplay
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 1.5.0
+PROJECT_NUMBER         = 1.6.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description 
 # for a project that appears at the top of each page and should give viewer 

+ 132 - 75
gameplay.sln

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay", "gameplay\gameplay.vcxproj", "{1032BA4B-57EB-4348-9E03-29DD63E80E4A}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay-tests", "gameplay-tests\gameplay-tests.vcxproj", "{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gameplay-tests", "gameplay-tests\gameplay-tests.vcxproj", "{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}"
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
@@ -33,12 +33,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample04-particles", "gamep
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample05-lua", "gameplay-samples\sample05-lua\sample05-lua.vcxproj", "{C6121A62-AA46-BA6D-A1CE-8000544456AA}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample05-lua", "gameplay-samples\sample05-lua\sample05-lua.vcxproj", "{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}"
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample06-racer", "gameplay-samples\sample06-racer\sample06-racer.vcxproj", "{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample06-racer", "gameplay-samples\sample06-racer\sample06-racer.vcxproj", "{82522888-E09A-ED48-AD7D-247237B37B3A}"
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
@@ -48,12 +48,15 @@ Global
 		Debug|BlackBerry = Debug|BlackBerry
 		Debug|BlackBerrySimulator = Debug|BlackBerrySimulator
 		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
 		DebugMem|BlackBerry = DebugMem|BlackBerry
 		DebugMem|BlackBerrySimulator = DebugMem|BlackBerrySimulator
 		DebugMem|Win32 = DebugMem|Win32
+		DebugMem|x64 = DebugMem|x64
 		Release|BlackBerry = Release|BlackBerry
 		Release|BlackBerrySimulator = Release|BlackBerrySimulator
 		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
@@ -64,6 +67,8 @@ Global
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|Win32.Build.0 = Debug|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|x64.ActiveCfg = Debug|x64
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|x64.Build.0 = Debug|x64
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
@@ -72,6 +77,8 @@ Global
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|x64.Build.0 = DebugMem|x64
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.Build.0 = Release|BlackBerry
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
@@ -80,30 +87,38 @@ Global
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.ActiveCfg = Release|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.Build.0 = Release|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.ActiveCfg = Debug|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.Build.0 = Debug|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.Build.0 = DebugMem|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.Build.0 = Release|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.ActiveCfg = Release|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.Build.0 = Release|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|x64.ActiveCfg = Release|x64
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|x64.Build.0 = Release|x64
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|Win32.Build.0 = Debug|Win32
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|x64.ActiveCfg = Debug|x64
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Debug|x64.Build.0 = Debug|x64
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.DebugMem|x64.Build.0 = DebugMem|x64
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|Win32.ActiveCfg = Release|Win32
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|Win32.Build.0 = Release|Win32
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|x64.ActiveCfg = Release|x64
+		{0F27C8C4-58B2-E367-8D1F-01B714FDBF1B}.Release|x64.Build.0 = Release|x64
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
@@ -112,6 +127,8 @@ Global
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|Win32.Build.0 = Debug|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|x64.ActiveCfg = Debug|x64
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|x64.Build.0 = Debug|x64
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
@@ -120,6 +137,8 @@ Global
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|x64.Build.0 = DebugMem|x64
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerry.Build.0 = Release|BlackBerry
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
@@ -128,6 +147,8 @@ Global
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|Win32.ActiveCfg = Release|Win32
 		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|Win32.Build.0 = Release|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|x64.ActiveCfg = Release|x64
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|x64.Build.0 = Release|x64
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
@@ -136,6 +157,8 @@ Global
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.Build.0 = Debug|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|x64.ActiveCfg = Debug|x64
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|x64.Build.0 = Debug|x64
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
@@ -144,6 +167,8 @@ Global
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|x64.Build.0 = DebugMem|x64
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.Build.0 = Release|BlackBerry
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
@@ -152,6 +177,8 @@ Global
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.ActiveCfg = Release|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.Build.0 = Release|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|x64.ActiveCfg = Release|x64
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|x64.Build.0 = Release|x64
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
@@ -160,6 +187,8 @@ Global
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.Build.0 = Debug|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|x64.ActiveCfg = Debug|x64
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|x64.Build.0 = Debug|x64
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
@@ -168,6 +197,8 @@ Global
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|x64.Build.0 = DebugMem|x64
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.Build.0 = Release|BlackBerry
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
@@ -176,6 +207,8 @@ Global
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.ActiveCfg = Release|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.Build.0 = Release|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|x64.ActiveCfg = Release|x64
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|x64.Build.0 = Release|x64
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
@@ -184,6 +217,8 @@ Global
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|Win32.ActiveCfg = Debug|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|Win32.Build.0 = Debug|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|x64.ActiveCfg = Debug|x64
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|x64.Build.0 = Debug|x64
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
@@ -192,6 +227,8 @@ Global
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|x64.Build.0 = DebugMem|x64
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.Build.0 = Release|BlackBerry
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
@@ -200,6 +237,8 @@ Global
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.ActiveCfg = Release|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.Build.0 = Release|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|x64.ActiveCfg = Release|x64
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|x64.Build.0 = Release|x64
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
@@ -208,6 +247,8 @@ Global
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|Win32.Build.0 = Debug|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|x64.ActiveCfg = Debug|x64
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|x64.Build.0 = Debug|x64
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
@@ -216,6 +257,8 @@ Global
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|x64.Build.0 = DebugMem|x64
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.Build.0 = Release|BlackBerry
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
@@ -224,54 +267,68 @@ Global
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|Win32.ActiveCfg = Release|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|Win32.Build.0 = Release|Win32
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|Win32.ActiveCfg = Debug|Win32
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|Win32.Build.0 = Debug|Win32
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.Build.0 = DebugMem|Win32
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.Build.0 = Release|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.ActiveCfg = Release|Win32
-		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.Build.0 = Release|Win32
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|Win32.ActiveCfg = Debug|Win32
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|Win32.Build.0 = Debug|Win32
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|Win32.Build.0 = DebugMem|Win32
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.Build.0 = Release|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|Win32.ActiveCfg = Release|Win32
-		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|Win32.Build.0 = Release|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|x64.ActiveCfg = Release|x64
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|x64.Build.0 = Release|x64
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|Win32.Build.0 = Debug|Win32
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|x64.ActiveCfg = Debug|x64
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Debug|x64.Build.0 = Debug|x64
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.DebugMem|x64.Build.0 = DebugMem|x64
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|Win32.ActiveCfg = Release|Win32
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|Win32.Build.0 = Release|Win32
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|x64.ActiveCfg = Release|x64
+		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|x64.Build.0 = Release|x64
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|Win32.Build.0 = Debug|Win32
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|x64.ActiveCfg = Debug|x64
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Debug|x64.Build.0 = Debug|x64
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|x64.ActiveCfg = DebugMem|x64
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.DebugMem|x64.Build.0 = DebugMem|x64
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|Win32.ActiveCfg = Release|Win32
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|Win32.Build.0 = Release|Win32
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|x64.ActiveCfg = Release|x64
+		{82522888-E09A-ED48-AD7D-247237B37B3A}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 23 - 15
gameplay/.cproject

@@ -20,9 +20,10 @@
 							<builder buildPath="${workspace_loc:/gameplay/Device-Debug}" id="org.eclipse.cdt.build.core.internal.builder.159190287" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="org.eclipse.cdt.build.core.internal.builder"/>
 							<tool id="com.qnx.qcc.tool.compiler.96907942" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
 								<option id="com.qnx.qcc.option.compile.debug.1765481355" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.security.311918799" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.security.311918799" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1481323494" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.2133604142" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/lua/include&quot;"/>
@@ -41,6 +42,7 @@
 							</tool>
 							<tool id="com.qnx.qcc.tool.assembler.1988140188" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler">
 								<option id="com.qnx.qcc.option.assembler.debug.1929307156" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.assembler.defines.1866459653" name="Defines (-D)" superClass="com.qnx.qcc.option.assembler.defines"/>
 								<inputType id="com.qnx.qcc.inputType.assembler.1944074393" superClass="com.qnx.qcc.inputType.assembler"/>
 							</tool>
 							<tool id="com.qnx.qcc.tool.linker.85592747" name="QCC Linker" superClass="com.qnx.qcc.tool.linker">
@@ -80,10 +82,11 @@
 							<targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1117051584" osList="all" superClass="com.qnx.qcc.targetPlatform"/>
 							<builder buildPath="${workspace_loc:/gameplay/Device-Release}" id="cdt.managedbuild.target.gnu.builder.base.1199322737" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
 							<tool id="com.qnx.qcc.tool.compiler.1345567866" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
-								<option id="com.qnx.qcc.option.compiler.optlevel.1056793982" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.2" valueType="enumerated"/>
-								<option id="com.qnx.qcc.option.compiler.security.324540233" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.optlevel.1056793982" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.1" valueType="enumerated"/>
+								<option id="com.qnx.qcc.option.compiler.security.324540233" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.398688299" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1670164593" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -95,7 +98,7 @@
 								<option id="com.qnx.qcc.option.compiler.ccoptions.1122311163" name="Compiler Options (-Wc,)" superClass="com.qnx.qcc.option.compiler.ccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-mfpu=neon"/>
 								</option>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.1770609643" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+								<option id="com.qnx.qcc.option.compiler.qccoptions.1770609643" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-Wno-psabi"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.1380846613" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -141,9 +144,10 @@
 							<tool id="com.qnx.qcc.tool.compiler.1281156842" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
 								<option id="com.qnx.qcc.option.compile.debug.626405189" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.profile2.1207899085" name="Build for Profiling (Function Instrumentation) (-finstrument-functions)" superClass="com.qnx.qcc.option.compiler.profile2" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.security.1649809766" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.security.1649809766" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.276653249" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1503059677" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -155,7 +159,7 @@
 								<option id="com.qnx.qcc.option.compiler.ccoptions.1956270067" name="Compiler Options (-Wc,)" superClass="com.qnx.qcc.option.compiler.ccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-mfpu=neon"/>
 								</option>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.1366354884" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+								<option id="com.qnx.qcc.option.compiler.qccoptions.1366354884" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-Wno-psabi"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.81809638" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -204,9 +208,10 @@
 							<tool id="com.qnx.qcc.tool.compiler.306557636" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
 								<option id="com.qnx.qcc.option.compile.debug.168813234" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.coverage.1032644527" name="Build for Code Coverage (-Wc,-ftest-coverage -Wc,-fprofile-arcs)" superClass="com.qnx.qcc.option.compiler.coverage" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.security.1227516972" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.security.1227516972" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.374283024" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1769677874" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -218,7 +223,7 @@
 								<option id="com.qnx.qcc.option.compiler.ccoptions.47607907" name="Compiler Options (-Wc,)" superClass="com.qnx.qcc.option.compiler.ccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-mfpu=neon"/>
 								</option>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.146547607" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+								<option id="com.qnx.qcc.option.compiler.qccoptions.146547607" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-Wno-psabi"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.2007171407" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -265,9 +270,10 @@
 							<builder buildPath="${workspace_loc:/gameplay/Simulator}" id="cdt.managedbuild.target.gnu.builder.base.10075032" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
 							<tool id="com.qnx.qcc.tool.compiler.1004416224" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
 								<option id="com.qnx.qcc.option.compile.debug.1122485646" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.security.1671403331" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.security.1671403331" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1863269886" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.847642559" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -277,7 +283,7 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.ccoptions.1432778691" name="Compiler Options (-Wc,)" superClass="com.qnx.qcc.option.compiler.ccoptions"/>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.245518255" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+								<option id="com.qnx.qcc.option.compiler.qccoptions.245518255" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-Wno-psabi"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.1038720310" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -324,9 +330,10 @@
 							<tool id="com.qnx.qcc.tool.compiler.417488704" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
 								<option id="com.qnx.qcc.option.compile.debug.1290366598" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.profile2.216911941" name="Build for Profiling (Function Instrumentation) (-finstrument-functions)" superClass="com.qnx.qcc.option.compiler.profile2" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.security.1329750381" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.security.1329750381" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1679396285" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.513622172" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -336,7 +343,7 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.ccoptions.663337616" name="Compiler Options (-Wc,)" superClass="com.qnx.qcc.option.compiler.ccoptions"/>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.288926109" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+								<option id="com.qnx.qcc.option.compiler.qccoptions.288926109" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-Wno-psabi"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.1961855927" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -384,9 +391,10 @@
 							<tool id="com.qnx.qcc.tool.compiler.563072865" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler">
 								<option id="com.qnx.qcc.option.compile.debug.1789973550" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.coverage.1289221781" name="Build for Code Coverage (-Wc,-ftest-coverage -Wc,-fprofile-arcs)" superClass="com.qnx.qcc.option.compiler.coverage" value="true" valueType="boolean"/>
-								<option id="com.qnx.qcc.option.compiler.security.1296061040" name="Enhanced Security (-fstack-protector-all)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/>
+								<option id="com.qnx.qcc.option.compiler.security.1296061040" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1925901823" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
+									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1685994750" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -396,7 +404,7 @@
 									<listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.ccoptions.346770186" name="Compiler Options (-Wc,)" superClass="com.qnx.qcc.option.compiler.ccoptions"/>
-								<option id="com.qnx.qcc.option.compiler.qccoptions.1085566269" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
+								<option id="com.qnx.qcc.option.compiler.qccoptions.1085566269" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList">
 									<listOptionValue builtIn="false" value="-Wno-psabi"/>
 								</option>
 								<inputType id="com.qnx.qcc.inputType.compiler.1658185881" superClass="com.qnx.qcc.inputType.compiler"/>
@@ -458,4 +466,4 @@
 	</storageModule>
 	<storageModule moduleId="com.qnx.tools.ide.qde.core.QNXProjectProperties"/>
 	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-</cproject>
+</cproject>

+ 31 - 15
gameplay/CMakeLists.txt

@@ -77,7 +77,9 @@ set(GAMEPLAY_SRC
     src/gameplay-main-blackberry.cpp
     src/gameplay-main-linux.cpp
     src/gameplay-main-windows.cpp
-	src/Gesture.h
+    src/Gesture.h
+    src/HeightField.cpp
+    src/HeightField.h
     src/Image.cpp
     src/Image.h
     src/Image.inl
@@ -146,10 +148,10 @@ set(GAMEPLAY_SRC
     src/PhysicsSocketConstraint.h
     src/PhysicsSpringConstraint.cpp
     src/PhysicsSpringConstraint.h
-	src/PhysicsVehicle.cpp
-	src/PhysicsVehicle.h
-	src/PhysicsVehicleWheel.cpp
-	src/PhysicsVehicle.h
+    src/PhysicsVehicle.cpp
+    src/PhysicsVehicle.h
+    src/PhysicsVehicleWheel.cpp
+    src/PhysicsVehicle.h
     src/Plane.cpp
     src/Plane.h
     src/Plane.inl
@@ -193,6 +195,10 @@ set(GAMEPLAY_SRC
     src/SpriteBatch.h
     src/Technique.cpp
     src/Technique.h
+    src/Terrain.cpp
+    src/Terrain.h
+    src/TerrainPatch.cpp
+    src/TerrainPatch.h
     src/TextBox.cpp
     src/TextBox.h
     src/Texture.cpp
@@ -327,18 +333,20 @@ set(GAMEPLAY_LUA
     src/lua/lua_GameClearFlags.h
     src/lua/lua_Gamepad.cpp
     src/lua/lua_Gamepad.h
-    src/lua/lua_GamepadButtonState.cpp
-    src/lua/lua_GamepadButtonState.h
+    src/lua/lua_GamepadButtonMapping.cpp
+    src/lua/lua_GamepadButtonMapping.h
     src/lua/lua_GamepadGamepadEvent.cpp
     src/lua/lua_GamepadGamepadEvent.h
     src/lua/lua_GameState.cpp
     src/lua/lua_GameState.h
-	src/lua/lua_Gesture.cpp
-	src/lua/lua_Gesture.h
-	src/lua/lua_GestureGestureEvent.cpp
-	src/lua/lua_GestureGestureEvent.h
+    src/lua/lua_Gesture.cpp
+    src/lua/lua_Gesture.h
+    src/lua/lua_GestureGestureEvent.cpp
+    src/lua/lua_GestureGestureEvent.h
     src/lua/lua_Global.cpp
     src/lua/lua_Global.h
+    src/lua/lua_HeightField.cpp
+    src/lua/lua_HeightField.h
     src/lua/lua_Image.cpp
     src/lua/lua_Image.h
     src/lua/lua_ImageFormat.cpp
@@ -451,10 +459,10 @@ set(GAMEPLAY_LUA
     src/lua/lua_PhysicsSocketConstraint.h
     src/lua/lua_PhysicsSpringConstraint.cpp
     src/lua/lua_PhysicsSpringConstraint.h
-	src/lua/lua_PhysicsVehicle.cpp
-	src/lua/lua_PhysicsVehicle.h
-	src/lua/lua_PhysicsVehicleWheel.cpp
-	src/lua/lua_PhysicsVehicleWheel.h
+    src/lua/lua_PhysicsVehicle.cpp
+    src/lua/lua_PhysicsVehicle.h
+    src/lua/lua_PhysicsVehicleWheel.cpp
+    src/lua/lua_PhysicsVehicleWheel.h
     src/lua/lua_Plane.cpp
     src/lua/lua_Plane.h
     src/lua/lua_Platform.cpp
@@ -479,6 +487,8 @@ set(GAMEPLAY_LUA
     src/lua/lua_RenderStateAutoBinding.h
     src/lua/lua_RenderStateBlend.cpp
     src/lua/lua_RenderStateBlend.h
+    src/lua/lua_RenderStateDepthFunction.cpp
+    src/lua/lua_RenderStateDepthFunction.h
     src/lua/lua_RenderStateStateBlock.cpp
     src/lua/lua_RenderStateStateBlock.h
     src/lua/lua_RenderTarget.cpp
@@ -499,6 +509,10 @@ set(GAMEPLAY_LUA
     src/lua/lua_SpriteBatch.h
     src/lua/lua_Technique.cpp
     src/lua/lua_Technique.h
+    src/lua/lua_Terrain.cpp
+    src/lua/lua_Terrain.h
+    src/lua/lua_TerrainFlags.cpp
+    src/lua/lua_TerrainFlags.h
     src/lua/lua_TextBox.cpp
     src/lua/lua_TextBox.h
     src/lua/lua_Texture.cpp
@@ -567,6 +581,8 @@ set(GAMEPLAY_RES_SHADERS
     res/shaders/textured-unlit.vert
     res/shaders/textured.frag
     res/shaders/textured.vert
+    res/shaders/terrain.frag
+    res/shaders/terrain.vert
 )
 
 set(GAMEPLAY_RES_SHADERS_LIB

+ 8 - 1
gameplay/android/jni/Android.mk

@@ -52,6 +52,7 @@ LOCAL_SRC_FILES := \
     Frustum.cpp \
     Game.cpp \
     Gamepad.cpp \
+    HeightField.cpp \
     Image.cpp \
     Joint.cpp \
     Joystick.cpp \
@@ -103,6 +104,8 @@ LOCAL_SRC_FILES := \
     Slider.cpp \
     SpriteBatch.cpp \
     Technique.cpp \
+    Terrain.cpp \
+    TerrainPatch.cpp \
     TextBox.cpp \
     Texture.cpp \
     Theme.cpp \
@@ -167,12 +170,13 @@ LOCAL_SRC_FILES := \
     lua/lua_Game.cpp \
     lua/lua_GameClearFlags.cpp \
     lua/lua_Gamepad.cpp \
-    lua/lua_GamepadButtonState.cpp \
+    lua/lua_GamepadButtonMapping.cpp \
     lua/lua_GamepadGamepadEvent.cpp \
     lua/lua_GameState.cpp \
     lua/lua_Gesture.cpp \
     lua/lua_GestureGestureEvent.cpp \
     lua/lua_Global.cpp \
+    lua/lua_HeightField.cpp \
     lua/lua_Image.cpp \
     lua/lua_ImageFormat.cpp \
     lua/lua_Joint.cpp \
@@ -243,6 +247,7 @@ LOCAL_SRC_FILES := \
     lua/lua_RenderState.cpp \
     lua/lua_RenderStateAutoBinding.cpp \
     lua/lua_RenderStateBlend.cpp \
+    lua/lua_RenderStateDepthFunction.cpp \
     lua/lua_RenderStateStateBlock.cpp \
     lua/lua_RenderTarget.cpp \
     lua/lua_Scene.cpp \
@@ -253,6 +258,8 @@ LOCAL_SRC_FILES := \
     lua/lua_Slider.cpp \
     lua/lua_SpriteBatch.cpp \
     lua/lua_Technique.cpp \
+    lua/lua_Terrain.cpp \
+    lua/lua_TerrainFlags.cpp \
     lua/lua_TextBox.cpp \
     lua/lua_Texture.cpp \
     lua/lua_TextureFilter.cpp \

+ 0 - 591
gameplay/gameplay.cbp

@@ -1,591 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<CodeBlocks_project_file>
-	<FileVersion major="1" minor="6" />
-	<Project>
-		<Option title="gameplay" />
-		<Option pch_mode="2" />
-		<Option compiler="gcc" />
-		<Build>
-			<Target title="Debug">
-				<Option output="Debug/libgameplay" prefix_auto="1" extension_auto="1" />
-				<Option working_dir="" />
-				<Option object_output="Debug/" />
-				<Option type="2" />
-				<Option compiler="gcc" />
-				<Option createDefFile="1" />
-				<Compiler>
-					<Add option="-g" />
-				</Compiler>
-			</Target>
-			<Target title="Release">
-				<Option output="Release/libgameplay" prefix_auto="1" extension_auto="1" />
-				<Option working_dir="" />
-				<Option object_output="Release/" />
-				<Option type="2" />
-				<Option compiler="gcc" />
-				<Option createDefFile="1" />
-				<Compiler>
-					<Add option="-O2" />
-				</Compiler>
-				<Linker>
-					<Add option="-s" />
-				</Linker>
-			</Target>
-		</Build>
-		<Compiler>
-			<Add option="-pedantic" />
-			<Add option="-Wswitch" />
-			<Add option="-Wunused-variable" />
-			<Add directory="../external-deps/zlib/include" />
-			<Add directory="../external-deps/lua/include" />
-			<Add directory="../external-deps/libpng/include" />
-			<Add directory="../external-deps/bullet/include" />
-			<Add directory="../external-deps/oggvorbis/include" />
-			<Add directory="../gameplay/src" />
-		</Compiler>
-		<Linker>
-			<Add directory="../external-deps/lua/lib/linux" />
-			<Add directory="../external-deps/libpng/lib/linux" />
-			<Add directory="../external-deps/bullet/lib/linux" />
-			<Add directory="../external-deps/oggvorbis/lib/linux" />
-		</Linker>
-		<Unit filename="src/AIAgent.cpp" />
-		<Unit filename="src/AIAgent.h" />
-		<Unit filename="src/AIController.cpp" />
-		<Unit filename="src/AIController.h" />
-		<Unit filename="src/AIMessage.cpp" />
-		<Unit filename="src/AIMessage.h" />
-		<Unit filename="src/AIState.cpp" />
-		<Unit filename="src/AIState.h" />
-		<Unit filename="src/AIStateMachine.cpp" />
-		<Unit filename="src/AIStateMachine.h" />
-		<Unit filename="src/AbsoluteLayout.cpp" />
-		<Unit filename="src/AbsoluteLayout.h" />
-		<Unit filename="src/Animation.cpp" />
-		<Unit filename="src/Animation.h" />
-		<Unit filename="src/AnimationClip.cpp" />
-		<Unit filename="src/AnimationClip.h" />
-		<Unit filename="src/AnimationController.cpp" />
-		<Unit filename="src/AnimationController.h" />
-		<Unit filename="src/AnimationTarget.cpp" />
-		<Unit filename="src/AnimationTarget.h" />
-		<Unit filename="src/AnimationValue.cpp" />
-		<Unit filename="src/AnimationValue.h" />
-		<Unit filename="src/AudioBuffer.cpp" />
-		<Unit filename="src/AudioBuffer.h" />
-		<Unit filename="src/AudioController.cpp" />
-		<Unit filename="src/AudioController.h" />
-		<Unit filename="src/AudioListener.cpp" />
-		<Unit filename="src/AudioListener.h" />
-		<Unit filename="src/AudioSource.cpp" />
-		<Unit filename="src/AudioSource.h" />
-		<Unit filename="src/Base.h" />
-		<Unit filename="src/BoundingBox.cpp" />
-		<Unit filename="src/BoundingBox.h" />
-		<Unit filename="src/BoundingSphere.cpp" />
-		<Unit filename="src/BoundingSphere.h" />
-		<Unit filename="src/Bundle.cpp" />
-		<Unit filename="src/Bundle.h" />
-		<Unit filename="src/Button.cpp" />
-		<Unit filename="src/Button.h" />
-		<Unit filename="src/Camera.cpp" />
-		<Unit filename="src/Camera.h" />
-		<Unit filename="src/CheckBox.cpp" />
-		<Unit filename="src/CheckBox.h" />
-		<Unit filename="src/Container.cpp" />
-		<Unit filename="src/Container.h" />
-		<Unit filename="src/Control.cpp" />
-		<Unit filename="src/Control.h" />
-		<Unit filename="src/Curve.cpp" />
-		<Unit filename="src/Curve.h" />
-		<Unit filename="src/DebugNew.cpp" />
-		<Unit filename="src/DebugNew.h" />
-		<Unit filename="src/DepthStencilTarget.cpp" />
-		<Unit filename="src/DepthStencilTarget.h" />
-		<Unit filename="src/Effect.cpp" />
-		<Unit filename="src/Effect.h" />
-		<Unit filename="src/FileSystem.cpp" />
-		<Unit filename="src/FileSystem.h" />
-		<Unit filename="src/FlowLayout.cpp" />
-		<Unit filename="src/FlowLayout.h" />
-		<Unit filename="src/Font.cpp" />
-		<Unit filename="src/Font.h" />
-		<Unit filename="src/Form.cpp" />
-		<Unit filename="src/Form.h" />
-		<Unit filename="src/FrameBuffer.cpp" />
-		<Unit filename="src/FrameBuffer.h" />
-		<Unit filename="src/Frustum.cpp" />
-		<Unit filename="src/Frustum.h" />
-		<Unit filename="src/Game.cpp" />
-		<Unit filename="src/Game.h" />
-		<Unit filename="src/Gamepad.cpp" />
-		<Unit filename="src/Gamepad.h" />
-		<Unit filename="src/gameplay.h" />
-        <Unit filename="src/gameplay-main-android.cpp" />
-		<Unit filename="src/gameplay-main-blackberry.cpp" />
-		<Unit filename="src/gameplay-main-linux.cpp" />
-		<Unit filename="src/gameplay-main-windows.cpp" />
-		<Unit filename="src/Gesture.h" />
-		<Unit filename="src/Image.cpp" />
-		<Unit filename="src/Image.h" />
-		<Unit filename="src/Joint.cpp" />
-		<Unit filename="src/Joint.h" />
-		<Unit filename="src/Joystick.cpp" />
-		<Unit filename="src/Joystick.h" />
-		<Unit filename="src/Keyboard.h" />
-		<Unit filename="src/Label.cpp" />
-		<Unit filename="src/Label.h" />
-		<Unit filename="src/Layout.cpp" />
-		<Unit filename="src/Layout.h" />
-		<Unit filename="src/Light.cpp" />
-		<Unit filename="src/Light.h" />
-		<Unit filename="src/Logger.cpp" />
-		<Unit filename="src/Logger.h" />
-		<Unit filename="src/Material.cpp" />
-		<Unit filename="src/Material.h" />
-		<Unit filename="src/MaterialParameter.cpp" />
-		<Unit filename="src/MaterialParameter.h" />
-		<Unit filename="src/MathUtil.cpp" />
-		<Unit filename="src/MathUtil.h" />
-		<Unit filename="src/Matrix.cpp" />
-		<Unit filename="src/Matrix.h" />
-		<Unit filename="src/Mesh.cpp" />
-		<Unit filename="src/Mesh.h" />
-		<Unit filename="src/MeshBatch.cpp" />
-		<Unit filename="src/MeshBatch.h" />
-		<Unit filename="src/MeshPart.cpp" />
-		<Unit filename="src/MeshPart.h" />
-		<Unit filename="src/MeshSkin.cpp" />
-		<Unit filename="src/MeshSkin.h" />
-		<Unit filename="src/Model.cpp" />
-		<Unit filename="src/Model.h" />
-		<Unit filename="src/Mouse.h" />
-		<Unit filename="src/Node.cpp" />
-		<Unit filename="src/Node.h" />
-		<Unit filename="src/ParticleEmitter.cpp" />
-		<Unit filename="src/ParticleEmitter.h" />
-		<Unit filename="src/Pass.cpp" />
-		<Unit filename="src/Pass.h" />
-		<Unit filename="src/PhysicsCharacter.cpp" />
-		<Unit filename="src/PhysicsCharacter.h" />
-		<Unit filename="src/PhysicsCollisionObject.cpp" />
-		<Unit filename="src/PhysicsCollisionObject.h" />
-		<Unit filename="src/PhysicsCollisionShape.cpp" />
-		<Unit filename="src/PhysicsCollisionShape.h" />
-		<Unit filename="src/PhysicsConstraint.cpp" />
-		<Unit filename="src/PhysicsConstraint.h" />
-		<Unit filename="src/PhysicsController.cpp" />
-		<Unit filename="src/PhysicsController.h" />
-		<Unit filename="src/PhysicsFixedConstraint.cpp" />
-		<Unit filename="src/PhysicsFixedConstraint.h" />
-		<Unit filename="src/PhysicsGenericConstraint.cpp" />
-		<Unit filename="src/PhysicsGenericConstraint.h" />
-		<Unit filename="src/PhysicsGhostObject.cpp" />
-		<Unit filename="src/PhysicsGhostObject.h" />
-		<Unit filename="src/PhysicsHingeConstraint.cpp" />
-		<Unit filename="src/PhysicsHingeConstraint.h" />
-		<Unit filename="src/PhysicsRigidBody.cpp" />
-		<Unit filename="src/PhysicsRigidBody.h" />
-		<Unit filename="src/PhysicsSocketConstraint.cpp" />
-		<Unit filename="src/PhysicsSocketConstraint.h" />
-		<Unit filename="src/PhysicsSpringConstraint.cpp" />
-		<Unit filename="src/PhysicsSpringConstraint.h" />
-		<Unit filename="src/PhysicsVehicle.cpp" />
-		<Unit filename="src/PhysicsVehicle.h" />
-		<Unit filename="src/PhysicsVehicleWheel.cpp" />
-		<Unit filename="src/PhysicsVehicleWheel.h" />
-		<Unit filename="src/Plane.cpp" />
-		<Unit filename="src/Plane.h" />
-		<Unit filename="src/Platform.h" />
-		<Unit filename="src/PlatformAndroid.cpp" />
-		<Unit filename="src/PlatformBlackBerry.cpp" />
-		<Unit filename="src/PlatformLinux.cpp" />
-		<Unit filename="src/PlatformWindows.cpp" />
-		<Unit filename="src/Properties.cpp" />
-		<Unit filename="src/Properties.h" />
-		<Unit filename="src/Quaternion.cpp" />
-		<Unit filename="src/Quaternion.h" />
-		<Unit filename="src/RadioButton.cpp" />
-		<Unit filename="src/RadioButton.h" />
-		<Unit filename="src/Ray.cpp" />
-		<Unit filename="src/Ray.h" />
-		<Unit filename="src/Rectangle.cpp" />
-		<Unit filename="src/Rectangle.h" />
-		<Unit filename="src/Ref.cpp" />
-		<Unit filename="src/Ref.h" />
-		<Unit filename="src/RenderState.cpp" />
-		<Unit filename="src/RenderState.h" />
-		<Unit filename="src/RenderTarget.cpp" />
-		<Unit filename="src/RenderTarget.h" />
-		<Unit filename="src/Scene.cpp" />
-		<Unit filename="src/Scene.h" />
-		<Unit filename="src/SceneLoader.cpp" />
-		<Unit filename="src/SceneLoader.h" />
-		<Unit filename="src/ScreenDisplayer.cpp" />
-		<Unit filename="src/ScreenDisplayer.h" />
-		<Unit filename="src/ScriptController.cpp" />
-		<Unit filename="src/ScriptController.h" />
-		<Unit filename="src/ScriptTarget.cpp" />
-		<Unit filename="src/ScriptTarget.h" />
-		<Unit filename="src/Slider.cpp" />
-		<Unit filename="src/Slider.h" />
-		<Unit filename="src/SpriteBatch.cpp" />
-		<Unit filename="src/SpriteBatch.h" />
-		<Unit filename="src/Technique.cpp" />
-		<Unit filename="src/Technique.h" />
-		<Unit filename="src/TextBox.cpp" />
-		<Unit filename="src/TextBox.h" />
-		<Unit filename="src/Texture.cpp" />
-		<Unit filename="src/Texture.h" />
-		<Unit filename="src/Theme.cpp" />
-		<Unit filename="src/Theme.h" />
-		<Unit filename="src/ThemeStyle.cpp" />
-		<Unit filename="src/ThemeStyle.h" />
-		<Unit filename="src/TimeListener.h" />
-		<Unit filename="src/Touch.h" />
-		<Unit filename="src/Transform.cpp" />
-		<Unit filename="src/Transform.h" />
-		<Unit filename="src/Vector2.cpp" />
-		<Unit filename="src/Vector2.h" />
-		<Unit filename="src/Vector3.cpp" />
-		<Unit filename="src/Vector3.h" />
-		<Unit filename="src/Vector4.cpp" />
-		<Unit filename="src/Vector4.h" />
-		<Unit filename="src/VertexAttributeBinding.cpp" />
-		<Unit filename="src/VertexAttributeBinding.h" />
-		<Unit filename="src/VertexFormat.cpp" />
-		<Unit filename="src/VertexFormat.h" />
-		<Unit filename="src/VerticalLayout.cpp" />
-		<Unit filename="src/VerticalLayout.h" />
-		<Unit filename="src/lua/lua_AIAgent.cpp" />
-		<Unit filename="src/lua/lua_AIAgent.h" />
-		<Unit filename="src/lua/lua_AIAgentListener.cpp" />
-		<Unit filename="src/lua/lua_AIAgentListener.h" />
-		<Unit filename="src/lua/lua_AIController.cpp" />
-		<Unit filename="src/lua/lua_AIController.h" />
-		<Unit filename="src/lua/lua_AIMessage.cpp" />
-		<Unit filename="src/lua/lua_AIMessage.h" />
-		<Unit filename="src/lua/lua_AIMessageParameterType.cpp" />
-		<Unit filename="src/lua/lua_AIMessageParameterType.h" />
-		<Unit filename="src/lua/lua_AIState.cpp" />
-		<Unit filename="src/lua/lua_AIState.h" />
-		<Unit filename="src/lua/lua_AIStateListener.cpp" />
-		<Unit filename="src/lua/lua_AIStateListener.h" />
-		<Unit filename="src/lua/lua_AIStateMachine.cpp" />
-		<Unit filename="src/lua/lua_AIStateMachine.h" />
-		<Unit filename="src/lua/lua_AbsoluteLayout.cpp" />
-		<Unit filename="src/lua/lua_AbsoluteLayout.h" />
-		<Unit filename="src/lua/lua_Animation.cpp" />
-		<Unit filename="src/lua/lua_Animation.h" />
-		<Unit filename="src/lua/lua_AnimationClip.cpp" />
-		<Unit filename="src/lua/lua_AnimationClip.h" />
-		<Unit filename="src/lua/lua_AnimationClipListener.cpp" />
-		<Unit filename="src/lua/lua_AnimationClipListener.h" />
-		<Unit filename="src/lua/lua_AnimationClipListenerEventType.cpp" />
-		<Unit filename="src/lua/lua_AnimationClipListenerEventType.h" />
-		<Unit filename="src/lua/lua_AnimationController.cpp" />
-		<Unit filename="src/lua/lua_AnimationController.h" />
-		<Unit filename="src/lua/lua_AnimationTarget.cpp" />
-		<Unit filename="src/lua/lua_AnimationTarget.h" />
-		<Unit filename="src/lua/lua_AnimationValue.cpp" />
-		<Unit filename="src/lua/lua_AnimationValue.h" />
-		<Unit filename="src/lua/lua_AudioBuffer.cpp" />
-		<Unit filename="src/lua/lua_AudioBuffer.h" />
-		<Unit filename="src/lua/lua_AudioController.cpp" />
-		<Unit filename="src/lua/lua_AudioController.h" />
-		<Unit filename="src/lua/lua_AudioListener.cpp" />
-		<Unit filename="src/lua/lua_AudioListener.h" />
-		<Unit filename="src/lua/lua_AudioSource.cpp" />
-		<Unit filename="src/lua/lua_AudioSource.h" />
-		<Unit filename="src/lua/lua_AudioSourceState.cpp" />
-		<Unit filename="src/lua/lua_AudioSourceState.h" />
-		<Unit filename="src/lua/lua_BoundingBox.cpp" />
-		<Unit filename="src/lua/lua_BoundingBox.h" />
-		<Unit filename="src/lua/lua_BoundingSphere.cpp" />
-		<Unit filename="src/lua/lua_BoundingSphere.h" />
-		<Unit filename="src/lua/lua_Bundle.cpp" />
-		<Unit filename="src/lua/lua_Bundle.h" />
-		<Unit filename="src/lua/lua_Button.cpp" />
-		<Unit filename="src/lua/lua_Button.h" />
-		<Unit filename="src/lua/lua_Camera.cpp" />
-		<Unit filename="src/lua/lua_Camera.h" />
-		<Unit filename="src/lua/lua_CameraType.cpp" />
-		<Unit filename="src/lua/lua_CameraType.h" />
-		<Unit filename="src/lua/lua_CheckBox.cpp" />
-		<Unit filename="src/lua/lua_CheckBox.h" />
-		<Unit filename="src/lua/lua_Container.cpp" />
-		<Unit filename="src/lua/lua_Container.h" />
-		<Unit filename="src/lua/lua_ContainerScroll.cpp" />
-		<Unit filename="src/lua/lua_ContainerScroll.h" />
-		<Unit filename="src/lua/lua_Control.cpp" />
-		<Unit filename="src/lua/lua_Control.h" />
-		<Unit filename="src/lua/lua_ControlAlignment.cpp" />
-		<Unit filename="src/lua/lua_ControlAlignment.h" />
-		<Unit filename="src/lua/lua_ControlListener.cpp" />
-		<Unit filename="src/lua/lua_ControlListener.h" />
-		<Unit filename="src/lua/lua_ControlListenerEventType.cpp" />
-		<Unit filename="src/lua/lua_ControlListenerEventType.h" />
-		<Unit filename="src/lua/lua_ControlState.cpp" />
-		<Unit filename="src/lua/lua_ControlState.h" />
-		<Unit filename="src/lua/lua_Curve.cpp" />
-		<Unit filename="src/lua/lua_Curve.h" />
-		<Unit filename="src/lua/lua_CurveInterpolationType.cpp" />
-		<Unit filename="src/lua/lua_CurveInterpolationType.h" />
-		<Unit filename="src/lua/lua_DepthStencilTarget.cpp" />
-		<Unit filename="src/lua/lua_DepthStencilTarget.h" />
-		<Unit filename="src/lua/lua_DepthStencilTargetFormat.cpp" />
-		<Unit filename="src/lua/lua_DepthStencilTargetFormat.h" />
-		<Unit filename="src/lua/lua_Effect.cpp" />
-		<Unit filename="src/lua/lua_Effect.h" />
-		<Unit filename="src/lua/lua_FileSystem.cpp" />
-		<Unit filename="src/lua/lua_FileSystem.h" />
-		<Unit filename="src/lua/lua_FlowLayout.cpp" />
-		<Unit filename="src/lua/lua_FlowLayout.h" />
-		<Unit filename="src/lua/lua_Font.cpp" />
-		<Unit filename="src/lua/lua_Font.h" />
-		<Unit filename="src/lua/lua_FontJustify.cpp" />
-		<Unit filename="src/lua/lua_FontJustify.h" />
-		<Unit filename="src/lua/lua_FontStyle.cpp" />
-		<Unit filename="src/lua/lua_FontStyle.h" />
-		<Unit filename="src/lua/lua_FontText.cpp" />
-		<Unit filename="src/lua/lua_FontText.h" />
-		<Unit filename="src/lua/lua_Form.cpp" />
-		<Unit filename="src/lua/lua_Form.h" />
-		<Unit filename="src/lua/lua_FrameBuffer.cpp" />
-		<Unit filename="src/lua/lua_FrameBuffer.h" />
-		<Unit filename="src/lua/lua_Frustum.cpp" />
-		<Unit filename="src/lua/lua_Frustum.h" />
-		<Unit filename="src/lua/lua_Game.cpp" />
-		<Unit filename="src/lua/lua_Game.h" />
-		<Unit filename="src/lua/lua_GameClearFlags.cpp" />
-		<Unit filename="src/lua/lua_GameClearFlags.h" />
-		<Unit filename="src/lua/lua_GameState.cpp" />
-		<Unit filename="src/lua/lua_GameState.h" />
-		<Unit filename="src/lua/lua_Gamepad.cpp" />
-		<Unit filename="src/lua/lua_Gamepad.h" />
-		<Unit filename="src/lua/lua_GamepadButtonState.cpp" />
-		<Unit filename="src/lua/lua_GamepadButtonState.h" />
-		<Unit filename="src/lua/lua_GamepadGamepadEvent.cpp" />
-		<Unit filename="src/lua/lua_GamepadGamepadEvent.h" />
-		<Unit filename="src/lua/lua_Gesture.cpp" />
-		<Unit filename="src/lua/lua_Gesture.h" />
-		<Unit filename="src/lua/lua_GestureGestureEvent.cpp" />
-		<Unit filename="src/lua/lua_GestureGestureEvent.h" />
-		<Unit filename="src/lua/lua_Global.cpp" />
-		<Unit filename="src/lua/lua_Global.h" />
-		<Unit filename="src/lua/lua_Image.cpp" />
-		<Unit filename="src/lua/lua_Image.h" />
-		<Unit filename="src/lua/lua_ImageFormat.cpp" />
-		<Unit filename="src/lua/lua_ImageFormat.h" />
-		<Unit filename="src/lua/lua_Joint.cpp" />
-		<Unit filename="src/lua/lua_Joint.h" />
-		<Unit filename="src/lua/lua_Joystick.cpp" />
-		<Unit filename="src/lua/lua_Joystick.h" />
-		<Unit filename="src/lua/lua_Keyboard.cpp" />
-		<Unit filename="src/lua/lua_Keyboard.h" />
-		<Unit filename="src/lua/lua_KeyboardKey.cpp" />
-		<Unit filename="src/lua/lua_KeyboardKey.h" />
-		<Unit filename="src/lua/lua_KeyboardKeyEvent.cpp" />
-		<Unit filename="src/lua/lua_KeyboardKeyEvent.h" />
-		<Unit filename="src/lua/lua_Label.cpp" />
-		<Unit filename="src/lua/lua_Label.h" />
-		<Unit filename="src/lua/lua_Layout.cpp" />
-		<Unit filename="src/lua/lua_Layout.h" />
-		<Unit filename="src/lua/lua_LayoutType.cpp" />
-		<Unit filename="src/lua/lua_LayoutType.h" />
-		<Unit filename="src/lua/lua_Light.cpp" />
-		<Unit filename="src/lua/lua_Light.h" />
-		<Unit filename="src/lua/lua_LightType.cpp" />
-		<Unit filename="src/lua/lua_LightType.h" />
-		<Unit filename="src/lua/lua_Logger.cpp" />
-		<Unit filename="src/lua/lua_Logger.h" />
-		<Unit filename="src/lua/lua_LoggerLevel.cpp" />
-		<Unit filename="src/lua/lua_LoggerLevel.h" />
-		<Unit filename="src/lua/lua_Material.cpp" />
-		<Unit filename="src/lua/lua_Material.h" />
-		<Unit filename="src/lua/lua_MaterialParameter.cpp" />
-		<Unit filename="src/lua/lua_MaterialParameter.h" />
-		<Unit filename="src/lua/lua_MathUtil.cpp" />
-		<Unit filename="src/lua/lua_MathUtil.h" />
-		<Unit filename="src/lua/lua_Matrix.cpp" />
-		<Unit filename="src/lua/lua_Matrix.h" />
-		<Unit filename="src/lua/lua_Mesh.cpp" />
-		<Unit filename="src/lua/lua_Mesh.h" />
-		<Unit filename="src/lua/lua_MeshBatch.cpp" />
-		<Unit filename="src/lua/lua_MeshBatch.h" />
-		<Unit filename="src/lua/lua_MeshIndexFormat.cpp" />
-		<Unit filename="src/lua/lua_MeshIndexFormat.h" />
-		<Unit filename="src/lua/lua_MeshPart.cpp" />
-		<Unit filename="src/lua/lua_MeshPart.h" />
-		<Unit filename="src/lua/lua_MeshPrimitiveType.cpp" />
-		<Unit filename="src/lua/lua_MeshPrimitiveType.h" />
-		<Unit filename="src/lua/lua_MeshSkin.cpp" />
-		<Unit filename="src/lua/lua_MeshSkin.h" />
-		<Unit filename="src/lua/lua_Model.cpp" />
-		<Unit filename="src/lua/lua_Model.h" />
-		<Unit filename="src/lua/lua_Mouse.cpp" />
-		<Unit filename="src/lua/lua_Mouse.h" />
-		<Unit filename="src/lua/lua_MouseMouseEvent.cpp" />
-		<Unit filename="src/lua/lua_MouseMouseEvent.h" />
-		<Unit filename="src/lua/lua_Node.cpp" />
-		<Unit filename="src/lua/lua_Node.h" />
-		<Unit filename="src/lua/lua_NodeCloneContext.cpp" />
-		<Unit filename="src/lua/lua_NodeCloneContext.h" />
-		<Unit filename="src/lua/lua_NodeType.cpp" />
-		<Unit filename="src/lua/lua_NodeType.h" />
-		<Unit filename="src/lua/lua_ParticleEmitter.cpp" />
-		<Unit filename="src/lua/lua_ParticleEmitter.h" />
-		<Unit filename="src/lua/lua_ParticleEmitterTextureBlending.cpp" />
-		<Unit filename="src/lua/lua_ParticleEmitterTextureBlending.h" />
-		<Unit filename="src/lua/lua_Pass.cpp" />
-		<Unit filename="src/lua/lua_Pass.h" />
-		<Unit filename="src/lua/lua_PhysicsCharacter.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCharacter.h" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObject.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObject.h" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionListener.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionListener.h" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionListenerEventType.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionListenerEventType.h" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionPair.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObjectCollisionPair.h" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObjectType.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCollisionObjectType.h" />
-		<Unit filename="src/lua/lua_PhysicsCollisionShape.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCollisionShape.h" />
-		<Unit filename="src/lua/lua_PhysicsCollisionShapeDefinition.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCollisionShapeDefinition.h" />
-		<Unit filename="src/lua/lua_PhysicsCollisionShapeType.cpp" />
-		<Unit filename="src/lua/lua_PhysicsCollisionShapeType.h" />
-		<Unit filename="src/lua/lua_PhysicsConstraint.cpp" />
-		<Unit filename="src/lua/lua_PhysicsConstraint.h" />
-		<Unit filename="src/lua/lua_PhysicsController.cpp" />
-		<Unit filename="src/lua/lua_PhysicsController.h" />
-		<Unit filename="src/lua/lua_PhysicsControllerHitFilter.cpp" />
-		<Unit filename="src/lua/lua_PhysicsControllerHitFilter.h" />
-		<Unit filename="src/lua/lua_PhysicsControllerHitResult.cpp" />
-		<Unit filename="src/lua/lua_PhysicsControllerHitResult.h" />
-		<Unit filename="src/lua/lua_PhysicsControllerListener.cpp" />
-		<Unit filename="src/lua/lua_PhysicsControllerListener.h" />
-		<Unit filename="src/lua/lua_PhysicsControllerListenerEventType.cpp" />
-		<Unit filename="src/lua/lua_PhysicsControllerListenerEventType.h" />
-		<Unit filename="src/lua/lua_PhysicsFixedConstraint.cpp" />
-		<Unit filename="src/lua/lua_PhysicsFixedConstraint.h" />
-		<Unit filename="src/lua/lua_PhysicsGenericConstraint.cpp" />
-		<Unit filename="src/lua/lua_PhysicsGenericConstraint.h" />
-		<Unit filename="src/lua/lua_PhysicsGhostObject.cpp" />
-		<Unit filename="src/lua/lua_PhysicsGhostObject.h" />
-		<Unit filename="src/lua/lua_PhysicsHingeConstraint.cpp" />
-		<Unit filename="src/lua/lua_PhysicsHingeConstraint.h" />
-		<Unit filename="src/lua/lua_PhysicsRigidBody.cpp" />
-		<Unit filename="src/lua/lua_PhysicsRigidBody.h" />
-		<Unit filename="src/lua/lua_PhysicsRigidBodyParameters.cpp" />
-		<Unit filename="src/lua/lua_PhysicsRigidBodyParameters.h" />
-		<Unit filename="src/lua/lua_PhysicsSocketConstraint.cpp" />
-		<Unit filename="src/lua/lua_PhysicsSocketConstraint.h" />
-		<Unit filename="src/lua/lua_PhysicsSpringConstraint.cpp" />
-		<Unit filename="src/lua/lua_PhysicsSpringConstraint.h" />
-		<Unit filename="src/lua/lua_PhysicsVehicle.cpp" />
-		<Unit filename="src/lua/lua_PhysicsVehicle.h" />
-		<Unit filename="src/lua/lua_PhysicsVehicleWheel.cpp" />
-		<Unit filename="src/lua/lua_PhysicsVehicleWheel.h" />
-		<Unit filename="src/lua/lua_Plane.cpp" />
-		<Unit filename="src/lua/lua_Plane.h" />
-		<Unit filename="src/lua/lua_Platform.cpp" />
-		<Unit filename="src/lua/lua_Platform.h" />
-		<Unit filename="src/lua/lua_Properties.cpp" />
-		<Unit filename="src/lua/lua_Properties.h" />
-		<Unit filename="src/lua/lua_PropertiesType.cpp" />
-		<Unit filename="src/lua/lua_PropertiesType.h" />
-		<Unit filename="src/lua/lua_Quaternion.cpp" />
-		<Unit filename="src/lua/lua_Quaternion.h" />
-		<Unit filename="src/lua/lua_RadioButton.cpp" />
-		<Unit filename="src/lua/lua_RadioButton.h" />
-		<Unit filename="src/lua/lua_Ray.cpp" />
-		<Unit filename="src/lua/lua_Ray.h" />
-		<Unit filename="src/lua/lua_Rectangle.cpp" />
-		<Unit filename="src/lua/lua_Rectangle.h" />
-		<Unit filename="src/lua/lua_Ref.cpp" />
-		<Unit filename="src/lua/lua_Ref.h" />
-		<Unit filename="src/lua/lua_RenderState.cpp" />
-		<Unit filename="src/lua/lua_RenderState.h" />
-		<Unit filename="src/lua/lua_RenderStateAutoBinding.cpp" />
-		<Unit filename="src/lua/lua_RenderStateAutoBinding.h" />
-		<Unit filename="src/lua/lua_RenderStateBlend.cpp" />
-		<Unit filename="src/lua/lua_RenderStateBlend.h" />
-		<Unit filename="src/lua/lua_RenderStateStateBlock.cpp" />
-		<Unit filename="src/lua/lua_RenderStateStateBlock.h" />
-		<Unit filename="src/lua/lua_RenderTarget.cpp" />
-		<Unit filename="src/lua/lua_RenderTarget.h" />
-		<Unit filename="src/lua/lua_Scene.cpp" />
-		<Unit filename="src/lua/lua_Scene.h" />
-		<Unit filename="src/lua/lua_SceneDebugFlags.cpp" />
-		<Unit filename="src/lua/lua_SceneDebugFlags.h" />
-		<Unit filename="src/lua/lua_ScreenDisplayer.cpp" />
-		<Unit filename="src/lua/lua_ScreenDisplayer.h" />
-		<Unit filename="src/lua/lua_ScriptController.cpp" />
-		<Unit filename="src/lua/lua_ScriptController.h" />
-		<Unit filename="src/lua/lua_ScriptTarget.cpp" />
-		<Unit filename="src/lua/lua_ScriptTarget.h" />
-		<Unit filename="src/lua/lua_Slider.cpp" />
-		<Unit filename="src/lua/lua_Slider.h" />
-		<Unit filename="src/lua/lua_SpriteBatch.cpp" />
-		<Unit filename="src/lua/lua_SpriteBatch.h" />
-		<Unit filename="src/lua/lua_Technique.cpp" />
-		<Unit filename="src/lua/lua_Technique.h" />
-		<Unit filename="src/lua/lua_TextBox.cpp" />
-		<Unit filename="src/lua/lua_TextBox.h" />
-		<Unit filename="src/lua/lua_Texture.cpp" />
-		<Unit filename="src/lua/lua_Texture.h" />
-		<Unit filename="src/lua/lua_TextureFilter.cpp" />
-		<Unit filename="src/lua/lua_TextureFilter.h" />
-		<Unit filename="src/lua/lua_TextureFormat.cpp" />
-		<Unit filename="src/lua/lua_TextureFormat.h" />
-		<Unit filename="src/lua/lua_TextureSampler.cpp" />
-		<Unit filename="src/lua/lua_TextureSampler.h" />
-		<Unit filename="src/lua/lua_TextureWrap.cpp" />
-		<Unit filename="src/lua/lua_TextureWrap.h" />
-		<Unit filename="src/lua/lua_Theme.cpp" />
-		<Unit filename="src/lua/lua_Theme.h" />
-		<Unit filename="src/lua/lua_ThemeSideRegions.cpp" />
-		<Unit filename="src/lua/lua_ThemeSideRegions.h" />
-		<Unit filename="src/lua/lua_ThemeStyle.cpp" />
-		<Unit filename="src/lua/lua_ThemeStyle.h" />
-		<Unit filename="src/lua/lua_ThemeThemeImage.cpp" />
-		<Unit filename="src/lua/lua_ThemeThemeImage.h" />
-		<Unit filename="src/lua/lua_ThemeUVs.cpp" />
-		<Unit filename="src/lua/lua_ThemeUVs.h" />
-		<Unit filename="src/lua/lua_Touch.cpp" />
-		<Unit filename="src/lua/lua_Touch.h" />
-		<Unit filename="src/lua/lua_TouchTouchEvent.cpp" />
-		<Unit filename="src/lua/lua_TouchTouchEvent.h" />
-		<Unit filename="src/lua/lua_Transform.cpp" />
-		<Unit filename="src/lua/lua_Transform.h" />
-		<Unit filename="src/lua/lua_TransformListener.cpp" />
-		<Unit filename="src/lua/lua_TransformListener.h" />
-		<Unit filename="src/lua/lua_Uniform.cpp" />
-		<Unit filename="src/lua/lua_Uniform.h" />
-		<Unit filename="src/lua/lua_Vector2.cpp" />
-		<Unit filename="src/lua/lua_Vector2.h" />
-		<Unit filename="src/lua/lua_Vector3.cpp" />
-		<Unit filename="src/lua/lua_Vector3.h" />
-		<Unit filename="src/lua/lua_Vector4.cpp" />
-		<Unit filename="src/lua/lua_Vector4.h" />
-		<Unit filename="src/lua/lua_VertexAttributeBinding.cpp" />
-		<Unit filename="src/lua/lua_VertexAttributeBinding.h" />
-		<Unit filename="src/lua/lua_VertexFormat.cpp" />
-		<Unit filename="src/lua/lua_VertexFormat.h" />
-		<Unit filename="src/lua/lua_VertexFormatElement.cpp" />
-		<Unit filename="src/lua/lua_VertexFormatElement.h" />
-		<Unit filename="src/lua/lua_VertexFormatUsage.cpp" />
-		<Unit filename="src/lua/lua_VertexFormatUsage.h" />
-		<Unit filename="src/lua/lua_VerticalLayout.cpp" />
-		<Unit filename="src/lua/lua_VerticalLayout.h" />
-		<Unit filename="src/lua/lua_all_bindings.cpp" />
-		<Unit filename="src/lua/lua_all_bindings.h" />
-		<Extensions>
-			<code_completion />
-			<debugger />
-		</Extensions>
-	</Project>
-</CodeBlocks_project_file>

+ 151 - 10
gameplay/gameplay.vcxproj

@@ -13,6 +13,10 @@
       <Configuration>DebugMem</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMem|x64">
+      <Configuration>DebugMem</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|BlackBerry">
       <Configuration>Debug</Configuration>
       <Platform>BlackBerry</Platform>
@@ -25,6 +29,10 @@
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|BlackBerry">
       <Configuration>Release</Configuration>
       <Platform>BlackBerry</Platform>
@@ -37,6 +45,10 @@
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\AbsoluteLayout.cpp" />
@@ -77,6 +89,7 @@
     <ClCompile Include="src\gameplay-main-blackberry.cpp" />
     <ClCompile Include="src\gameplay-main-linux.cpp" />
     <ClCompile Include="src\gameplay-main-windows.cpp" />
+    <ClCompile Include="src\HeightField.cpp" />
     <ClCompile Include="src\Image.cpp" />
     <ClCompile Include="src\Joint.cpp" />
     <ClCompile Include="src\Joystick.cpp" />
@@ -137,12 +150,13 @@
     <ClCompile Include="src\lua\lua_Game.cpp" />
     <ClCompile Include="src\lua\lua_GameClearFlags.cpp" />
     <ClCompile Include="src\lua\lua_Gamepad.cpp" />
-    <ClCompile Include="src\lua\lua_GamepadButtonState.cpp" />
+    <ClCompile Include="src\lua\lua_GamepadButtonMapping.cpp" />
     <ClCompile Include="src\lua\lua_GamepadGamepadEvent.cpp" />
     <ClCompile Include="src\lua\lua_GameState.cpp" />
     <ClCompile Include="src\lua\lua_Gesture.cpp" />
     <ClCompile Include="src\lua\lua_GestureGestureEvent.cpp" />
     <ClCompile Include="src\lua\lua_Global.cpp" />
+    <ClCompile Include="src\lua\lua_HeightField.cpp" />
     <ClCompile Include="src\lua\lua_Image.cpp" />
     <ClCompile Include="src\lua\lua_ImageFormat.cpp" />
     <ClCompile Include="src\lua\lua_Joint.cpp" />
@@ -213,6 +227,7 @@
     <ClCompile Include="src\lua\lua_RenderState.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateAutoBinding.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateBlend.cpp" />
+    <ClCompile Include="src\lua\lua_RenderStateDepthFunction.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateStateBlock.cpp" />
     <ClCompile Include="src\lua\lua_RenderTarget.cpp" />
     <ClCompile Include="src\lua\lua_Scene.cpp" />
@@ -223,6 +238,8 @@
     <ClCompile Include="src\lua\lua_Slider.cpp" />
     <ClCompile Include="src\lua\lua_SpriteBatch.cpp" />
     <ClCompile Include="src\lua\lua_Technique.cpp" />
+    <ClCompile Include="src\lua\lua_Terrain.cpp" />
+    <ClCompile Include="src\lua\lua_TerrainFlags.cpp" />
     <ClCompile Include="src\lua\lua_TextBox.cpp" />
     <ClCompile Include="src\lua\lua_Texture.cpp" />
     <ClCompile Include="src\lua\lua_TextureFilter.cpp" />
@@ -295,6 +312,8 @@
     <ClCompile Include="src\Slider.cpp" />
     <ClCompile Include="src\SpriteBatch.cpp" />
     <ClCompile Include="src\Technique.cpp" />
+    <ClCompile Include="src\Terrain.cpp" />
+    <ClCompile Include="src\TerrainPatch.cpp" />
     <ClCompile Include="src\TextBox.cpp" />
     <ClCompile Include="src\Texture.cpp" />
     <ClCompile Include="src\Theme.cpp" />
@@ -345,6 +364,7 @@
     <ClInclude Include="src\Gamepad.h" />
     <ClInclude Include="src\gameplay.h" />
     <ClInclude Include="src\Gesture.h" />
+    <ClInclude Include="src\HeightField.h" />
     <ClInclude Include="src\Image.h" />
     <ClInclude Include="src\Joint.h" />
     <ClInclude Include="src\Joystick.h" />
@@ -406,12 +426,13 @@
     <ClInclude Include="src\lua\lua_Game.h" />
     <ClInclude Include="src\lua\lua_GameClearFlags.h" />
     <ClInclude Include="src\lua\lua_Gamepad.h" />
-    <ClInclude Include="src\lua\lua_GamepadButtonState.h" />
+    <ClInclude Include="src\lua\lua_GamepadButtonMapping.h" />
     <ClInclude Include="src\lua\lua_GamepadGamepadEvent.h" />
     <ClInclude Include="src\lua\lua_GameState.h" />
     <ClInclude Include="src\lua\lua_Gesture.h" />
     <ClInclude Include="src\lua\lua_GestureGestureEvent.h" />
     <ClInclude Include="src\lua\lua_Global.h" />
+    <ClInclude Include="src\lua\lua_HeightField.h" />
     <ClInclude Include="src\lua\lua_Image.h" />
     <ClInclude Include="src\lua\lua_ImageFormat.h" />
     <ClInclude Include="src\lua\lua_Joint.h" />
@@ -482,6 +503,7 @@
     <ClInclude Include="src\lua\lua_RenderState.h" />
     <ClInclude Include="src\lua\lua_RenderStateAutoBinding.h" />
     <ClInclude Include="src\lua\lua_RenderStateBlend.h" />
+    <ClInclude Include="src\lua\lua_RenderStateDepthFunction.h" />
     <ClInclude Include="src\lua\lua_RenderStateStateBlock.h" />
     <ClInclude Include="src\lua\lua_RenderTarget.h" />
     <ClInclude Include="src\lua\lua_Scene.h" />
@@ -492,6 +514,8 @@
     <ClInclude Include="src\lua\lua_Slider.h" />
     <ClInclude Include="src\lua\lua_SpriteBatch.h" />
     <ClInclude Include="src\lua\lua_Technique.h" />
+    <ClInclude Include="src\lua\lua_Terrain.h" />
+    <ClInclude Include="src\lua\lua_TerrainFlags.h" />
     <ClInclude Include="src\lua\lua_TextBox.h" />
     <ClInclude Include="src\lua\lua_Texture.h" />
     <ClInclude Include="src\lua\lua_TextureFilter.h" />
@@ -561,7 +585,10 @@
     <ClInclude Include="src\ScriptTarget.h" />
     <ClInclude Include="src\Slider.h" />
     <ClInclude Include="src\SpriteBatch.h" />
+    <ClInclude Include="src\Stream.h" />
     <ClInclude Include="src\Technique.h" />
+    <ClInclude Include="src\Terrain.h" />
+    <ClInclude Include="src\TerrainPatch.h" />
     <ClInclude Include="src\TextBox.h" />
     <ClInclude Include="src\Texture.h" />
     <ClInclude Include="src\Theme.h" />
@@ -594,6 +621,8 @@
     <None Include="res\shaders\lib\lighting-spot.frag" />
     <None Include="res\shaders\lib\lighting-spot.vert" />
     <None Include="res\shaders\lib\lighting.frag" />
+    <None Include="res\shaders\terrain.frag" />
+    <None Include="res\shaders\terrain.vert" />
     <None Include="res\shaders\textured-bumped.frag" />
     <None Include="res\shaders\textured-bumped.vert" />
     <None Include="res\shaders\textured-unlit.frag" />
@@ -635,6 +664,11 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
@@ -650,6 +684,11 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
@@ -666,6 +705,12 @@
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
@@ -684,6 +729,9 @@
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
@@ -693,6 +741,9 @@
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
@@ -702,6 +753,9 @@
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
@@ -710,7 +764,10 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <OutDir>$(Configuration)\</OutDir>
+    <OutDir>windows\x86\$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>windows\x64\$(Configuration)\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
     <OutDir>Device-$(Configuration)\</OutDir>
@@ -719,7 +776,10 @@
     <OutDir>Simulator\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <OutDir>$(Configuration)\</OutDir>
+    <OutDir>windows\x86\$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <OutDir>windows\x64\$(Configuration)\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
     <OutDir>Device-$(Configuration)\</OutDir>
@@ -728,7 +788,10 @@
     <OutDir>Simulator\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Configuration)\</IntDir>
+    <IntDir>windows\x86\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <IntDir>windows\x64\$(Configuration)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
     <IntDir>Device-$(Configuration)\</IntDir>
@@ -739,7 +802,10 @@
     <TargetName>lib$(ProjectName)</TargetName>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
-    <IntDir>$(Configuration)\</IntDir>
+    <IntDir>windows\x86\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
+    <IntDir>windows\x64\$(Configuration)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
     <IntDir>Device-$(Configuration)\</IntDir>
@@ -750,7 +816,10 @@
     <TargetName>lib$(ProjectName)</TargetName>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <OutDir>$(Configuration)\</OutDir>
+    <OutDir>windows\x86\$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>windows\x64\$(Configuration)\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'">
     <OutDir>Device-$(Configuration)\</OutDir>
@@ -759,7 +828,10 @@
     <OutDir>Simulator\</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Configuration)\</IntDir>
+    <IntDir>windows\x86\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <IntDir>windows\x64\$(Configuration)\</IntDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'">
     <IntDir>Device-$(Configuration)\</IntDir>
@@ -785,8 +857,11 @@
       <SubSystem>Windows</SubSystem>
       <GenerateDebugInformation>true</GenerateDebugInformation>
     </Link>
+    <Lib>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
       <PrecompiledHeader>
       </PrecompiledHeader>
@@ -797,6 +872,26 @@
       <RuntimeTypeInfo>
       </RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Lib>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>__BB10__;_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>
+      </RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
@@ -839,9 +934,13 @@
     <Lib>
       <Verbose>
       </Verbose>
+      <AdditionalDependencies>
+      </AdditionalDependencies>
+      <AdditionalLibraryDirectories>
+      </AdditionalLibraryDirectories>
     </Lib>
   </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|x64'">
     <ClCompile>
       <PrecompiledHeader>
       </PrecompiledHeader>
@@ -851,6 +950,26 @@
       <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Lib>
+      <Verbose>
+      </Verbose>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>__BB10__;_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GAMEPLAY_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <Link>
@@ -892,6 +1011,28 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>

Diff do ficheiro suprimidas por serem muito extensas
+ 336 - 318
gameplay/gameplay.vcxproj.filters


Diff do ficheiro suprimidas por serem muito extensas
+ 42 - 968
gameplay/gameplay.xcodeproj/project.pbxproj


+ 1 - 0
gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-ios.xcscheme

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0450"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 1 - 0
gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-macosx.xcscheme

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
+   LastUpgradeVersion = "0450"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 9 - 9
gameplay/res/shaders/colored-unlit.frag

@@ -2,14 +2,6 @@
 precision highp float;
 #endif
 
-// Inputs
-#if defined(VERTEX_COLOR)
-varying vec3 v_color;						// Input Vertex color ( r g b )
-#endif
-#if defined(TEXTURE_LIGHTMAP)
-varying vec2 v_texCoord;
-#endif
-
 // Uniforms
 uniform vec4 u_diffuseColor;               	// Diffuse color
 #if defined(TEXTURE_LIGHTMAP)
@@ -22,7 +14,15 @@ uniform vec4 u_modulateColor;               // Modulation color
 uniform float u_modulateAlpha;              // Modulation alpha
 #endif
 
-// Fragment program
+// Varyings
+#if defined(VERTEX_COLOR)
+varying vec3 v_color;						// Input Vertex color ( r g b )
+#endif
+#if defined(TEXTURE_LIGHTMAP)
+varying vec2 v_texCoord;
+#endif
+
+
 void main()
 {
     // Set base diffuse color

+ 12 - 12
gameplay/res/shaders/colored-unlit.vert

@@ -1,4 +1,4 @@
-// Inputs
+// Attributes
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
 #if defined(TEXTURE_LIGHTMAP)
 attribute vec2 a_texCoord;                                  // Texture Coordinate (for lightmapping)
@@ -11,7 +11,13 @@ attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette
 attribute vec3 a_color;										// Vertex Color								(r, g, b)
 #endif
 
-// Outputs
+// Uniforms
+uniform mat4 u_worldViewProjectionMatrix;					// Matrix to transform a position to clip space.
+#if defined(SKINNING)
+uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];		// Array of 4x3 matrices as an array of floats
+#endif
+
+// Varyings
 #if defined(TEXTURE_LIGHTMAP)
 varying vec2 v_texCoord;                                    // Output Texture Coordinate
 #endif
@@ -19,20 +25,14 @@ varying vec2 v_texCoord;                                    // Output Texture Co
 varying vec3 v_color;										// Output Vertex color						(r, g, b)
 #endif
 
-// Uniforms
-uniform mat4 u_worldViewProjectionMatrix;					// Matrix to transform a position to clip space.
-#if defined(SKINNING)
-uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];		// Array of 4x3 matrices as an array of floats
-#endif
-
-// Attribute accessor
+// Skinning
 #if defined(SKINNING)
-#include "lib/attributes-skinning.vert"
+#include "skinning.vert"
 #else
-#include "lib/attributes.vert" 
+#include "skinning-none.vert" 
 #endif
 
-// Vertex Program
+
 void main()
 {
     // Get the vertex position

+ 24 - 21
gameplay/res/shaders/colored.frag

@@ -3,6 +3,25 @@
 precision highp float;
 #endif
 
+// Uniforms
+uniform vec4 u_diffuseColor;               		// Diffuse color
+uniform vec3 u_ambientColor;                    // Ambient color
+uniform vec3 u_lightColor;                      // Light color
+uniform vec3 u_lightDirection;					// Light direction
+#if defined(SPECULAR)
+uniform float u_specularExponent;				// Specular exponent
+#endif
+#if defined(SPOT_LIGHT)
+uniform float u_spotLightInnerAngleCos;			// The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;			// The soft outer part [0.0 - 1.0]
+#endif
+#if defined(MODULATE_COLOR)
+uniform vec4 u_modulateColor;					// Modulation color
+#endif
+#if defined(MODULATE_ALPHA)
+uniform float u_modulateAlpha;					// Modulation alpha
+#endif
+
 // Inputs
 varying vec3 v_normalVector;					// Normal vector in view space
 #if defined(VERTEX_COLOR)
@@ -22,32 +41,16 @@ varying vec3 v_lightDirection;					// Direction of light in tangent space
 varying vec3 v_cameraDirection;                 // Camera direction
 #endif
 
-// Uniforms
-uniform vec4 u_diffuseColor;               		// Diffuse color
-uniform vec3 u_ambientColor;                    // Ambient color
-uniform vec3 u_lightColor;                      // Light color
-uniform vec3 u_lightDirection;					// Light direction
-#if defined(SPECULAR)
-uniform float u_specularExponent;				// Specular exponent
-#endif
-#if defined(MODULATE_COLOR)
-uniform vec4 u_modulateColor;					// Modulation color
-#endif
-#if defined(MODULATE_ALPHA)
-uniform float u_modulateAlpha;					// Modulation alpha
-#endif
-#include "lib/lighting.frag"
+// Lighting
+#include "lighting.frag"
 #if defined(POINT_LIGHT)
-#include "lib/lighting-point.frag"
+#include "lighting-point.frag"
 #elif defined(SPOT_LIGHT)
-uniform float u_spotLightInnerAngleCos;			// The bright spot [0.0 - 1.0]
-uniform float u_spotLightOuterAngleCos;			// The soft outer part [0.0 - 1.0]
-#include "lib/lighting-spot.frag"
+#include "lighting-spot.frag"
 #else
-#include "lib/lighting-directional.frag"
+#include "lighting-directional.frag"
 #endif
 
-// Fragment program
 void main()
 {
     // Set base diffuse color

+ 11 - 10
gameplay/res/shaders/colored.vert

@@ -1,6 +1,6 @@
 #define LIGHTING
 
-// Inputs
+// Attributes
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
 attribute vec3 a_normal;									// Vertex Normal							(x, y, z)
 #if defined(SKINNING)
@@ -14,7 +14,7 @@ varying vec3 v_color;										// Output Vertex Color
 
 // Uniforms
 uniform mat4 u_worldViewProjectionMatrix;					// Matrix to transform a position to clip space.
-uniform mat4 u_inverseTransposeWorldViewMatrix;				// Matrix to transform a normal to view space.
+uniform mat4 u_inverseTransposeWorldViewMatrix;				// Matrix to transform a normal to view space
 #if defined(SKINNING)
 uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];		// Array of 4x3 matrices
 #endif
@@ -31,33 +31,34 @@ uniform float u_spotLightRangeInverse;						// Inverse of light range.
 #else
 #endif
 
-// Outputs
+// Varyings
 varying vec3 v_normalVector;								// Normal vector in view space.
 #if defined(SPECULAR)
 varying vec3 v_cameraDirection;								// Direction the camera is looking at in tangent space.
 #endif
+
 // Lighting
 #if defined(POINT_LIGHT)
 varying vec3 v_vertexToPointLightDirection;					// Direction of point light w.r.t current vertex in tangent space.
 varying float v_pointLightAttenuation;						// Attenuation of point light.
-#include "lib/lighting-point.vert"
+#include "lighting-point.vert"
 #elif defined(SPOT_LIGHT)
 varying vec3 v_vertexToSpotLightDirection;					// Direction of the spot light w.r.t current vertex in tangent space.
 varying float v_spotLightAttenuation;						// Attenuation of spot light.
-#include "lib/lighting-spot.vert"
+#include "lighting-spot.vert"
 #else
 uniform vec3 u_lightDirection;								// Direction of light
-#include "lib/lighting-directional.vert"
+#include "lighting-directional.vert"
 #endif
 
-// Vertex attribute accessors
+// Skinning
 #if defined(SKINNING)
-#include "lib/attributes-skinning.vert"
+#include "skinning.vert"
 #else
-#include "lib/attributes.vert" 
+#include "skinning-none.vert" 
 #endif
 
-// Vertex program
+
 void main()
 {
     // Get the position and normal

+ 17 - 0
gameplay/res/shaders/font.frag

@@ -0,0 +1,17 @@
+#ifdef OPENGL_ES
+precision highp float;
+#endif
+
+// Uniforms
+uniform sampler2D u_texture;
+
+// Varyings
+varying vec2 v_texCoord;
+varying vec4 v_color;
+
+
+void main()
+{
+    gl_FragColor = v_color;
+    gl_FragColor.a = texture2D(u_texture, v_texCoord).a * v_color.a;
+}

+ 19 - 0
gameplay/res/shaders/font.vert

@@ -0,0 +1,19 @@
+// Atttributes
+attribute vec3 a_position;
+attribute vec2 a_texCoord;
+attribute vec4 a_color;
+
+// Uniforms
+uniform mat4 u_projectionMatrix;
+
+// Varyings
+varying vec2 v_texCoord;
+varying vec4 v_color;
+
+
+void main()
+{
+    gl_Position = u_projectionMatrix * vec4(a_position, 1);
+    v_texCoord = a_texCoord;
+    v_color = a_color;
+}

+ 15 - 0
gameplay/res/shaders/form.frag

@@ -0,0 +1,15 @@
+#ifdef OPENGL_ES
+precision highp float;
+#endif
+
+// Uniforms
+uniform sampler2D u_texture;
+
+// Varyings
+varying vec2 v_texCoord;
+
+
+void main()
+{
+    gl_FragColor = texture2D(u_texture, v_texCoord);
+}

+ 16 - 0
gameplay/res/shaders/form.vert

@@ -0,0 +1,16 @@
+// Attributes
+attribute vec3 a_position;
+attribute vec2 a_texCoord;
+
+// Uniforms
+uniform mat4 u_worldViewProjectionMatrix;
+
+// Varyings
+varying vec2 v_texCoord;
+
+
+void main()
+{
+    gl_Position = u_worldViewProjectionMatrix * vec4(a_position, 1);
+    v_texCoord = a_texCoord;
+}

+ 0 - 0
gameplay/res/shaders/lib/lighting-directional.frag → gameplay/res/shaders/lighting-directional.frag


+ 5 - 5
gameplay/res/shaders/lib/lighting-directional.vert → gameplay/res/shaders/lighting-directional.vert

@@ -8,9 +8,9 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
     #if defined(SPECULAR)
 
     // Compute the camera direction for specular lighting
-    vec4 positionWorldSpace = u_worldViewMatrix * a_position;
-    v_cameraDirection = u_cameraPosition - positionWorldSpace.xyz;
-    
+	vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    v_cameraDirection = u_cameraPosition - positionWorldViewSpace.xyz;
+
     #endif
 }
 
@@ -22,8 +22,8 @@ void applyLight(vec4 position)
     #if defined(SPECULAR)
 
     // Compute the camera direction for specular lighting
-    vec4 positionWorldSpace = u_worldViewMatrix * position;
-    v_cameraDirection = u_cameraPosition - positionWorldSpace.xyz;
+	vec4 positionWorldViewSpace = u_worldViewMatrix * position;
+    v_cameraDirection = u_cameraPosition - positionWorldViewSpace.xyz;
 
     #endif
 }

+ 0 - 0
gameplay/res/shaders/lib/lighting-point.frag → gameplay/res/shaders/lighting-point.frag


+ 9 - 12
gameplay/res/shaders/lib/lighting-point.vert → gameplay/res/shaders/lighting-point.vert

@@ -28,25 +28,22 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
 
 void applyLight(vec4 position)
 {
-    // World space position.
-    vec4 positionWorldViewSpace = u_worldViewMatrix * position;
+    // World view space position.
+	vec4 positionWorldViewSpace = u_worldViewMatrix * position;
     
-    // Compute the light direction.
-    vec3 lightDirection = u_pointLightPosition - positionWorldViewSpace.xyz;
-   
-    vec4 vertexToPointLightDirection;
-    vertexToPointLightDirection.xyz = lightDirection;
+    // Compute the light direction with light position and the vertex position.
+	v_vertexToPointLightDirection = u_pointLightPosition - positionWorldViewSpace.xyz;
    
     // Attenuation
-    v_pointLightAttenuation = 1.0 - dot(lightDirection * u_pointLightRangeInverse, lightDirection * u_pointLightRangeInverse);
+    v_pointLightAttenuation = 1.0 - dot(v_vertexToPointLightDirection * u_pointLightRangeInverse, v_vertexToPointLightDirection * u_pointLightRangeInverse);
 
     // Output light direction.
-    v_vertexToPointLightDirection =  vertexToPointLightDirection;
-   
-    #if defined (SPECULAR)
+    //v_vertexToPointLightDirection = lightDirection;
    
-    vec3 cameraDirection = normalize(v_cameraDirection);
+    #if defined (SPECULAR)  
 
+	v_cameraDirection = u_cameraPosition - positionWorldViewSpace.xyz;
+	
     #endif
 }
 

+ 3 - 3
gameplay/res/shaders/lib/lighting-spot.frag → gameplay/res/shaders/lighting-spot.frag

@@ -13,7 +13,7 @@ vec3 getLitPixel()
     vec3 vertexToSpotLightDirection = normalize(v_vertexToSpotLightDirection);
     
     // "-lightDirection" because light direction points in opposite direction to to spot direction.
-    float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
+    float spotCurrentAngleCos = dot(spotLightDirection, -vertexToSpotLightDirection);
     
     // Intensity of spot depends on the spot light attenuation and the part of the cone vertexToSpotLightDirection points to (inner or outer).
     float spotLightAttenuation = clamp(v_spotLightAttenuation, 0.0, 1.0);
@@ -40,8 +40,8 @@ vec3 getLitPixel()
     vec3 spotLightDirection = normalize(u_spotLightDirection); 
     vec3 vertexToSpotLightDirection = normalize(v_vertexToSpotLightDirection);
 
-    // "-lightDirection" is used because light direction points in opposite direction to to spot direction.
-    float spotCurrentAngleCos = max(0.0, dot(spotLightDirection, -vertexToSpotLightDirection));
+    // "-lightDirection" is used because light direction points in opposite direction to spot direction.
+    float spotCurrentAngleCos = dot(spotLightDirection, -vertexToSpotLightDirection);
     
     // Intensity of spot depends on the spot light attenuation and the 
     // part of the cone vertexToSpotLightDirection points to (inner or outer).

+ 15 - 17
gameplay/res/shaders/lib/lighting-spot.vert → gameplay/res/shaders/lighting-spot.vert

@@ -2,13 +2,14 @@
 
 void applyLight(mat3 tangentSpaceTransformMatrix)
 {
-    vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
+    //vec4 positionWorldSpace = u_worldMatrix * a_position;
+	vec4 positionWorldViewSpace = u_worldViewMatrix * a_position;
 
     // Transform spot light direction to tangent space.
     v_spotLightDirection = tangentSpaceTransformMatrix * u_spotLightDirection;
 
     // Compute the light direction with light position and the vertex position.
-    vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
+	vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
     
     // Transform current light direction to tangent space.
     lightDirection = tangentSpaceTransformMatrix * lightDirection;
@@ -22,7 +23,7 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
     #if defined(SPECULAR)
     
     // Compute camera direction and transform it to tangent space.
-    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
+	v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
     
     #endif
 }
@@ -31,24 +32,21 @@ void applyLight(mat3 tangentSpaceTransformMatrix)
 
 void applyLight(vec4 position)
 {
-    // World space position.
-    vec4 positionWorldViewSpace = u_worldViewMatrix * position;
+    // World view space position.
+	vec4 positionWorldViewSpace = u_worldViewMatrix * position;
 
     // Compute the light direction with light position and the vertex position.
-    vec3 lightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
-
-    // Attenuation
-    v_spotLightAttenuation = 1.0 - dot(lightDirection * u_spotLightRangeInverse, lightDirection * u_spotLightRangeInverse);
-
-    // Output light direction.
-    v_vertexToSpotLightDirection = lightDirection;
-    
-    #if defined(SPECULAR)
+	v_vertexToSpotLightDirection = u_spotLightPosition - positionWorldViewSpace.xyz;
     
+    // Attenuation
+    v_spotLightAttenuation = 1.0 - dot(v_vertexToSpotLightDirection * u_spotLightRangeInverse, v_vertexToSpotLightDirection * u_spotLightRangeInverse);
+  
     // Compute camera direction and transform it to tangent space.
-    v_cameraDirection = tangentSpaceTransformMatrix * (u_cameraPosition - positionWorldViewSpace.xyz);
-    
-    #endif
+	#if defined(SPECULAR)
+	
+	v_cameraDirection = u_cameraPosition - positionWorldViewSpace.xyz;
+	
+	#endif
 }
 
 #endif

+ 0 - 0
gameplay/res/shaders/lib/lighting.frag → gameplay/res/shaders/lighting.frag


+ 0 - 0
gameplay/res/shaders/lib/attributes.vert → gameplay/res/shaders/skinning-none.vert


+ 2 - 2
gameplay/res/shaders/lib/attributes-skinning.vert → gameplay/res/shaders/skinning.vert

@@ -37,6 +37,8 @@ vec4 getPosition()
     return _skinnedPosition;    
 }
 
+#if defined(LIGHTING)
+
 void skinTangentSpaceVector(vec3 vector, float blendWeight, int matrixIndex)
 {
     vec3 tmp;
@@ -70,8 +72,6 @@ vec3 getTangentSpaceVector(vec3 vector)
     return _skinnedNormal;
 }
 
-#if defined(LIGHTING)
-
 vec3 getNormal()
 {
     return getTangentSpaceVector(a_normal);

+ 16 - 0
gameplay/res/shaders/sprite.frag

@@ -0,0 +1,16 @@
+#ifdef OPENGL_ES
+precision highp float;
+#endif
+
+// Uniforms
+uniform sampler2D u_texture;
+
+// Varyings
+varying vec2 v_texCoord;
+varying vec4 v_color;
+
+
+void main()
+{
+    gl_FragColor = v_color * texture2D(u_texture, v_texCoord);
+}

+ 19 - 0
gameplay/res/shaders/sprite.vert

@@ -0,0 +1,19 @@
+// Attributes
+attribute vec3 a_position;
+attribute vec2 a_texCoord;
+attribute vec4 a_color;
+
+// Uniforms
+uniform mat4 u_projectionMatrix;
+
+// Varyings
+varying vec2 v_texCoord;
+varying vec4 v_color;
+
+
+void main()
+{
+    gl_Position = u_projectionMatrix * vec4(a_position, 1);
+    v_texCoord = a_texCoord;
+    v_color = a_color;
+}

+ 82 - 0
gameplay/res/shaders/terrain.frag

@@ -0,0 +1,82 @@
+#ifdef OPENGL_ES
+precision highp float;
+#endif
+
+// Uniforms
+uniform vec3 u_ambientColor;                    // Ambient color
+uniform vec3 u_lightColor;                      // Light color
+uniform vec3 u_lightDirection;					// Light direction
+#if defined(DEBUG_PATCHES)
+uniform float u_row;                            // Patch row
+uniform float u_column;                         // Patch column
+#endif
+#if (LAYER_COUNT > 0)
+uniform sampler2D u_samplers[SAMPLER_COUNT];    // Surface layer samplers
+#endif
+#if defined (NORMAL_MAP)
+uniform sampler2D u_normalMap;                  // Normal map
+#endif
+
+// Varyings
+#if defined(NORMAL_MAP)
+vec3 v_normalVector;                            // Normal vector variable (from normal map)
+#else
+varying vec3 v_normalVector;					// Normal vector from vertex shader
+#endif
+varying vec2 v_texCoord0;
+#if (LAYER_COUNT > 0)
+varying vec2 v_texCoordLayer0;
+#endif
+#if (LAYER_COUNT > 1)
+varying vec2 v_texCoordLayer1;
+#endif
+#if (LAYER_COUNT > 2)
+varying vec2 v_texCoordLayer2;
+#endif
+
+// Lighting
+#include "lighting.frag"
+#include "lighting-directional.frag"
+
+#if (LAYER_COUNT > 1)
+void blendLayer(sampler2D textureMap, vec2 texCoord, float alphaBlend)
+{
+    // Sample full intensity diffuse color
+    vec3 diffuse = texture2D(textureMap,  mod(texCoord, vec2(1,1))).rgb;
+
+    _baseColor.rgb = _baseColor.rgb * (1.0 - alphaBlend) + diffuse * alphaBlend;
+}
+#endif
+
+void main()
+{
+#if (LAYER_COUNT > 0)
+    // Sample base texture
+	_baseColor.rgb = texture2D(u_samplers[TEXTURE_INDEX_0], mod(v_texCoordLayer0, vec2(1,1))).rgb;
+    _baseColor.a = 1.0;
+#else
+    // If no layers are defined, simply use a white color
+    _baseColor = vec4(1,1,1,1);
+#endif
+
+#if (LAYER_COUNT > 1)
+    blendLayer(u_samplers[TEXTURE_INDEX_1], v_texCoordLayer1, texture2D(u_samplers[BLEND_INDEX_1], v_texCoord0)[BLEND_CHANNEL_1]);
+#endif
+#if (LAYER_COUNT > 2)
+    blendLayer(u_samplers[TEXTURE_INDEX_2], v_texCoordLayer2, texture2D(u_samplers[BLEND_INDEX_2], v_texCoord0)[BLEND_CHANNEL_2]);
+#endif
+
+#if defined(DEBUG_PATCHES)
+    // If patch debug drawing is enabled, tint patches alternate colors
+    float tint = mod(u_row + mod(u_column, 2.0), 2.0);
+    _baseColor.rgb = _baseColor.rgb * 0.75 + vec3(1.0-tint, tint, 0) * 0.25;
+#endif
+
+    // Light the pixel
+#if defined(NORMAL_MAP)
+    v_normalVector = normalize(texture2D(u_normalMap, v_texCoord0).xyz * 2.0 - 1.0);
+#endif
+
+    gl_FragColor.a = _baseColor.a;
+    gl_FragColor.rgb = getLitPixel();
+}

+ 53 - 0
gameplay/res/shaders/terrain.vert

@@ -0,0 +1,53 @@
+// Attributes
+attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
+#ifndef NORMAL_MAP
+attribute vec3 a_normal;									// Vertex Normal							(x, y, z)
+#endif
+attribute vec2 a_texCoord0;
+
+// Uniforms
+uniform mat4 u_worldViewProjectionMatrix;					// World view projection matrix
+#ifndef NORMAL_MAP
+uniform mat4 u_normalMatrix;					            // Matrix used for normal vector transformation
+#endif
+uniform vec3 u_lightDirection;								// Direction of light
+
+// Varyings
+#ifndef NORMAL_MAP
+varying vec3 v_normalVector;								// Normal vector out
+#endif
+varying vec2 v_texCoord0;
+#if LAYER_COUNT > 0
+varying vec2 v_texCoordLayer0;
+#endif
+#if LAYER_COUNT > 1
+varying vec2 v_texCoordLayer1;
+#endif
+#if LAYER_COUNT > 2
+varying vec2 v_texCoordLayer2;
+#endif
+
+void main()
+{
+    // Transform position to clip space.
+    gl_Position = u_worldViewProjectionMatrix * a_position;
+
+#ifndef NORMAL_MAP
+    // Pass normal to fragment shader
+    v_normalVector = (u_normalMatrix * vec4(a_normal.x, a_normal.y, a_normal.z, 0)).xyz;
+#endif
+
+    // Pass base texture coord
+    v_texCoord0 = a_texCoord0;
+
+    // Pass repeated texture coordinates for each layer
+#if LAYER_COUNT > 0
+    v_texCoordLayer0 = a_texCoord0 * TEXTURE_REPEAT_0;
+#endif
+#if LAYER_COUNT > 1
+    v_texCoordLayer1 = a_texCoord0 * TEXTURE_REPEAT_1;
+#endif
+#if LAYER_COUNT > 2
+    v_texCoordLayer2 = a_texCoord0 * TEXTURE_REPEAT_2;
+#endif
+}

+ 36 - 28
gameplay/res/shaders/textured-bumped.frag

@@ -5,7 +5,27 @@
 precision highp float;
 #endif
 
-// Inputs
+// Uniforms
+uniform sampler2D u_diffuseTexture;        		// Diffuse map texture
+uniform sampler2D u_normalmapTexture;       	// Normalmap texture
+uniform vec3 u_ambientColor;                    // Ambient color
+uniform vec3 u_lightColor;                      // Light color
+uniform vec3 u_lightDirection;					// Light direction
+#if defined(SPECULAR)
+uniform float u_specularExponent;				// Specular exponent.
+#endif
+#if defined (SPOT_LIGHT)
+uniform float u_spotLightInnerAngleCos;			// The bright spot [0.0 - 1.0]
+uniform float u_spotLightOuterAngleCos;			// The soft outer part [0.0 - 1.0]
+#endif
+#if defined(MODULATE_COLOR)
+uniform vec4 u_modulateColor;					// Modulation color
+#endif
+#if defined(MODULATE_ALPHA)
+uniform float u_modulateAlpha;					// Modulation alpha
+#endif
+
+// Varyings
 varying vec3 v_normalVector;					// Normal vector in view space
 varying vec2 v_texCoord;						// Texture Coordinate
 #if defined(POINT_LIGHT)
@@ -22,33 +42,17 @@ varying vec3 v_lightDirection;					// Direction of light in tangent space.
 varying vec3 v_cameraDirection;                 // Camera direction
 #endif
 
-// Uniforms
-uniform sampler2D u_diffuseTexture;        		// Diffuse map texture
-uniform sampler2D u_normalmapTexture;       	// Normalmap texture
-uniform vec3 u_ambientColor;                    // Ambient color
-uniform vec3 u_lightColor;                      // Light color
-uniform vec3 u_lightDirection;					// Light direction
-#if defined(SPECULAR)
-uniform float u_specularExponent;				// Specular exponent.
-#endif
-#if defined(MODULATE_COLOR)
-uniform vec4 u_modulateColor;					// Modulation color
-#endif
-#if defined(MODULATE_ALPHA)
-uniform float u_modulateAlpha;					// Modulation alpha
-#endif
-#include "lib/lighting.frag"
+// Lighting
+#include "lighting.frag"
 #if defined(POINT_LIGHT)
-#include "lib/lighting-point.frag"
+#include "lighting-point.frag"
 #elif defined(SPOT_LIGHT)
-uniform float u_spotLightInnerAngleCos;			// The bright spot [0.0 - 1.0]
-uniform float u_spotLightOuterAngleCos;			// The soft outer part [0.0 - 1.0]
-#include "lib/lighting-spot.frag"
+#include "lighting-spot.frag"
 #else
-#include "lib/lighting-directional.frag"
+#include "lighting-directional.frag"
 #endif
 
-// Fragment program
+
 void main()
 {
     // Fetch diffuse color from texture.
@@ -56,13 +60,17 @@ void main()
 
     // Light the pixel
     gl_FragColor.a = _baseColor.a;
+    #if defined(TEXTURE_DISCARD_ALPHA)
+    if (gl_FragColor.a < 0.5)
+        discard;
+    #endif
     gl_FragColor.rgb = getLitPixel();
 
-	// Global color modulation
-	#if defined(MODULATE_COLOR)
-	gl_FragColor *= u_modulateColor;
-	#endif
-	#if defined(MODULATE_ALPHA)
+    // Global color modulation
+    #if defined(MODULATE_COLOR)
+    gl_FragColor *= u_modulateColor;
+    #endif
+    #if defined(MODULATE_ALPHA)
     gl_FragColor.a *= u_modulateAlpha;
     #endif
 }

+ 14 - 10
gameplay/res/shaders/textured-bumped.vert

@@ -15,11 +15,14 @@ attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette
 // Uniforms
 uniform mat4 u_worldViewProjectionMatrix;					// Matrix to transform a position to clip space
 uniform mat4 u_inverseTransposeWorldViewMatrix;				// Matrix to transform a normal to view space
+#if defined(SPECULAR) || defined(SPOT_LIGHT) || defined(POINT_LIGHT)
+uniform mat4 u_worldViewMatrix;								// Matrix to tranform a position to view space
+uniform mat4 u_worldMatrix;								    // Matrix to tranform a position to world space
+#endif
 #if defined(SKINNING)
 uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];		// Array of 4x3 matrices
 #endif
 #if defined(SPECULAR)
-uniform mat4 u_worldViewMatrix;								// Matrix to tranform a position to view space
 uniform vec3 u_cameraPosition;                 				// Position of the camera in view space
 #endif
 #if defined(TEXTURE_REPEAT)
@@ -39,35 +42,36 @@ uniform vec3 u_spotLightDirection;							// Direction of light
 uniform vec3 u_lightDirection;								// Direction of light
 #endif
 
-// Outputs
+// Varyings
 varying vec3 v_normalVector;								// Normal vector in view space
 varying vec2 v_texCoord;									// Texture Coordinate
 #if defined(SPECULAR)
 varying vec3 v_cameraDirection;								// Direction the camera is looking at in tangent space
 #endif
+
 // Lighting
 #if defined(POINT_LIGHT)
 varying vec3 v_vertexToPointLightDirection;					// Direction of point light w.r.t current vertex in tangent space
 varying float v_pointLightAttenuation;						// Attenuation of point light
-#include "lib/lighting-point.vert"
+#include "lighting-point.vert"
 #elif defined(SPOT_LIGHT)
 varying vec3 v_vertexToSpotLightDirection;					// Direction of the spot light w.r.t current vertex in tangent space
 varying float v_spotLightAttenuation;						// Attenuation of spot light
 varying vec3 v_spotLightDirection;							// Direction of spot light in tangent space
-#include "lib/lighting-spot.vert"
+#include "lighting-spot.vert"
 #else
 varying vec3 v_lightDirection;								// Direction of light
-#include "lib/lighting-directional.vert"
+#include "lighting-directional.vert"
 #endif
 
-// Vertex Attribute Accessors
+// Skinning
 #if defined(SKINNING)
-#include "lib/attributes-skinning.vert"
+#include "skinning.vert"
 #else
-#include "lib/attributes.vert" 
+#include "skinning-none.vert" 
 #endif
 
-// Vertex program
+
 void main()
 {
     // Get the position, normal, tangents and binormals.
@@ -80,7 +84,7 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform the normal, tangent and binormals to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz, u_inverseTransposeWorldViewMatrix[1].xyz, u_inverseTransposeWorldViewMatrix[2].xyz);
+	mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz, u_inverseTransposeWorldViewMatrix[1].xyz, u_inverseTransposeWorldViewMatrix[2].xyz);
     vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * normal);
     
     // Create a transform to convert a vector to tangent space.

+ 13 - 9
gameplay/res/shaders/textured-unlit.frag

@@ -14,30 +14,34 @@ uniform vec4 u_modulateColor;               // Modulation color
 uniform float u_modulateAlpha;              // Modulation alpha
 #endif
 
-// Inputs
+// Varyings
 varying vec2 v_texCoord0;                	// Texture coordinate(u, v)
 #if defined(TEXCOORD1)
 varying vec2 v_texCoord1;                   // Second tex coord for multi-texturing
 #endif
 
-// Fragment Program
+
 void main()
 {
     // Sample the texture for the color
     gl_FragColor = texture2D(u_diffuseTexture, v_texCoord0);
-	#if defined(TEXTURE_LIGHTMAP)
+    #if defined(TEXTURE_DISCARD_ALPHA)
+    if (gl_FragColor.a < 0.5)
+        discard;
+    #endif
+    #if defined(TEXTURE_LIGHTMAP)
     #if defined(TEXCOORD1)
     vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord1);
     #else
     vec4 lightColor = texture2D(u_lightmapTexture, v_texCoord0);
     #endif
     gl_FragColor.rgb *= lightColor.rgb;
-	#endif
-	// Global color modulation
-	#if defined(MODULATE_COLOR)
-	gl_FragColor *= u_modulateColor;
-	#endif
-	#if defined(MODULATE_ALPHA)
+    #endif
+    // Global color modulation
+    #if defined(MODULATE_COLOR)
+    gl_FragColor *= u_modulateColor;
+    #endif
+    #if defined(MODULATE_ALPHA)
     gl_FragColor.a *= u_modulateAlpha;
     #endif
 }

+ 6 - 6
gameplay/res/shaders/textured-unlit.vert

@@ -1,4 +1,4 @@
-// Inputs
+// Attributes
 attribute vec4 a_position;									// Vertex Position							(x, y, z, w)
 attribute vec2 a_texCoord0;									// Vertex Texture Coordinate				(u, v)
 #if defined(TEXCOORD1)
@@ -21,20 +21,20 @@ uniform vec2 u_textureRepeat;								// Texture repeat for tiling
 uniform vec2 u_textureOffset;								// Texture offset
 #endif
 
-// Outputs
+// Varyings
 varying vec2 v_texCoord0;									// Texture Coordinate
 #if defined(TEXCOORD1)
 varying vec2 v_texCoord1;                                   // Second tex coord for multi-texturing
 #endif
 
-// Vertex attribute accessors
+// Skinning 
 #if defined(SKINNING)
-#include "lib/attributes-skinning.vert"
+#include "skinning.vert"
 #else
-#include "lib/attributes.vert" 
+#include "skinning-none.vert" 
 #endif
 
-// Vertex Program
+
 void main()
 {
     // Get the vertex position

+ 27 - 21
gameplay/res/shaders/textured.frag

@@ -4,7 +4,22 @@
 precision highp float;
 #endif
 
-// Inputs
+// Uniforms
+uniform sampler2D u_diffuseTexture;             // Diffuse map texture
+uniform vec3 u_ambientColor;                    // Ambient color
+uniform vec3 u_lightColor;                      // Light color
+uniform vec3 u_lightDirection;					// Light direction
+#if defined(SPECULAR)
+uniform float u_specularExponent;				// Specular exponent
+#endif
+#if defined(MODULATE_COLOR)
+uniform vec4 u_modulateColor;               	// Modulation color
+#endif
+#if defined(MODULATE_ALPHA)
+uniform float u_modulateAlpha;              	// Modulation alpha
+#endif
+
+// Varyings
 varying vec3 v_normalVector;                    // Normal vector in view space
 varying vec2 v_texCoord;                        // Texture coordinate
 #if defined(POINT_LIGHT)
@@ -21,33 +36,20 @@ varying vec3 v_lightDirection;					// Direction of light in tangent space.
 varying vec3 v_cameraDirection;                 // Camera direction
 #endif
 
-// Uniforms
-uniform sampler2D u_diffuseTexture;             // Diffuse map texture
-uniform vec3 u_ambientColor;                    // Ambient color
-uniform vec3 u_lightColor;                      // Light color
-uniform vec3 u_lightDirection;					// Light direction
-
-#if defined(SPECULAR)
-uniform float u_specularExponent;				// Specular exponent
-#endif
-#if defined(MODULATE_COLOR)
-uniform vec4 u_modulateColor;               	// Modulation color
-#endif
-#if defined(MODULATE_ALPHA)
-uniform float u_modulateAlpha;              	// Modulation alpha
-#endif
-#include "lib/lighting.frag"
+// Lighting 
+#include "lighting.frag"
 #if defined(POINT_LIGHT)
-#include "lib/lighting-point.frag"
+#include "lighting-point.frag"
 #elif defined(SPOT_LIGHT)
 uniform float u_spotLightInnerAngleCos;			// The bright spot [0.0 - 1.0]
 uniform float u_spotLightOuterAngleCos;			// The soft outer part [0.0 - 1.0]
-#include "lib/lighting-spot.frag"
+uniform vec3 u_spotLightDirection;              // Direction of a spot light source
+#include "lighting-spot.frag"
 #else
-#include "lib/lighting-directional.frag"
+#include "lighting-directional.frag"
 #endif
 
-// Fragment Program
+
 void main()
 {
     // Sample the diffuse texture for base color
@@ -55,6 +57,10 @@ void main()
 
     // Light the pixel
     gl_FragColor.a = _baseColor.a;
+    #if defined(TEXTURE_DISCARD_ALPHA)
+    if (gl_FragColor.a < 0.5)
+        discard;
+    #endif
     gl_FragColor.rgb = getLitPixel();
 	
 	// Global color modulation

+ 18 - 13
gameplay/res/shaders/textured.vert

@@ -1,6 +1,6 @@
 #define LIGHTING
 
-// Inputs
+// Attributes
 attribute vec4 a_position;									// Vertex position							(x, y, z, w)
 attribute vec3 a_normal;									// Vertex normal							(x, y, z)
 attribute vec2 a_texCoord;									// Vertex texture coordinate				(u, v)
@@ -12,11 +12,13 @@ attribute vec4 a_blendIndices;								// Vertex blend index int u_matrixPalette
 // Uniforms
 uniform mat4 u_worldViewProjectionMatrix;					// Matrix to transform a position to clip space
 uniform mat4 u_inverseTransposeWorldViewMatrix;				// Matrix to transform a normal to view space
+#if defined(SPECULAR) || defined(SPOT_LIGHT) || defined(POINT_LIGHT)
+uniform mat4 u_worldViewMatrix;								// Matrix to tranform a position to view space
+#endif
 #if defined(SKINNING)
 uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];		// Array of 4x3 matrices
 #endif
 #if defined(SPECULAR)
-uniform mat4 u_worldViewMatrix;								// Matrix to tranform a position to view space
 uniform vec3 u_cameraPosition;                 				// Position of the camera in view space
 #endif
 #if defined(TEXTURE_REPEAT)
@@ -31,10 +33,11 @@ uniform float u_pointLightRangeInverse;						// Inverse of light range
 #elif defined(SPOT_LIGHT)
 uniform vec3 u_spotLightPosition;							// Position of light
 uniform float u_spotLightRangeInverse;						// Inverse of light range
+uniform vec3 u_spotLightDirection;                          // Direction of a spot light source
 #else
 #endif
 
-// Outputs
+// Varyings
 varying vec3 v_normalVector;								// Normal vector in view space
 varying vec2 v_texCoord;									// Texture coordinate
 #if defined(SPECULAR)
@@ -43,26 +46,28 @@ varying vec3 v_cameraDirection;								// Direction the camera is looking at in
 #if defined(POINT_LIGHT)
 varying vec3 v_vertexToPointLightDirection;					// Direction of point light w.r.t current vertex in tangent space
 varying float v_pointLightAttenuation;						// Attenuation of point light
-#include "lib/lighting-point.vert"
+#include "lighting-point.vert"
 #elif defined(SPOT_LIGHT)
 varying vec3 v_vertexToSpotLightDirection;					// Direction of the spot light w.r.t current vertex in tangent space
 varying float v_spotLightAttenuation;						// Attenuation of spot light
-#include "lib/lighting-spot.vert"
+
+// Lighting
+#include "lighting-spot.vert"
 #else
-#include "lib/lighting-directional.vert"
+#include "lighting-directional.vert"
 #endif
 
-// Vertex attribute accessors
+// Skinning
 #if defined(SKINNING)
-#include "lib/attributes-skinning.vert"
+#include "skinning.vert"
 #else
-#include "lib/attributes.vert" 
+#include "skinning-none.vert" 
 #endif
 
-// Vertex Program
+
 void main()
 {
-    // Get the position and normal from attribute accessors
+    // Get the position and normal
     vec4 position = getPosition();
     vec3 normal = getNormal();
 
@@ -70,12 +75,12 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 normalMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz, u_inverseTransposeWorldViewMatrix[1].xyz, u_inverseTransposeWorldViewMatrix[2].xyz);
+	mat3 normalMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz, u_inverseTransposeWorldViewMatrix[1].xyz, u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = normalMatrix * normal;
 
     // Apply light.
     applyLight(position);
-    
+
     // Texture transformation
     v_texCoord = a_texCoord;
     #if defined(TEXTURE_REPEAT)

+ 1 - 2
gameplay/src/AbsoluteLayout.cpp

@@ -42,8 +42,7 @@ void AbsoluteLayout::update(const Container* container, const Vector2& offset)
 
     // 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++)
+    for (size_t i = 0, count = controls.size(); i < count; i++)
     {
         Control* control = controls[i];
         GP_ASSERT(control);

+ 2 - 2
gameplay/src/Animation.cpp

@@ -18,7 +18,7 @@ namespace gameplay
 Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type)
     : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
 {
-    createChannel(target, propertyId, keyCount, keyTimes, keyValues, type);
+    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();
@@ -171,7 +171,7 @@ AnimationClip* Animation::getClip(unsigned int index) const
 
 unsigned int Animation::getClipCount() const
 {
-    return _clips ? _clips->size() : 0;
+    return _clips ? (unsigned int)_clips->size() : 0;
 }
 
 void Animation::play(const char* clipId)

+ 10 - 6
gameplay/src/AnimationClip.cpp

@@ -17,9 +17,8 @@ AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long
 {
     GP_ASSERT(_animation);
     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++)
+
+    for (size_t i = 0, count = _animation->_channels.size(); i < count; i++)
     {
         GP_ASSERT(_animation->_channels[i]);
         GP_ASSERT(_animation->_channels[i]->getCurve());
@@ -445,9 +444,13 @@ bool AnimationClip::update(float elapsedTime)
 
     // Add back in start time, and divide by the total animation's duration to get the actual percentage complete
     GP_ASSERT(_animation);
-    GP_ASSERT(_animation->_duration > 0);
-    float percentComplete = ((float)_startTime + currentTime) / (float)_animation->_duration;
+
+    // If the animation duration is zero (start time == end time, such as when there is only a single keyframe),
+    // then prevent a divide by zero and set percentComplete = 1.
+    float percentComplete = _animation->_duration == 0 ? 1 : ((float)_startTime + currentTime) / (float)_animation->_duration;
     
+    percentComplete = MATH_CLAMP(percentComplete, 0.0f, 1.0f);
+
     if (isClipStateBitSet(CLIP_IS_FADING_OUT_BIT))
     {
         GP_ASSERT(_crossFadeToClip);
@@ -484,7 +487,8 @@ bool AnimationClip::update(float elapsedTime)
             }
         }
         else
-        {   // Fade is done.
+        {
+            // Fade is done.
             _crossFadeToClip->_blendWeight = 1.0f;
             _blendWeight = 0.0f;
             resetClipStateBit(CLIP_IS_STARTED_BIT);            

+ 81 - 55
gameplay/src/AudioBuffer.cpp

@@ -8,6 +8,36 @@ namespace gameplay
 // Audio buffer cache
 static std::vector<AudioBuffer*> __buffers;
 
+// Callbacks for loading an ogg file using Stream
+static size_t readStream(void *ptr, size_t size, size_t nmemb, void *datasource)
+{
+    GP_ASSERT(datasource);
+    Stream* stream = reinterpret_cast<Stream*>(datasource);
+    return stream->read(ptr, size, nmemb);
+}
+
+static int seekStream(void *datasource, ogg_int64_t offset, int whence)
+{
+    GP_ASSERT(datasource);
+    Stream* stream = reinterpret_cast<Stream*>(datasource);
+    return !stream->seek(offset, whence);
+}
+
+static int closeStream(void *datasource)
+{
+    GP_ASSERT(datasource);
+    Stream* stream = reinterpret_cast<Stream*>(datasource);
+    stream->close();
+    return 0;
+}
+
+static long tellStream(void *datasource)
+{
+    GP_ASSERT(datasource);
+    Stream* stream = reinterpret_cast<Stream*>(datasource);
+    return stream->position();
+}
+
 AudioBuffer::AudioBuffer(const char* path, ALuint buffer)
     : _filePath(path), _alBuffer(buffer)
 {
@@ -63,8 +93,8 @@ AudioBuffer* AudioBuffer::create(const char* path)
     }
     
     // Load sound file.
-    FILE* file = FileSystem::openFile(path, "rb");
-    if (!file)
+    std::auto_ptr<Stream> stream(FileSystem::open(path));
+    if (stream.get() == NULL || !stream->canRead())
     {
         GP_ERROR("Failed to load audio file %s.", path);
         goto cleanup;
@@ -72,7 +102,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     
     // Read the file header
     char header[12];
-    if (fread(header, 1, 12, file) != 12)
+    if (stream->read(header, 1, 12) != 12)
     {
         GP_ERROR("Invalid header for audio file %s.", path);
         goto cleanup;
@@ -81,7 +111,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     // Check the file format
     if (memcmp(header, "RIFF", 4) == 0)
     {
-        if (!AudioBuffer::loadWav(file, alBuffer))
+        if (!AudioBuffer::loadWav(stream.get(), alBuffer))
         {
             GP_ERROR("Invalid wave file: %s", path);
             goto cleanup;
@@ -89,7 +119,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     }
     else if (memcmp(header, "OggS", 4) == 0)
     {
-        if (!AudioBuffer::loadOgg(file, alBuffer))
+        if (!AudioBuffer::loadOgg(stream.get(), alBuffer))
         {
             GP_ERROR("Invalid ogg file: %s", path);
             goto cleanup;
@@ -101,10 +131,6 @@ AudioBuffer* AudioBuffer::create(const char* path)
         goto cleanup;
     }
 
-    //NOTE: loadOgg actually sets this null, so it is expected
-    if (file)    
-        fclose(file);
-
     buffer = new AudioBuffer(path, alBuffer);
 
     // Add the buffer to the cache.
@@ -113,34 +139,32 @@ AudioBuffer* AudioBuffer::create(const char* path)
     return buffer;
     
 cleanup:
-    
-    if (file)
-        fclose(file);
     if (alBuffer)
         AL_CHECK( alDeleteBuffers(1, &alBuffer) );
     return NULL;
 }
 
-bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
+bool AudioBuffer::loadWav(Stream* stream, ALuint buffer)
 {
-    GP_ASSERT(file);
-    unsigned char stream[12];
+    GP_ASSERT(stream);
+
+    unsigned char data[12];
     
     // Verify the wave fmt magic value meaning format.
-    if (fread(stream, 1, 8, file) != 8 || memcmp(stream, "fmt ", 4) != 0 )
+    if (stream->read(data, 1, 8) != 8 || memcmp(data, "fmt ", 4) != 0 )
     {
         GP_ERROR("Failed to verify the magic value for the wave file format.");
         return false;
     }
     
     unsigned int section_size;
-    section_size  = stream[7]<<24;
-    section_size |= stream[6]<<16;
-    section_size |= stream[5]<<8;
-    section_size |= stream[4];
+    section_size  = data[7]<<24;
+    section_size |= data[6]<<16;
+    section_size |= data[5]<<8;
+    section_size |= data[4];
 
     // Check for a valid pcm format.
-    if (fread(stream, 1, 2, file) != 2 || stream[1] != 0 || stream[0] != 1)
+    if (stream->read(data, 1, 2) != 2 || data[1] != 0 || data[0] != 1)
     {
         GP_ERROR("Unsupported audio file format (must be a valid PCM format).");
         return false;
@@ -148,31 +172,31 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
     
     // Get the channel count (16-bit little-endian).
     int channels;
-    if (fread(stream, 1, 2, file) != 2)
+    if (stream->read(data, 1, 2) != 2)
     {
         GP_ERROR("Failed to read the wave file's channel count.");
         return false;
     }
-    channels  = stream[1]<<8;
-    channels |= stream[0];
+    channels  = data[1]<<8;
+    channels |= data[0];
     
     // Get the sample frequency (32-bit little-endian).
     ALuint frequency;
-    if (fread(stream, 1, 4, file) != 4)
+    if (stream->read(data, 1, 4) != 4)
     {
         GP_ERROR("Failed to read the wave file's sample frequency.");
         return false;
     }
 
-    frequency  = stream[3]<<24;
-    frequency |= stream[2]<<16;
-    frequency |= stream[1]<<8;
-    frequency |= stream[0];
+    frequency  = data[3]<<24;
+    frequency |= data[2]<<16;
+    frequency |= data[1]<<8;
+    frequency |= data[0];
     
     // The next 6 bytes hold the block size and bytes-per-second. 
     // We don't need that info, so just read and ignore it. 
     // We could use this later if we need to know the duration.
-    if (fread(stream, 1, 6, file) != 6)
+    if (stream->read(data, 1, 6) != 6)
     {
         GP_ERROR("Failed to read past the wave file's block size and bytes-per-second.");
         return false;
@@ -180,13 +204,13 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
     
     // Get the bit depth (16-bit little-endian).
     int bits;
-    if (fread(stream, 1, 2, file) != 2)
+    if (stream->read(data, 1, 2) != 2)
     {
         GP_ERROR("Failed to read the wave file's bit depth.");
         return false;
     }
-    bits  = stream[1]<<8;
-    bits |= stream[0];
+    bits  = data[1]<<8;
+    bits |= data[0];
     
     // Now convert the given channel count and bit depth into an OpenAL format. 
     ALuint format = 0;
@@ -216,7 +240,7 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
         unsigned int length = section_size - 16;
 
         // Extension size is 2 bytes.
-        if (fread(stream, 1, length, file) != length)
+        if (stream->read(data, 1, length) != length)
         {
             GP_ERROR("Failed to read extension size from wave file.");
             return false;
@@ -227,32 +251,32 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
     while (true)
     {
         // Check if we are at the end of the file without reading the data.
-        if (feof(file))
+        if (stream->eof())
         {
             GP_ERROR("Failed to load wave file; file appears to have no data.");
             return false;
         }
 
         // Read in the type of the next section of the file.
-        if (fread(stream, 1, 4, file) != 4)
+        if (stream->read(data, 1, 4) != 4)
         {
             GP_ERROR("Failed to read next section type from wave file.");
             return false;
         }
 
         // Data chunk.
-        if (memcmp(stream, "data", 4) == 0)
+        if (memcmp(data, "data", 4) == 0)
         {
             // Read how much data is remaining and buffer it up.
             unsigned int dataSize;
-            if (fread(&dataSize, sizeof(int), 1, file) != 1)
+            if (stream->read(&dataSize, sizeof(int), 1) != 1)
             {
                 GP_ERROR("Failed to read size of data section from wave file.");
                 return false;
             }
 
             char* data = new char[dataSize];
-            if (fread(data, sizeof(char), dataSize, file) != dataSize)
+            if (stream->read(data, sizeof(char), dataSize) != dataSize)
             {
                 GP_ERROR("Failed to load wave file; file is missing data.");
                 SAFE_DELETE_ARRAY(data);
@@ -281,22 +305,22 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
         {
             // Store the name of the chunk so we can report errors informatively.
             char chunk[5] = { 0 };
-            memcpy(chunk, stream, 4);
+            memcpy(chunk, data, 4);
 
             // Read the chunk size.
-            if (fread(stream, 1, 4, file) != 4)
+            if (stream->read(data, 1, 4) != 4)
             {
                 GP_ERROR("Failed to read size of '%s' chunk from wave file.", chunk);
                 return false;
             }
 
-            section_size  = stream[3]<<24;
-            section_size |= stream[2]<<16;
-            section_size |= stream[1]<<8;
-            section_size |= stream[0];
+            section_size  = data[3]<<24;
+            section_size |= data[2]<<16;
+            section_size |= data[1]<<8;
+            section_size |= data[0];
 
             // Seek past the chunk.
-            if (fseek(file, section_size, SEEK_CUR) != 0)
+            if (stream->seek(section_size, SEEK_CUR) == false)
             {
                 GP_ERROR("Failed to seek past '%s' chunk in wave file.", chunk);
                 return false;
@@ -304,10 +328,10 @@ bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
         }
     }
 }
-    
-bool AudioBuffer::loadOgg(FILE*& file, ALuint buffer)
+
+bool AudioBuffer::loadOgg(Stream* stream, ALuint buffer)
 {
-    GP_ASSERT(file);
+    GP_ASSERT(stream);
 
     OggVorbis_File ogg_file;
     vorbis_info* info;
@@ -316,11 +340,16 @@ bool AudioBuffer::loadOgg(FILE*& file, ALuint buffer)
     int section;
     long size = 0;
 
-    rewind(file);
+    stream->rewind();
 
-    if ((result = ov_open(file, &ogg_file, NULL, 0)) < 0)
+    ov_callbacks callbacks;
+    callbacks.read_func = readStream;
+    callbacks.seek_func = seekStream;
+    callbacks.close_func = closeStream;
+    callbacks.tell_func = tellStream;
+
+    if ((result = ov_open_callbacks(stream, &ogg_file, NULL, 0, callbacks)) < 0)
     {
-        fclose(file);
         GP_ERROR("Failed to open ogg file.");
         return false;
     }
@@ -367,9 +396,6 @@ bool AudioBuffer::loadOgg(FILE*& file, ALuint buffer)
     SAFE_DELETE_ARRAY(data);
     ov_clear(&ogg_file);
 
-    // ov_clear actually closes the file pointer as well.
-    file = 0;
-
     return true;
 }
 

+ 3 - 2
gameplay/src/AudioBuffer.h

@@ -2,6 +2,7 @@
 #define AUDIOBUFFER_H_
 
 #include "Ref.h"
+#include "Stream.h"
 
 namespace gameplay
 {
@@ -43,9 +44,9 @@ private:
      */
     static AudioBuffer* create(const char* path);
     
-    static bool loadWav(FILE* file, ALuint buffer);
+    static bool loadWav(Stream* stream, ALuint buffer);
     
-    static bool loadOgg(FILE*& file, ALuint buffer);
+    static bool loadOgg(Stream* stream, ALuint buffer);
 
     std::string _filePath;
     ALuint _alBuffer;

+ 3 - 1
gameplay/src/AudioListener.cpp

@@ -13,7 +13,9 @@ AudioListener::AudioListener()
 
 AudioListener::~AudioListener()
 {
-    SAFE_RELEASE(_camera);
+	// Call setCamera() to release camera and cause transform listener
+	// to be removed.
+	setCamera(NULL);
 }
 
 AudioListener* AudioListener::getInstance()

+ 13 - 26
gameplay/src/Base.h

@@ -14,6 +14,7 @@
 #include <cstdarg>
 #include <ctime>
 #include <iostream>
+#include <sstream>
 #include <string>
 #include <cstring>
 #include <vector>
@@ -21,6 +22,7 @@
 #include <set>
 #include <stack>
 #include <map>
+#include <queue>
 #include <algorithm>
 #include <limits>
 #include <functional>
@@ -186,9 +188,10 @@ using std::va_list;
 
 // Graphics (OpenGL)
 #ifdef __QNX__
-#include <EGL/egl.h>
+    #include <EGL/egl.h>
     #include <GLES2/gl2.h>
     #include <GLES2/gl2ext.h>
+    #include <screen/screen.h>
     extern PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray;
     extern PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
     extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
@@ -274,6 +277,15 @@ typedef GLuint TextureHandle;
 typedef GLuint FrameBufferHandle;
 /** Render buffer handle. */
 typedef GLuint RenderBufferHandle;
+
+/** Gamepad handle definitions vary by platform. */
+#if defined(__QNX__) && defined(USE_BLACKBERRY_GAMEPAD)
+    typedef screen_device_t GamepadHandle;
+#elif defined(USE_XINPUT)
+    typedef unsigned long GamepadHandle;
+#else
+    typedef unsigned int GamepadHandle;
+#endif
 }
 
 /**
@@ -295,35 +307,10 @@ typedef GLuint RenderBufferHandle;
     } while(0)
 #endif
 
-/**
- * Executes the specified GL code and checks the GL error afterwards
- * to ensure it succeeded.
- *
- * This macro should be used instead of GL_ASSERT for code that must
- * be checked in both debug and release builds. The GL_LAST_ERROR
- * macro can be used afterwards to check whether a GL error was
- * encountered executing the specified code.
- */
-#define GL_CHECK( gl_code ) do \
-    { \
-        while (glGetError() != GL_NO_ERROR) ; \
-        gl_code; \
-        __gl_error_code = glGetError(); \
-        if (__gl_error_code != GL_NO_ERROR) \
-        { \
-            GP_ERROR(#gl_code ": %d", (int)__gl_error_code); \
-        } \
-    } while(0)
-
 /** Global variable to hold GL errors
  * @script{ignore} */
 extern GLenum __gl_error_code;
 
-/**
- * Accesses the most recently set global GL error.
- */
-#define GL_LAST_ERROR() __gl_error_code
-
 /**
  * Executes the specified AL code and checks the AL error afterwards
  * to ensure it succeeded.

+ 93 - 113
gameplay/src/Bundle.cpp

@@ -32,7 +32,7 @@ namespace gameplay
 static std::vector<Bundle*> __bundleCache;
 
 Bundle::Bundle(const char* path) :
-    _path(path), _referenceCount(0), _references(NULL), _file(NULL), _trackedNodes(NULL)
+    _path(path), _referenceCount(0), _references(NULL), _stream(NULL), _trackedNodes(NULL)
 {
 }
 
@@ -49,10 +49,9 @@ Bundle::~Bundle()
 
     SAFE_DELETE_ARRAY(_references);
 
-    if (_file)
+    if (_stream)
     {
-        fclose(_file);
-        _file = NULL;
+        SAFE_DELETE(_stream);
     }
 }
 
@@ -61,7 +60,7 @@ bool Bundle::readArray(unsigned int* length, T** ptr)
 {
     GP_ASSERT(length);
     GP_ASSERT(ptr);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
 
     if (!read(length))
     {
@@ -71,7 +70,7 @@ bool Bundle::readArray(unsigned int* length, T** ptr)
     if (*length > 0)
     {
         *ptr = new T[*length];
-        if (fread(*ptr, sizeof(T), *length, _file) != *length)
+        if (_stream->read(*ptr, sizeof(T), *length) != *length)
         {
             GP_ERROR("Failed to read an array of data from bundle (into an array).");
             SAFE_DELETE_ARRAY(*ptr);
@@ -85,7 +84,7 @@ template <class T>
 bool Bundle::readArray(unsigned int* length, std::vector<T>* values)
 {
     GP_ASSERT(length);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
 
     if (!read(length))
     {
@@ -95,7 +94,7 @@ bool Bundle::readArray(unsigned int* length, std::vector<T>* values)
     if (*length > 0 && values)
     {
         values->resize(*length);
-        if (fread(&(*values)[0], sizeof(T), *length, _file) != *length)
+        if (_stream->read(&(*values)[0], sizeof(T), *length) != *length)
         {
             GP_ERROR("Failed to read an array of data from bundle (into a std::vector).");
             return false;
@@ -108,7 +107,7 @@ template <class T>
 bool Bundle::readArray(unsigned int* length, std::vector<T>* values, unsigned int readSize)
 {
     GP_ASSERT(length);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
     GP_ASSERT(sizeof(T) >= readSize);
 
     if (!read(length))
@@ -119,7 +118,7 @@ bool Bundle::readArray(unsigned int* length, std::vector<T>* values, unsigned in
     if (*length > 0 && values)
     {
         values->resize(*length);
-        if (fread(&(*values)[0], readSize, *length, _file) != *length)
+        if (_stream->read(&(*values)[0], readSize, *length) != *length)
         {
             GP_ERROR("Failed to read an array of data from bundle (into a std::vector with a specified single element read size).");
             return false;
@@ -128,12 +127,12 @@ bool Bundle::readArray(unsigned int* length, std::vector<T>* values, unsigned in
     return true;
 }
 
-static std::string readString(FILE* fp)
+static std::string readString(Stream* stream)
 {
-    GP_ASSERT(fp);
+    GP_ASSERT(stream);
 
     unsigned int length;
-    if (fread(&length, 4, 1, fp) != 1)
+    if (stream->read(&length, 4, 1) != 1)
     {
         GP_ERROR("Failed to read the length of a string from a bundle.");
         return std::string();
@@ -146,7 +145,7 @@ static std::string readString(FILE* fp)
     if (length > 0)
     {
         str.resize(length);
-        if (fread(&str[0], 1, length, fp) != length)
+        if (stream->read(&str[0], 1, length) != length)
         {
             GP_ERROR("Failed to read string from bundle.");
             return std::string();
@@ -160,7 +159,7 @@ Bundle* Bundle::create(const char* path)
     GP_ASSERT(path);
 
     // Search the cache for this bundle.
-    for (unsigned int i = 0, count = __bundleCache.size(); i < count; ++i)
+    for (size_t i = 0, count = __bundleCache.size(); i < count; ++i)
     {
         Bundle* p = __bundleCache[i];
         GP_ASSERT(p);
@@ -173,8 +172,8 @@ Bundle* Bundle::create(const char* path)
     }
 
     // Open the bundle.
-    FILE* fp = FileSystem::openFile(path, "rb");
-    if (!fp)
+    Stream* stream = FileSystem::open(path);
+    if (!stream)
     {
         GP_ERROR("Failed to open file '%s'.", path);
         return NULL;
@@ -182,46 +181,34 @@ Bundle* Bundle::create(const char* path)
 
     // Read the GPB header info.
     char sig[9];
-    if (fread(sig, 1, 9, fp) != 9 || memcmp(sig, "\xABGPB\xBB\r\n\x1A\n", 9) != 0)
+    if (stream->read(sig, 1, 9) != 9 || memcmp(sig, "\xABGPB\xBB\r\n\x1A\n", 9) != 0)
     {
+        SAFE_DELETE(stream);
         GP_ERROR("Invalid GPB header for bundle '%s'.", path);
-        if (fclose(fp) != 0)
-        {
-            GP_ERROR("Failed to close file '%s'.", path);
-        }
         return NULL;
     }
 
     // Read version.
     unsigned char ver[2];
-    if (fread(ver, 1, 2, fp) != 2)
+    if (stream->read(ver, 1, 2) != 2)
     {
+        SAFE_DELETE(stream);
         GP_ERROR("Failed to read GPB version for bundle '%s'.", path);
-        if (fclose(fp) != 0)
-        {
-            GP_ERROR("Failed to close file '%s'.", path);
-        }
         return NULL;
     }
     if (ver[0] != BUNDLE_VERSION_MAJOR || ver[1] != BUNDLE_VERSION_MINOR)
     {
+        SAFE_DELETE(stream);
         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);
-        if (fclose(fp) != 0)
-        {
-            GP_ERROR("Failed to close file '%s'.", path);
-        }
         return NULL;
     }
 
     // Read ref table.
     unsigned int refCount;
-    if (fread(&refCount, 4, 1, fp) != 1)
+    if (stream->read(&refCount, 4, 1) != 1)
     {
+        SAFE_DELETE(stream);
         GP_ERROR("Failed to read ref table for bundle '%s'.", path);
-        if (fclose(fp) != 0)
-        {
-            GP_ERROR("Failed to close file '%s'.", path);
-        }
         return NULL;
     }
 
@@ -229,15 +216,12 @@ Bundle* Bundle::create(const char* path)
     Reference* refs = new Reference[refCount];
     for (unsigned int i = 0; i < refCount; ++i)
     {
-        if ((refs[i].id = readString(fp)).empty() ||
-            fread(&refs[i].type, 4, 1, fp) != 1 ||
-            fread(&refs[i].offset, 4, 1, fp) != 1)
+        if ((refs[i].id = readString(stream)).empty() ||
+            stream->read(&refs[i].type, 4, 1) != 1 ||
+            stream->read(&refs[i].offset, 4, 1) != 1)
         {
+            SAFE_DELETE(stream);
             GP_ERROR("Failed to read ref number %d for bundle '%s'.", i, path);
-            if (fclose(fp) != 0)
-            {
-                GP_ERROR("Failed to close file '%s'.", path);
-            }
             SAFE_DELETE_ARRAY(refs);
             return NULL;
         }
@@ -247,7 +231,7 @@ Bundle* Bundle::create(const char* path)
     Bundle* bundle = new Bundle(path);
     bundle->_referenceCount = refCount;
     bundle->_references = refs;
-    bundle->_file = fp;
+    bundle->_stream = stream;
 
     return bundle;
 }
@@ -272,7 +256,7 @@ Bundle::Reference* Bundle::find(const char* id) const
 
 void Bundle::clearLoadSession()
 {
-    for (unsigned int i = 0, count = _meshSkins.size(); i < count; ++i)
+    for (size_t i = 0, count = _meshSkins.size(); i < count; ++i)
     {
         SAFE_DELETE(_meshSkins[i]);
     }
@@ -281,8 +265,8 @@ void Bundle::clearLoadSession()
 
 const char* Bundle::getIdFromOffset() const
 {
-    GP_ASSERT(_file);
-    return getIdFromOffset((unsigned int) ftell(_file));
+    GP_ASSERT(_stream);
+    return getIdFromOffset((unsigned int) _stream->position());
 }
 
 const char* Bundle::getIdFromOffset(unsigned int offset) const
@@ -318,8 +302,8 @@ Bundle::Reference* Bundle::seekTo(const char* id, unsigned int type)
     }
 
     // Seek to the offset of this object.
-    GP_ASSERT(_file);
-    if (fseek(_file, ref->offset, SEEK_SET) != 0)
+    GP_ASSERT(_stream);
+    if (_stream->seek(ref->offset, SEEK_SET) == false)
     {
         GP_ERROR("Failed to seek to object '%s' in bundle '%s'.", id, _path.c_str());
         return NULL;
@@ -331,7 +315,7 @@ Bundle::Reference* Bundle::seekTo(const char* id, unsigned int type)
 Bundle::Reference* Bundle::seekToFirstType(unsigned int type)
 {
     GP_ASSERT(_references);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
 
     for (unsigned int i = 0; i < _referenceCount; ++i)
     {
@@ -339,7 +323,7 @@ Bundle::Reference* Bundle::seekToFirstType(unsigned int type)
         if (ref->type == type)
         {
             // Found a match.
-            if (fseek(_file, ref->offset, SEEK_SET) != 0)
+            if (_stream->seek(ref->offset, SEEK_SET) == false)
             {
                 GP_ERROR("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
                 return NULL;
@@ -352,22 +336,22 @@ Bundle::Reference* Bundle::seekToFirstType(unsigned int type)
 
 bool Bundle::read(unsigned int* ptr)
 {
-    return fread(ptr, sizeof(unsigned int), 1, _file) == 1;
+    return _stream->read(ptr, sizeof(unsigned int), 1) == 1;
 }
 
 bool Bundle::read(unsigned char* ptr)
 {
-    return fread(ptr, sizeof(unsigned char), 1, _file) == 1;
+    return _stream->read(ptr, sizeof(unsigned char), 1) == 1;
 }
 
 bool Bundle::read(float* ptr)
 {
-    return fread(ptr, sizeof(float), 1, _file) == 1;
+    return _stream->read(ptr, sizeof(float), 1) == 1;
 }
 
 bool Bundle::readMatrix(float* m)
 {
-    return fread(m, sizeof(float), 16, _file) == 16;
+    return _stream->read(m, sizeof(float), 16) == 16;
 }
 
 Scene* Bundle::loadScene(const char* id)
@@ -394,8 +378,7 @@ Scene* Bundle::loadScene(const char* id)
         }
     }
 
-    Scene* scene = Scene::create();
-    scene->setId(getIdFromOffset());
+    Scene* scene = Scene::create(getIdFromOffset());
 
     // Read the number of children.
     unsigned int childrenCount;
@@ -419,7 +402,7 @@ Scene* Bundle::loadScene(const char* id)
         }
     }
     // Read active camera.
-    std::string xref = readString(_file);
+    std::string xref = readString(_stream);
     if (xref.length() > 1 && xref[0] == '#') // TODO: Handle full xrefs
     {
         Node* node = scene->findNode(xref.c_str() + 1, true);
@@ -453,14 +436,14 @@ Scene* Bundle::loadScene(const char* id)
 
     // Parse animations.
     GP_ASSERT(_references);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
     for (unsigned int i = 0; i < _referenceCount; ++i)
     {
         Reference* ref = &_references[i];
         if (ref->type == BUNDLE_TYPE_ANIMATIONS)
         {
             // Found a match.
-            if (fseek(_file, ref->offset, SEEK_SET) != 0)
+            if (_stream->seek(ref->offset, SEEK_SET) == false)
             {
                 GP_ERROR("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
                 return NULL;
@@ -483,7 +466,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
 {
     GP_ASSERT(id);
     GP_ASSERT(_references);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
 
     clearLoadSession();
 
@@ -499,7 +482,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
         Reference* ref = &_references[i];
         if (ref->type == BUNDLE_TYPE_ANIMATIONS)
         {
-            if (fseek(_file, ref->offset, SEEK_SET) != 0)
+            if (_stream->seek(ref->offset, SEEK_SET) == false)
             {
                 GP_ERROR("Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str());
                 SAFE_DELETE(_trackedNodes);
@@ -517,7 +500,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
 
             for (unsigned int j = 0; j < animationCount; j++)
             {
-                const std::string id = readString(_file);
+                const std::string id = readString(_stream);
 
                 // Read the number of animation channels in this animation.
                 unsigned int animationChannelCount;
@@ -532,7 +515,7 @@ Node* Bundle::loadNode(const char* id, Scene* sceneContext)
                 for (unsigned int k = 0; k < animationChannelCount; k++)
                 {
                     // Read target id.
-                    std::string targetId = readString(_file);
+                    std::string targetId = readString(_stream);
                     if (targetId.empty())
                     {
                         GP_ERROR("Failed to read target id for animation '%s'.", id.c_str());
@@ -627,7 +610,7 @@ bool Bundle::skipNode()
 {
     const char* id = getIdFromOffset();
     GP_ASSERT(id);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
 
     // Skip the node's type.
     unsigned int nodeType;
@@ -638,12 +621,12 @@ bool Bundle::skipNode()
     }
 
     // Skip over the node's transform and parent ID.
-    if (fseek(_file, sizeof(float) * 16, SEEK_CUR) != 0)
+    if (_stream->seek(sizeof(float) * 16, SEEK_CUR) == false)
     {
         GP_ERROR("Failed to skip over node transform for node '%s'.", id);
         return false;
     }
-    readString(_file);
+    readString(_stream);
 
     // Skip over the node's children.
     unsigned int childrenCount;
@@ -673,7 +656,7 @@ Node* Bundle::readNode(Scene* sceneContext, Node* nodeContext)
 {
     const char* id = getIdFromOffset();
     GP_ASSERT(id);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
 
     // If we are tracking nodes and it's not in the set yet, add it.
     if (_trackedNodes)
@@ -725,7 +708,7 @@ Node* Bundle::readNode(Scene* sceneContext, Node* nodeContext)
 
     // Read transform.
     float transform[16];
-    if (fread(transform, sizeof(float), 16, _file) != 16)
+    if (_stream->read(transform, sizeof(float), 16) != 16)
     {
         GP_ERROR("Failed to read transform for node '%s'.", id);
         SAFE_RELEASE(node);
@@ -734,7 +717,7 @@ Node* Bundle::readNode(Scene* sceneContext, Node* nodeContext)
     setTransform(transform, node);
 
     // Skip the parent ID.
-    readString(_file);
+    readString(_stream);
 
     // Read children.
     unsigned int childrenCount;
@@ -952,12 +935,10 @@ Light* Bundle::readLight()
 
 Model* Bundle::readModel(const char* nodeId)
 {
-    // Read mesh.
-    Mesh* mesh = NULL;
-    std::string xref = readString(_file);
+    std::string xref = readString(_stream);
     if (xref.length() > 1 && xref[0] == '#') // TODO: Handle full xrefs
     {
-        mesh = loadMesh(xref.c_str() + 1, nodeId);
+        Mesh* mesh = loadMesh(xref.c_str() + 1, nodeId);
         if (mesh)
         {
             Model* model = Model::create(mesh);
@@ -1035,7 +1016,7 @@ MeshSkin* Bundle::readMeshSkin()
     // Read joint xref strings for all joints in the list.
     for (unsigned int i = 0; i < jointCount; i++)
     {
-        skinData->joints.push_back(readString(_file));
+        skinData->joints.push_back(readString(_stream));
     }
 
     // Read bind poses.
@@ -1072,18 +1053,17 @@ MeshSkin* Bundle::readMeshSkin()
 
 void Bundle::resolveJointReferences(Scene* sceneContext, Node* nodeContext)
 {
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
 
-    const unsigned int skinCount = _meshSkins.size();
-    for (unsigned int i = 0; i < skinCount; ++i)
+    for (size_t i = 0, skinCount = _meshSkins.size(); i < skinCount; ++i)
     {
         MeshSkinData* skinData = _meshSkins[i];
         GP_ASSERT(skinData);
         GP_ASSERT(skinData->skin);
 
         // Resolve all joints in skin joint list.
-        const unsigned int jointCount = skinData->joints.size();
-        for (unsigned int j = 0; j < jointCount; ++j)
+        size_t jointCount = skinData->joints.size();
+        for (size_t j = 0; j < jointCount; ++j)
         {
             // TODO: Handle full xrefs (not just local # xrefs).
             std::string jointId = skinData->joints[j];
@@ -1096,7 +1076,7 @@ void Bundle::resolveJointReferences(Scene* sceneContext, Node* nodeContext)
                 {
                     Joint* joint = static_cast<Joint*>(n);
                     joint->setInverseBindPose(skinData->inverseBindPoseMatrices[j]);
-                    skinData->skin->setJoint(joint, j);
+                    skinData->skin->setJoint(joint, (unsigned int)j);
                     SAFE_RELEASE(joint);
                 }
             }
@@ -1145,12 +1125,12 @@ void Bundle::resolveJointReferences(Scene* sceneContext, Node* nodeContext)
                         seekTo(nodeId.c_str(), ref->type);
 
                         // Skip over the node type (1 unsigned int) and transform (16 floats) and read the parent id.
-                        if (fseek(_file, sizeof(unsigned int) + sizeof(float)*16, SEEK_CUR) != 0)
+                        if (_stream->seek(sizeof(unsigned int) + sizeof(float)*16, SEEK_CUR) == false)
                         {
                             GP_ERROR("Failed to skip over node type and transform for node '%s' in bundle '%s'.", nodeId.c_str(), _path.c_str());
                             return;
                         }
-                        std::string parentID = readString(_file);
+                        std::string parentID = readString(_stream);
 
                         if (!parentID.empty())
                             nodeId = parentID;
@@ -1186,7 +1166,7 @@ void Bundle::resolveJointReferences(Scene* sceneContext, Node* nodeContext)
 
 void Bundle::readAnimation(Scene* scene)
 {
-    const std::string animationId = readString(_file);
+    const std::string animationId = readString(_stream);
 
     // Read the number of animation channels in this animation.
     unsigned int animationChannelCount;
@@ -1224,7 +1204,7 @@ Animation* Bundle::readAnimationChannel(Scene* scene, Animation* animation, cons
     GP_ASSERT(animationId);
 
     // Read target id.
-    std::string targetId = readString(_file);
+    std::string targetId = readString(_stream);
     if (targetId.empty())
     {
         GP_ERROR("Failed to read target id for animation '%s'.", animationId);
@@ -1332,11 +1312,11 @@ Mesh* Bundle::loadMesh(const char* id)
 
 Mesh* Bundle::loadMesh(const char* id, const char* nodeId)
 {
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
     GP_ASSERT(id);
 
     // Save the file position.
-    long position = ftell(_file);
+    long position = _stream->position();
     if (position == -1L)
     {
         GP_ERROR("Failed to save the current file position before loading mesh '%s'.", id);
@@ -1396,7 +1376,7 @@ Mesh* Bundle::loadMesh(const char* id, const char* nodeId)
     SAFE_DELETE(meshData);
 
     // Restore file pointer.
-    if (fseek(_file, position, SEEK_SET) != 0)
+    if (_stream->seek(position, SEEK_SET) == false)
     {
         GP_ERROR("Failed to restore file pointer after loading mesh '%s'.", id);
         return NULL;
@@ -1409,7 +1389,7 @@ Bundle::MeshData* Bundle::readMeshData()
 {
     // Read vertex format/elements.
     unsigned int vertexElementCount;
-    if (fread(&vertexElementCount, 4, 1, _file) != 1)
+    if (_stream->read(&vertexElementCount, 4, 1) != 1)
     {
         GP_ERROR("Failed to load vertex element count.");
         return NULL;
@@ -1424,13 +1404,13 @@ Bundle::MeshData* Bundle::readMeshData()
     for (unsigned int i = 0; i < vertexElementCount; ++i)
     {
         unsigned int vUsage, vSize;
-        if (fread(&vUsage, 4, 1, _file) != 1)
+        if (_stream->read(&vUsage, 4, 1) != 1)
         {
             GP_ERROR("Failed to load vertex usage.");
             SAFE_DELETE_ARRAY(vertexElements);
             return NULL;
         }
-        if (fread(&vSize, 4, 1, _file) != 1)
+        if (_stream->read(&vSize, 4, 1) != 1)
         {
             GP_ERROR("Failed to load vertex size.");
             SAFE_DELETE_ARRAY(vertexElements);
@@ -1446,7 +1426,7 @@ Bundle::MeshData* Bundle::readMeshData()
 
     // Read vertex data.
     unsigned int vertexByteCount;
-    if (fread(&vertexByteCount, 4, 1, _file) != 1)
+    if (_stream->read(&vertexByteCount, 4, 1) != 1)
     {
         GP_ERROR("Failed to load vertex byte count.");
         SAFE_DELETE(meshData);
@@ -1462,7 +1442,7 @@ Bundle::MeshData* Bundle::readMeshData()
     GP_ASSERT(meshData->vertexFormat.getVertexSize());
     meshData->vertexCount = vertexByteCount / meshData->vertexFormat.getVertexSize();
     meshData->vertexData = new unsigned char[vertexByteCount];
-    if (fread(meshData->vertexData, 1, vertexByteCount, _file) != vertexByteCount)
+    if (_stream->read(meshData->vertexData, 1, vertexByteCount) != vertexByteCount)
     {
         GP_ERROR("Failed to load vertex data.");
         SAFE_DELETE(meshData);
@@ -1470,13 +1450,13 @@ Bundle::MeshData* Bundle::readMeshData()
     }
 
     // Read mesh bounds (bounding box and bounding sphere).
-    if (fread(&meshData->boundingBox.min.x, 4, 3, _file) != 3 || fread(&meshData->boundingBox.max.x, 4, 3, _file) != 3)
+    if (_stream->read(&meshData->boundingBox.min.x, 4, 3) != 3 || _stream->read(&meshData->boundingBox.max.x, 4, 3) != 3)
     {
         GP_ERROR("Failed to load mesh bounding box.");
         SAFE_DELETE(meshData);
         return NULL;
     }
-    if (fread(&meshData->boundingSphere.center.x, 4, 3, _file) != 3 || fread(&meshData->boundingSphere.radius, 4, 1, _file) != 1)
+    if (_stream->read(&meshData->boundingSphere.center.x, 4, 3) != 3 || _stream->read(&meshData->boundingSphere.radius, 4, 1) != 1)
     {
         GP_ERROR("Failed to load mesh bounding sphere.");
         SAFE_DELETE(meshData);
@@ -1485,7 +1465,7 @@ Bundle::MeshData* Bundle::readMeshData()
 
     // Read mesh parts.
     unsigned int meshPartCount;
-    if (fread(&meshPartCount, 4, 1, _file) != 1)
+    if (_stream->read(&meshPartCount, 4, 1) != 1)
     {
         GP_ERROR("Failed to load mesh part count.");
         SAFE_DELETE(meshData);
@@ -1495,19 +1475,19 @@ Bundle::MeshData* Bundle::readMeshData()
     {
         // Read primitive type, index format and index count.
         unsigned int pType, iFormat, iByteCount;
-        if (fread(&pType, 4, 1, _file) != 1)
+        if (_stream->read(&pType, 4, 1) != 1)
         {
             GP_ERROR("Failed to load primitive type for mesh part with index %d.", i);
             SAFE_DELETE(meshData);
             return NULL;
         }
-        if (fread(&iFormat, 4, 1, _file) != 1)
+        if (_stream->read(&iFormat, 4, 1) != 1)
         {
             GP_ERROR("Failed to load index format for mesh part with index %d.", i);
             SAFE_DELETE(meshData);
             return NULL;
         }
-        if (fread(&iByteCount, 4, 1, _file) != 1)
+        if (_stream->read(&iByteCount, 4, 1) != 1)
         {
             GP_ERROR("Failed to load index byte count for mesh part with index %d.", i);
             SAFE_DELETE(meshData);
@@ -1541,7 +1521,7 @@ Bundle::MeshData* Bundle::readMeshData()
         partData->indexCount = iByteCount / indexSize;
 
         partData->indexData = new unsigned char[iByteCount];
-        if (fread(partData->indexData, 1, iByteCount, _file) != iByteCount)
+        if (_stream->read(partData->indexData, 1, iByteCount) != iByteCount)
         {
             GP_ERROR("Failed to read index data for mesh part with index %d.", i);
             SAFE_DELETE(meshData);
@@ -1556,7 +1536,7 @@ Bundle::MeshData* Bundle::readMeshData(const char* url)
 {
     GP_ASSERT(url);
 
-    unsigned int len = strlen(url);
+    size_t len = strlen(url);
     if (len == 0)
     {
         GP_ERROR("Mesh data URL must be non-empty.");
@@ -1565,7 +1545,7 @@ Bundle::MeshData* Bundle::readMeshData(const char* url)
 
     // Parse URL (formatted as 'bundle#id').
     std::string urlstring(url);
-    unsigned int pos = urlstring.find('#');
+    size_t pos = urlstring.find('#');
     if (pos == std::string::npos)
     {
         GP_ERROR("Invalid mesh data URL '%s' (must be of the form 'bundle#id').", url);
@@ -1602,7 +1582,7 @@ Bundle::MeshData* Bundle::readMeshData(const char* url)
 Font* Bundle::loadFont(const char* id)
 {
     GP_ASSERT(id);
-    GP_ASSERT(_file);
+    GP_ASSERT(_stream);
 
     // Seek to the specified font.
     Reference* ref = seekTo(id, BUNDLE_TYPE_FONT);
@@ -1613,7 +1593,7 @@ Font* Bundle::loadFont(const char* id)
     }
 
     // Read font family.
-    std::string family = readString(_file);
+    std::string family = readString(_stream);
     if (family.empty())
     {
         GP_ERROR("Failed to read font family for font '%s'.", id);
@@ -1622,23 +1602,23 @@ Font* Bundle::loadFont(const char* id)
 
     // Read font style and size.
     unsigned int style, size;
-    if (fread(&style, 4, 1, _file) != 1)
+    if (_stream->read(&style, 4, 1) != 1)
     {
         GP_ERROR("Failed to read style for font '%s'.", id);
         return NULL;
     }
-    if (fread(&size, 4, 1, _file) != 1)
+    if (_stream->read(&size, 4, 1) != 1)
     {
         GP_ERROR("Failed to read size for font '%s'.", id);
         return NULL;
     }
 
     // Read character set.
-    std::string charset = readString(_file);
+    std::string charset = readString(_stream);
 
     // Read font glyphs.
     unsigned int glyphCount;
-    if (fread(&glyphCount, 4, 1, _file) != 1)
+    if (_stream->read(&glyphCount, 4, 1) != 1)
     {
         GP_ERROR("Failed to read glyph count for font '%s'.", id);
         return NULL;
@@ -1650,7 +1630,7 @@ Font* Bundle::loadFont(const char* id)
     }
 
     Font::Glyph* glyphs = new Font::Glyph[glyphCount];
-    if (fread(glyphs, sizeof(Font::Glyph), glyphCount, _file) != glyphCount)
+    if (_stream->read(glyphs, sizeof(Font::Glyph), glyphCount) != glyphCount)
     {
         GP_ERROR("Failed to read glyphs for font '%s'.", id);
         SAFE_DELETE_ARRAY(glyphs);
@@ -1659,19 +1639,19 @@ Font* Bundle::loadFont(const char* id)
 
     // Read texture attributes.
     unsigned int width, height, textureByteCount;
-    if (fread(&width, 4, 1, _file) != 1)
+    if (_stream->read(&width, 4, 1) != 1)
     {
         GP_ERROR("Failed to read texture width for font '%s'.", id);
         SAFE_DELETE_ARRAY(glyphs);
         return NULL;
     }
-    if (fread(&height, 4, 1, _file) != 1)
+    if (_stream->read(&height, 4, 1) != 1)
     {
         GP_ERROR("Failed to read texture height for font '%s'.", id);
         SAFE_DELETE_ARRAY(glyphs);
         return NULL;
     }
-    if (fread(&textureByteCount, 4, 1, _file) != 1)
+    if (_stream->read(&textureByteCount, 4, 1) != 1)
     {
         GP_ERROR("Failed to read texture byte count for font '%s'.", id);
         SAFE_DELETE_ARRAY(glyphs);
@@ -1686,7 +1666,7 @@ Font* Bundle::loadFont(const char* id)
 
     // Read texture data.
     unsigned char* textureData = new unsigned char[textureByteCount];
-    if (fread(textureData, 1, textureByteCount, _file) != textureByteCount)
+    if (_stream->read(textureData, 1, textureByteCount) != textureByteCount)
     {
         GP_ERROR("Failed to read texture data for font '%s'.", id);
         SAFE_DELETE_ARRAY(glyphs);

+ 1 - 1
gameplay/src/Bundle.h

@@ -429,7 +429,7 @@ private:
     std::string _path;
     unsigned int _referenceCount;
     Reference* _references;
-    FILE* _file;
+    Stream* _stream;
 
     std::vector<MeshSkinData*> _meshSkins;
     std::map<std::string, Node*>* _trackedNodes;

+ 20 - 4
gameplay/src/Button.cpp

@@ -1,10 +1,11 @@
 #include "Base.h"
 #include "Button.h"
+#include "Gamepad.h"
 
 namespace gameplay
 {
 
-Button::Button()
+Button::Button() : _dataBinding(0)
 {
 }
 
@@ -27,14 +28,19 @@ Button* Button::create(Theme::Style* style, Properties* properties)
     Button* button = new Button();
     button->initialize(style, properties);
 
+    // Different types of data bindings can be named differently in a button namespace.
+    // Gamepad button mappings have the name "mapping" and correspond to Gamepad::ButtonMapping enums.
+    const char* mapping = properties->getString("mapping");
+    if (mapping)
+    {
+        button->_dataBinding = Gamepad::getButtonMappingFromString(mapping);
+    }
+
     return button;
 }
 
 bool Button::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
 {
-    if (!isEnabled())
-        return false;
-
     switch (evt)
     {
     case Touch::TOUCH_PRESS:
@@ -92,4 +98,14 @@ const char* Button::getType() const
     return "button";
 }
 
+const unsigned int Button::getDataBinding() const
+{
+    return _dataBinding;
+}
+
+void Button::setDataBinding(unsigned int dataBinding)
+{
+    _dataBinding = dataBinding;
+}
+
 }

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff