فهرست منبع

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

Conflicts:
	gameplay/android/jni/Android.mk
	gameplay/gameplay.vcxproj
	gameplay/gameplay.xcodeproj/project.pbxproj
	gameplay/src/Platform.cpp
	gameplay/src/ScriptController.cpp
	gameplay/src/ScriptController.h
	gameplay/src/lua/lua_GamepadButtonMapping.cpp
	gameplay/src/lua/lua_GamepadGamepadEvent.cpp
	gameplay/src/lua/lua_Global.cpp
	gameplay/src/lua/lua_Global.h
	gameplay/src/lua/lua_Texture.cpp
	gameplay/src/lua/lua_TextureSampler.cpp
	template/android/jni/Android.mk
sgrenier 11 سال پیش
والد
کامیت
e0f3f43168
100فایلهای تغییر یافته به همراه3030 افزوده شده و 2296 حذف شده
  1. 14 5
      .gitignore
  2. 0 61
      build.xml
  3. 4 0
      gameplay/CMakeLists.txt
  4. 48 0
      gameplay/android/.project
  5. 2 2
      gameplay/android/AndroidManifest.xml
  6. 29 3
      gameplay/android/build.xml
  7. 80 4
      gameplay/android/jni/Android.mk
  8. 1 1
      gameplay/android/jni/Application.mk
  9. 2 2
      gameplay/android/project.properties
  10. 12 0
      gameplay/gameplay.vcxproj.filters
  11. 532 532
      gameplay/gameplay.xcodeproj/project.pbxproj
  12. 5 2
      gameplay/src/Base.h
  13. 2 2
      gameplay/src/Bundle.cpp
  14. 1 1
      gameplay/src/Camera.h
  15. 11 1
      gameplay/src/Control.cpp
  16. 19 5
      gameplay/src/Control.h
  17. 7 3
      gameplay/src/Effect.cpp
  18. 59 32
      gameplay/src/Form.cpp
  19. 17 3
      gameplay/src/Form.h
  20. 29 15
      gameplay/src/FrameBuffer.cpp
  21. 27 16
      gameplay/src/FrameBuffer.h
  22. 1 1
      gameplay/src/Game.cpp
  23. 2 1
      gameplay/src/Game.h
  24. 25 56
      gameplay/src/Gamepad.cpp
  25. 18 55
      gameplay/src/Gamepad.h
  26. 26 26
      gameplay/src/Image.cpp
  27. 5 5
      gameplay/src/Image.h
  28. 6 1
      gameplay/src/Material.cpp
  29. 31 17
      gameplay/src/Platform.cpp
  30. 28 7
      gameplay/src/Platform.h
  31. 443 300
      gameplay/src/PlatformAndroid.cpp
  32. 5 5
      gameplay/src/PlatformLinux.cpp
  33. 6 49
      gameplay/src/PlatformMacOSX.mm
  34. 9 12
      gameplay/src/PlatformWindows.cpp
  35. 14 10
      gameplay/src/PlatformiOS.mm
  36. 9 17
      gameplay/src/Slider.cpp
  37. 8 31
      gameplay/src/Slider.h
  38. 1 0
      gameplay/src/SpriteBatch.cpp
  39. 3 0
      gameplay/src/Terrain.cpp
  40. 7 0
      gameplay/src/TerrainPatch.cpp
  41. 396 114
      gameplay/src/Texture.cpp
  42. 52 7
      gameplay/src/Texture.h
  43. 114 32
      gameplay/src/lua/lua_FrameBuffer.cpp
  44. 4 112
      gameplay/src/lua/lua_Gamepad.cpp
  45. 1 4
      gameplay/src/lua/lua_Gamepad.h
  46. 23 9
      gameplay/src/lua/lua_Global.cpp
  47. 37 0
      gameplay/src/lua/lua_Joint.cpp
  48. 1 0
      gameplay/src/lua/lua_Joint.h
  49. 37 0
      gameplay/src/lua/lua_Node.cpp
  50. 1 0
      gameplay/src/lua/lua_Node.h
  51. 37 0
      gameplay/src/lua/lua_Scene.cpp
  52. 1 0
      gameplay/src/lua/lua_Scene.h
  53. 125 1
      gameplay/src/lua/lua_Texture.cpp
  54. 2 0
      gameplay/src/lua/lua_Texture.h
  55. 27 1
      gameplay/src/lua/lua_TextureSampler.cpp
  56. 127 0
      gameplay/src/org/gameplay3d/GameNativeActivity.java
  57. 38 52
      newproject.bat
  58. 43 55
      newproject.sh
  59. 3 0
      samples/browser/android/.cproject
  60. 49 1
      samples/browser/android/.project
  61. 4 4
      samples/browser/android/AndroidManifest.xml
  62. 32 5
      samples/browser/android/build.xml
  63. 7 6
      samples/browser/android/jni/Android.mk
  64. 1 1
      samples/browser/android/jni/Application.mk
  65. 2 1
      samples/browser/android/project.properties
  66. 0 75
      samples/browser/bar-descriptor.xml
  67. 4 4
      samples/browser/sample-browser.xcodeproj/project.pbxproj
  68. 12 21
      samples/browser/src/GamepadSample.cpp
  69. 17 16
      samples/browser/src/GestureSample.cpp
  70. 4 4
      samples/character/android/AndroidManifest.xml
  71. 33 6
      samples/character/android/build.xml
  72. 7 8
      samples/character/android/jni/Android.mk
  73. 1 1
      samples/character/android/jni/Application.mk
  74. 2 1
      samples/character/android/project.properties
  75. 0 117
      samples/character/bar-descriptor.xml
  76. 4 4
      samples/character/sample-character.xcodeproj/project.pbxproj
  77. 3 3
      samples/lua/android/AndroidManifest.xml
  78. 33 6
      samples/lua/android/build.xml
  79. 7 8
      samples/lua/android/jni/Android.mk
  80. 1 1
      samples/lua/android/jni/Application.mk
  81. 2 1
      samples/lua/android/project.properties
  82. 0 90
      samples/lua/bar-descriptor.xml
  83. 4 4
      samples/lua/sample-lua.xcodeproj/project.pbxproj
  84. 48 0
      samples/mesh/android/.project
  85. 3 3
      samples/mesh/android/AndroidManifest.xml
  86. 35 8
      samples/mesh/android/build.xml
  87. 7 8
      samples/mesh/android/jni/Android.mk
  88. 1 1
      samples/mesh/android/jni/Application.mk
  89. 2 1
      samples/mesh/android/project.properties
  90. 0 88
      samples/mesh/bar-descriptor.xml
  91. 4 4
      samples/mesh/sample-mesh.xcodeproj/project.pbxproj
  92. 3 3
      samples/particles/android/AndroidManifest.xml
  93. 33 6
      samples/particles/android/build.xml
  94. 7 8
      samples/particles/android/jni/Android.mk
  95. 1 1
      samples/particles/android/jni/Application.mk
  96. 2 1
      samples/particles/android/project.properties
  97. 0 93
      samples/particles/bar-descriptor.xml
  98. 4 4
      samples/particles/sample-particles.xcodeproj/project.pbxproj
  99. 3 3
      samples/racer/android/AndroidManifest.xml
  100. 31 6
      samples/racer/android/build.xml

+ 14 - 5
.gitignore

@@ -81,6 +81,7 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/browser/res/shaders
 /samples/browser/res/ui
 /samples/browser/res/logo_powered_white.png
+/samples/browser/src/org
 /samples/browser/android/src
 /samples/browser/android/assets
 /samples/browser/android/bin
@@ -108,9 +109,7 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/character/res/shaders
 /samples/character/res/ui
 /samples/character/res/logo_powered_white.png
-/samples/character/android/proguard-project.txt
-/samples/character/android/proguard.cfg
-/samples/character/android/local.properties
+/samples/character/src/org
 /samples/character/android/src
 /samples/character/android/assets
 /samples/character/android/bin
@@ -118,6 +117,9 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/character/android/libs
 /samples/character/android/obj
 /samples/character/android/NUL
+/samples/character/android/local.properties
+/samples/character/android/proguard-project.txt
+/samples/character/android/proguard.cfg
 /samples/character/res/gamepad.xcf
 /samples/character/sample-character.xcodeproj/xcuserdata
 
@@ -134,6 +136,7 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/lua/res/shaders
 /samples/lua/res/ui
 /samples/lua/res/logo_powered_white.png
+/samples/lua/src/org
 /samples/lua/android/src
 /samples/lua/android/assets
 /samples/lua/android/bin
@@ -144,6 +147,7 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/lua/android/local.properties
 /samples/lua/android/proguard-project.txt
 /samples/lua/android/proguard.cfg
+/samples/lua/android/src/org/gameplay3d
 /samples/lua/sample-lua.xcodeproj/xcuserdata
 
 /samples/mesh/Debug
@@ -159,6 +163,7 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/mesh/res/shaders
 /samples/mesh/res/ui
 /samples/mesh/res/logo_powered_white.png
+/samples/mesh/src/org
 /samples/mesh/android/src
 /samples/mesh/android/assets
 /samples/mesh/android/bin
@@ -187,12 +192,14 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/particles/Device-Debug
 /samples/particles/Debug
 /samples/particles/DebugMem
+/samples/particles/src/org
 /samples/particles/android/src
 /samples/particles/android/assets
 /samples/particles/android/bin
 /samples/particles/android/gen
 /samples/particles/android/libs
 /samples/particles/android/obj
+/samples/particles/android/NUL
 /samples/particles/android/local.properties
 /samples/particles/android/proguard-project.txt
 /samples/particles/android/proguard.cfg
@@ -214,6 +221,7 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/racer/res/shaders
 /samples/racer/res/ui
 /samples/racer/res/logo_powered_white.png
+/samples/racer/src/org
 /samples/racer/android/src
 /samples/racer/android/assets
 /samples/racer/android/bin
@@ -239,13 +247,14 @@ gameplay.xcworkspace/xcshareddata/gameplay.xccheckout
 /samples/spaceship/res/shaders
 /samples/spaceship/res/ui
 /samples/spaceship/res/logo_powered_white.png
-/samples/spaceship/android/NUL
+/samples/spaceship/src/org
+/samples/spaceship/android/src
 /samples/spaceship/android/assets
 /samples/spaceship/android/bin
 /samples/spaceship/android/gen
 /samples/spaceship/android/libs
 /samples/spaceship/android/obj
-/samples/spaceship/android/src
+/samples/spaceship/android/NUL
 /samples/spaceship/android/local.properties
 /samples/spaceship/android/proguard.cfg
 /samples/spaceship/android/proguard-project.txt

+ 0 - 61
build.xml

@@ -1,61 +0,0 @@
-<!-- Android build script -->
-<project name="gameplay" default="build" basedir=".">
-
-  <fail message="OS not supported. Supported platforms: Windows, MacOS X or Linux.">
-    <condition>
-      <not>
-        <or>
-          <os family="unix"/>
-          <os family="windows"/>
-        </or>
-      </not>
-    </condition>
-  </fail>
-
-  <macrodef name="build-native">
-    <attribute name="location"/>
-    <sequential>
-
-      <exec osfamily="unix" dir="@{location}/android" executable="android">
-        <arg value="update"/>
-        <arg value="project"/>
-        <arg value="-t"/>
-        <arg value="1"/>
-        <arg value="-p"/>
-        <arg value="."/>
-        <arg value="-s"/>
-      </exec>
-      <exec osfamily="unix" dir="@{location}/android" executable="ndk-build"/>
-
-      <exec osfamily="windows" dir="@{location}/android" executable="cmd">
-        <arg value="/c"/>
-        <arg value="android.bat"/>
-        <arg value="update"/>
-        <arg value="project"/>
-        <arg value="-t"/>
-        <arg value="1"/>
-        <arg value="-p"/>
-        <arg value="."/>
-        <arg value="-s"/>
-      </exec>
-      <exec osfamily="windows" dir="@{location}/android" executable="cmd">
-        <arg value="/c"/>
-        <arg value="ndk-build"/>
-      </exec> 
-      
-    </sequential>
-  </macrodef>
-
-    
-  <target name="build">
-    <build-native location="gameplay"/>
-    <build-native location="samples/browser"/>
-    <build-native location="samples/character"/>
-    <build-native location="samples/lua"/>
-    <build-native location="samples/mesh"/>
-    <build-native location="samples/particles"/>
-    <build-native location="samples/racer"/>
-    <build-native location="samples/spaceship"/>
-  </target>
-  
-</project>

+ 4 - 0
gameplay/CMakeLists.txt

@@ -539,12 +539,16 @@ set(GAMEPLAY_LUA
     src/lua/lua_TextBoxInputMode.h
     src/lua/lua_Texture.cpp
     src/lua/lua_Texture.h
+    src/lua/lua_TextureCubeFace.cpp
+    src/lua/lua_TextureCubeFace.h
     src/lua/lua_TextureFilter.cpp
     src/lua/lua_TextureFilter.h
     src/lua/lua_TextureFormat.cpp
     src/lua/lua_TextureFormat.h
     src/lua/lua_TextureSampler.cpp
     src/lua/lua_TextureSampler.h
+    src/lua/lua_TextureType.cpp
+    src/lua/lua_TextureType.h
     src/lua/lua_TextureWrap.cpp
     src/lua/lua_TextureWrap.h
     src/lua/lua_Theme.cpp

+ 48 - 0
gameplay/android/.project

@@ -9,6 +9,54 @@
 			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
 			<triggers>clean,full,incremental,</triggers>
 			<arguments>
+				<dictionary>
+					<key>?children?</key>
+					<value>?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\||</value>
+				</dictionary>
+				<dictionary>
+					<key>?name?</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.append_environment</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildArguments</key>
+					<value>NDK_DEBUG=1 -j4</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildCommand</key>
+					<value>ndk-build</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+					<value>clean</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.contents</key>
+					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.stopOnError</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+					<value>false</value>
+				</dictionary>
 			</arguments>
 		</buildCommand>
 		<buildCommand>

+ 2 - 2
gameplay/android/AndroidManifest.xml

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
-	package="org.gameplay3d.gameplay" 
+	package="org.gameplay3d" 
 	android:versionCode="1" 
 	android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="15" />
+    <uses-sdk android:minSdkVersion="16" />
 
 </manifest>

+ 29 - 3
gameplay/android/build.xml

@@ -3,11 +3,37 @@
 
     <property file="local.properties" />
     <property file="ant.properties" />
-    
+   
     <loadproperties srcFile="project.properties" />
     
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'" unless="sdk.dir" />
-
+    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project -t 1 -p . -s'" unless="sdk.dir" />
+    <fail message="OS not supported. Supported platforms: Windows, MacOS X or Linux.">
+        <condition>
+            <not>
+                <or>
+                    <os family="unix"/>
+                    <os family="windows"/>
+                </or>
+            </not>
+        </condition>
+    </fail>
+    <macrodef name="build-native">
+        <attribute name="location"/>
+        <sequential>
+            <exec osfamily="unix" dir="@{location}/android" executable="ndk-build">
+                <arg value="-j4"/>
+            </exec>
+            <exec osfamily="windows" dir="@{location}/android" executable="cmd">
+                <arg value="/c"/>
+                <arg value="ndk-build -j4"/>
+            </exec> 
+        </sequential>
+    </macrodef>
+    
+    <target name="-pre-build">
+        <build-native location=".."/>
+    </target>
+    
     <!-- version-tag: 1 -->
     <import file="${sdk.dir}/tools/ant/build.xml" />
 

+ 80 - 4
gameplay/android/jni/Android.mk

@@ -1,7 +1,81 @@
 
-LOCAL_PATH := $(call my-dir)/../../src
+GAMEPLAY_PATH := $(call my-dir)/../../src
 
+# external-deps
+PNG_PATH := ../../external-deps/png/lib/android/arm
+ZLIB_PATH := ../../external-deps/zlib/lib/android/arm
+LUA_PATH := ../../external-deps/lua/lib/android/arm
+BULLET_PATH := ../../external-deps/bullet/lib/android/arm
+OGG_PATH := ../../external-deps/ogg/lib/android/arm
+VORBIS_PATH := ../../external-deps/vorbis/lib/android/arm
+OPENAL_PATH := ../../external-deps/openal/lib/android/arm
+
+# libpng
+LOCAL_PATH := $(PNG_PATH)
+include $(CLEAR_VARS)
+LOCAL_MODULE    := libpng 
+LOCAL_SRC_FILES := libpng.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# libz
+LOCAL_PATH := $(ZLIB_PATH)
+include $(CLEAR_VARS)
+LOCAL_MODULE    := libz
+LOCAL_SRC_FILES := libz.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# liblua
+LOCAL_PATH := $(LUA_PATH)
+include $(CLEAR_VARS)
+LOCAL_MODULE    := liblua
+LOCAL_SRC_FILES := liblua.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# libLinearMath
+LOCAL_PATH := $(BULLET_PATH)
+include $(CLEAR_VARS)
+LOCAL_MODULE    := libLinearMath
+LOCAL_SRC_FILES := libLinearMath.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# libBulletCollision
+LOCAL_PATH := $(BULLET_PATH)
+include $(CLEAR_VARS)
+LOCAL_MODULE    := libBulletCollision
+LOCAL_SRC_FILES := libBulletCollision.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# libBulletDynamics
+LOCAL_PATH := $(BULLET_PATH)
 include $(CLEAR_VARS)
+LOCAL_MODULE    := libBulletDynamics
+LOCAL_SRC_FILES := libBulletDynamics.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# libogg
+LOCAL_PATH := $(OGG_PATH)
+include $(CLEAR_VARS)
+LOCAL_MODULE    := libogg
+LOCAL_SRC_FILES := libogg.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# libvorbis
+LOCAL_PATH := $(VORBIS_PATH)
+include $(CLEAR_VARS)
+LOCAL_MODULE    := libvorbis
+LOCAL_SRC_FILES := libvorbis.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# libOpenAL
+LOCAL_PATH := $(OPENAL_PATH)
+include $(CLEAR_VARS)
+LOCAL_MODULE    := libOpenAL
+LOCAL_SRC_FILES := libOpenAL.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+# libgameplay
+include $(CLEAR_VARS)
+LOCAL_PATH := $(GAMEPLAY_PATH)
 LOCAL_MODULE    := libgameplay
 LOCAL_SRC_FILES := \
     AbsoluteLayout.cpp \
@@ -241,9 +315,11 @@ LOCAL_SRC_FILES := \
 
 LOCAL_CPPFLAGS += -std=c++11 -Wno-switch-enum -Wno-switch
 LOCAL_ARM_MODE := arm
+LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv2 -lOpenSLES
 LOCAL_CFLAGS := -D__ANDROID__ -I"../../external-deps/lua/include" -I"../../external-deps/bullet/include" -I"../../external-deps/png/include" -I"../../external-deps/ogg/include" -I"../../external-deps/vorbis/include" -I"../../external-deps/openal/include"
-LOCAL_STATIC_LIBRARIES := android_native_app_glue
-
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_ADDITIONAL_DEPENDENCIES := gameplay
+LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
+include $(BUILD_SHARED_LIBRARY)
 
 $(call import-module,android/native_app_glue)
+

+ 1 - 1
gameplay/android/jni/Application.mk

@@ -3,5 +3,5 @@ APP_CPPFLAGS += -std=c++11
 APP_STL      := gnustl_static
 APP_MODULES  := libgameplay
 APP_ABI      := armeabi-v7a
-APP_PLATFORM := android-14
+APP_PLATFORM := android-16
 

+ 2 - 2
gameplay/android/project.properties

@@ -1,3 +1,3 @@
-target=android-20
+target=android-16
 android.library=true
-
+source.dir=../src

+ 12 - 0
gameplay/gameplay.vcxproj.filters

@@ -738,6 +738,12 @@
     <ClCompile Include="src\lua\lua_ScriptTargetEventRegistry.cpp">
       <Filter>src\lua</Filter>
     </ClCompile>
+    <ClCompile Include="src\lua\lua_TextureCubeFace.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_TextureType.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Plane.h">
@@ -1463,6 +1469,12 @@
     <ClInclude Include="src\lua\lua_ScriptTargetEventRegistry.h">
       <Filter>src\lua</Filter>
     </ClInclude>
+    <ClInclude Include="src\lua\lua_TextureCubeFace.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_TextureType.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="src\ScriptController.inl">

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 532 - 532
gameplay/gameplay.xcodeproj/project.pbxproj


+ 5 - 2
gameplay/src/Base.h

@@ -278,9 +278,12 @@ typedef GLuint FrameBufferHandle;
 /** Render buffer handle. */
 typedef GLuint RenderBufferHandle;
 
-/** Gamepad handle definitions vary by platform. */
+/** Gamepad handle */
+#ifdef __ANDROID__
+typedef unsigned int GamepadHandle;
+#else
 typedef unsigned long GamepadHandle;
-
+#endif
 }
 
 /**

+ 2 - 2
gameplay/src/Bundle.cpp

@@ -1869,7 +1869,7 @@ Bundle::Reference::~Reference()
 }
 
 Bundle::MeshPartData::MeshPartData() :
-    indexCount(0), indexData(NULL)
+		primitiveType(Mesh::TRIANGLES), indexFormat(Mesh::INDEX32), indexCount(0), indexData(NULL)
 {
 }
 
@@ -1879,7 +1879,7 @@ Bundle::MeshPartData::~MeshPartData()
 }
 
 Bundle::MeshData::MeshData(const VertexFormat& vertexFormat)
-    : vertexFormat(vertexFormat), vertexCount(0), vertexData(NULL)
+    : vertexFormat(vertexFormat), vertexCount(0), vertexData(NULL), primitiveType(Mesh::TRIANGLES)
 {
 }
 

+ 1 - 1
gameplay/src/Camera.h

@@ -51,7 +51,7 @@ public:
     /**
      * Creates a perspective camera.
      *
-     * @param fieldOfView The field of view for the perspective camera (normally in the range of 40-60 degrees).
+     * @param fieldOfView The field of view in degrees for the perspective camera (normally in the range of 40-60 degrees).
      * @param aspectRatio The aspect ratio of the camera (normally the width of the viewport divided by the height of the viewport).
      * @param nearPlane The near plane distance.
      * @param farPlane The far plane distance.

+ 11 - 1
gameplay/src/Control.cpp

@@ -1083,7 +1083,17 @@ bool Control::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
     return false;
 }
 
-bool Control::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
+bool Control::gamepadButtonEvent(Gamepad* gamepad)
+{
+    return false;
+}
+
+bool Control::gamepadTriggerEvent(Gamepad* gamepad, unsigned int index)
+{
+    return false;
+}
+
+bool Control::gamepadJoystickEvent(Gamepad* gamepad, unsigned int index)
 {
     return false;
 }

+ 19 - 5
gameplay/src/Control.h

@@ -1103,13 +1103,27 @@ protected:
     virtual bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
 
     /**
-     * Gamepad callback on gamepad events.
+     * Gamepad callback on gamepad button changes.
      *
-     * @param gamepad The gamepad whose state changed.
-     * @param evt The gamepad event that occurred.
-     * @param analogIndex If evt is JOYSTICK_EVENT or TRIGGER_EVENT, this will be the index of the corresponding control.
+     * @param gamepad The gamepad whose one or more buttons have changed.
      */
-    virtual bool gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex);
+    virtual bool gamepadButtonEvent(Gamepad* gamepad);
+
+    /**
+     * Gamepad callback on gamepad trigger changes.
+     *
+     * @param gamepad The gamepad whose one or more buttons have changed.
+     * @param index The index of the trigger that changed. 
+     */
+    virtual bool gamepadTriggerEvent(Gamepad* gamepad, unsigned int index);
+
+    /**
+     * Gamepad callback on gamepad analog joystick changes.
+     *
+     * @param gamepad The gamepad whose one or more buttons have changed.
+     * @param index The index of the joystick that changed.
+     */
+    virtual bool gamepadJoystickEvent(Gamepad* gamepad, unsigned int index);
 
     /**
      * Called each frame to update this control and its children.

+ 7 - 3
gameplay/src/Effect.cpp

@@ -439,7 +439,7 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
                 uniform->_name = uniformName;
                 uniform->_location = uniformLocation;
                 uniform->_type = uniformType;
-                if (uniformType == GL_SAMPLER_2D)
+                if (uniformType == GL_SAMPLER_2D || uniformType == GL_SAMPLER_CUBE)
                 {
                     uniform->_index = samplerIndex;
                     samplerIndex += uniformSize;
@@ -608,8 +608,10 @@ void Effect::setValue(Uniform* uniform, const Vector4* values, unsigned int coun
 void Effect::setValue(Uniform* uniform, const Texture::Sampler* sampler)
 {
     GP_ASSERT(uniform);
-    GP_ASSERT(uniform->_type == GL_SAMPLER_2D);
+    GP_ASSERT(uniform->_type == GL_SAMPLER_2D || uniform->_type == GL_SAMPLER_CUBE);
     GP_ASSERT(sampler);
+    GP_ASSERT((sampler->getTexture()->getType() == Texture::TEXTURE_2D && uniform->_type == GL_SAMPLER_2D) || 
+        (sampler->getTexture()->getType() == Texture::TEXTURE_CUBE && uniform->_type == GL_SAMPLER_CUBE));
 
     GL_ASSERT( glActiveTexture(GL_TEXTURE0 + uniform->_index) );
 
@@ -622,13 +624,15 @@ void Effect::setValue(Uniform* uniform, const Texture::Sampler* sampler)
 void Effect::setValue(Uniform* uniform, const Texture::Sampler** values, unsigned int count)
 {
     GP_ASSERT(uniform);
-    GP_ASSERT(uniform->_type == GL_SAMPLER_2D);
+    GP_ASSERT(uniform->_type == GL_SAMPLER_2D || uniform->_type == GL_SAMPLER_CUBE);
     GP_ASSERT(values);
 
     // Set samplers as active and load texture unit array
     GLint units[32];
     for (unsigned int i = 0; i < count; ++i)
     {
+        GP_ASSERT((const_cast<Texture::Sampler*>(values[i])->getTexture()->getType() == Texture::TEXTURE_2D && uniform->_type == GL_SAMPLER_2D) || 
+            (const_cast<Texture::Sampler*>(values[i])->getTexture()->getType() == Texture::TEXTURE_CUBE && uniform->_type == GL_SAMPLER_CUBE));
         GL_ASSERT( glActiveTexture(GL_TEXTURE0 + uniform->_index + i) );
 
         // Bind the sampler - this binds the texture and applies sampler state

+ 59 - 32
gameplay/src/Form.cpp

@@ -10,8 +10,8 @@
 #include "CheckBox.h"
 #include "Scene.h"
 
-// Scroll speed when using a DPad -- max scroll speed when using a joystick.
-static const float GAMEPAD_SCROLL_SPEED = 500.0f;
+// Scroll speed when using a joystick.
+static const float GAMEPAD_SCROLL_SPEED = 600.0f;
 // Distance a joystick must be pushed in order to trigger focus-change and/or scrolling.
 static const float JOYSTICK_THRESHOLD = 0.75f;
 // If the DPad or joystick is held down, this is the initial delay in milliseconds between focus changes.
@@ -902,7 +902,7 @@ bool Form::pollGamepad(Gamepad* gamepad)
     return focusPressed || scrolling;
 }
 
-bool Form::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
+bool Form::gamepadButtonEventInternal(Gamepad* gamepad)
 {
     if (!__focusControl)
         return false;
@@ -910,56 +910,83 @@ bool Form::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, uns
     bool selectButtonPressed = gamepad->isButtonDown(Gamepad::BUTTON_A) || gamepad->isButtonDown(Gamepad::BUTTON_X);
 
     // Fire press, release and click events to focused controls
-    switch (evt)
+    if (selectButtonPressed && __focusControl->_state != ACTIVE)
     {
-    case Gamepad::BUTTON_EVENT:
-        if (selectButtonPressed && __focusControl->_state != ACTIVE)
-        {
-            if (__activeControl[0])
-                __activeControl[0]->setDirty(DIRTY_STATE);
+        if (__activeControl[0])
+            __activeControl[0]->setDirty(DIRTY_STATE);
 
-            __activeControl[0] = __focusControl;
-            __focusControl->_state = ACTIVE;
-            __focusControl->notifyListeners(Control::Listener::PRESS);
-            return true;
-        }
-        else if (!selectButtonPressed && __focusControl->_state == ACTIVE)
-        {
-            if (__activeControl[0])
-                __activeControl[0]->setDirty(DIRTY_STATE);
+        __activeControl[0] = __focusControl;
+        __focusControl->_state = ACTIVE;
+        __focusControl->notifyListeners(Control::Listener::PRESS);
+        return true;
+    }
+    else if (!selectButtonPressed && __focusControl->_state == ACTIVE)
+    {
+        if (__activeControl[0])
+            __activeControl[0]->setDirty(DIRTY_STATE);
 
-            for (unsigned int i = 0; i < Touch::MAX_TOUCH_POINTS; ++i)
+        for (unsigned int i = 0; i < Touch::MAX_TOUCH_POINTS; ++i)
+        {
+            if (__activeControl[i] == __focusControl)
             {
-                if (__activeControl[i] == __focusControl)
-                {
-                    __activeControl[i] = NULL;
-                }
+                __activeControl[i] = NULL;
             }
-
-            __focusControl->_state = NORMAL;
-            __focusControl->notifyListeners(Control::Listener::RELEASE);
-            __focusControl->notifyListeners(Control::Listener::CLICK);
-            return true;
         }
-        break;
+
+        __focusControl->_state = NORMAL;
+        __focusControl->notifyListeners(Control::Listener::RELEASE);
+        __focusControl->notifyListeners(Control::Listener::CLICK);
+        return true;
     }
 
-    // Dispatch gamepad events to focused controls (or their parents)
-    Control * ctrl = __focusControl;
+    // Dispatch gamepad button events to focused controls (or their parents)
+    Control* ctrl = __focusControl;
     while (ctrl)
     {
         if (ctrl->isEnabled() && ctrl->isVisible())
         {
-            if (ctrl->gamepadEvent(evt, gamepad, analogIndex))
+            if (ctrl->gamepadButtonEvent(gamepad))
                 return true;
         }
 
         ctrl = ctrl->getParent();
     }
+    return false;
+}
+
+bool Form::gamepadTriggerEventInternal(Gamepad* gamepad, unsigned int index)
+{
+    // Dispatch gamepad trigger events to focused controls (or their parents)
+    Control* ctrl = __focusControl;
+    while (ctrl)
+    {
+        if (ctrl->isEnabled() && ctrl->isVisible())
+        {
+            if (ctrl->gamepadTriggerEvent(gamepad, index))
+                return true;
+        }
 
+        ctrl = ctrl->getParent();
+    }
     return false;
 }
 
+bool Form::gamepadJoystickEventInternal(Gamepad* gamepad, unsigned int index)
+{
+    // Dispatch gamepad joystick events to focused controls (or their parents)
+    Control* ctrl = __focusControl;
+    while (ctrl)
+    {
+        if (ctrl->isEnabled() && ctrl->isVisible())
+        {
+            if (ctrl->gamepadJoystickEvent(gamepad, index))
+                return true;
+        }
+
+        ctrl = ctrl->getParent();
+    }
+    return false;
+}
 void Form::resizeEventInternal(unsigned int width, unsigned int height)
 {
     for (size_t i = 0, size = __forms.size(); i < size; ++i)

+ 17 - 3
gameplay/src/Form.h

@@ -206,11 +206,25 @@ private:
     static bool mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
 
     /**
-     * Propagate gamepad events to enabled forms.
+     * Propagate gamepad button events to enabled forms.
      *
-     * @see Control::gamepadEvent
+     * @see Control::gamepadButtonEventInternal
      */
-    static bool gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex);
+    static bool gamepadButtonEventInternal(Gamepad* gamepad);
+
+    /**
+     * Propagate gamepad trigger events to enabled forms.
+     *
+     * @see Control::gamepadTriggerEventInternal
+     */
+    static bool gamepadTriggerEventInternal(Gamepad* gamepad, unsigned int index);
+
+    /**
+     * Propagate gamepad button events to enabled forms.
+     *
+     * @see Control::gamepadJoystickEventInternal
+     */
+    static bool gamepadJoystickEventInternal(Gamepad* gamepad, unsigned int index);
 
     /**
      * Fired by the platform when the game window resizes.

+ 29 - 15
gameplay/src/FrameBuffer.cpp

@@ -155,13 +155,28 @@ unsigned int FrameBuffer::getMaxRenderTargets()
 
 void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 {
-    GP_ASSERT(index < _maxRenderTargets);
-    GP_ASSERT(_renderTargets);
+    GP_ASSERT(!target || (target->getTexture() && target->getTexture()->getType() == Texture::TEXTURE_2D));
 
     // No change
     if (_renderTargets[index] == target)
         return;
 
+    setRenderTarget(target, index, GL_TEXTURE_2D);
+}
+
+void FrameBuffer::setRenderTarget(RenderTarget* target, Texture::CubeFace face, unsigned int index)
+{
+    GP_ASSERT(face >= Texture::POSITIVE_X && face <= Texture::NEGATIVE_Z);
+    GP_ASSERT(!target || (target->getTexture() && target->getTexture()->getType() == Texture::TEXTURE_CUBE));
+
+    setRenderTarget(target, index, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face);
+}
+
+void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index, GLenum textureTarget)
+{
+    GP_ASSERT(index < _maxRenderTargets);
+    GP_ASSERT(_renderTargets);
+
     // Release our reference to the current RenderTarget at this index.
     if (_renderTargets[index])
     {
@@ -173,8 +188,6 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 
     if (target)
     {
-        GP_ASSERT( _renderTargets[index]->getTexture() );
-
         ++_renderTargetCount;
 
         // This FrameBuffer now references the RenderTarget.
@@ -183,7 +196,7 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
         // Now set this target as the color attachment corresponding to index.
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
         GLenum attachment = GL_COLOR_ATTACHMENT0 + index;
-        GL_ASSERT( glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, _renderTargets[index]->getTexture()->getHandle(), 0) );
+        GL_ASSERT( glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, textureTarget, _renderTargets[index]->getTexture()->getHandle(), 0) );
         GLenum fboStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
         if (fboStatus != GL_FRAMEBUFFER_COMPLETE)
         {
@@ -271,22 +284,23 @@ FrameBuffer* FrameBuffer::bind()
 
 void FrameBuffer::getScreenshot(Image* image)
 {
-	GP_ASSERT(image);
-	GP_ASSERT(image->getFormat() == Image::RGBA);
+    GP_ASSERT( image );
 
-	unsigned int width = _currentFrameBuffer->getWidth();
-	unsigned int height = _currentFrameBuffer->getHeight();
+    unsigned int width = _currentFrameBuffer->getWidth();
+    unsigned int height = _currentFrameBuffer->getHeight();
 
-	if (image->getWidth() == width && image->getHeight() == height)
-		GL_ASSERT( glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, image->getData()) );
+	if (image->getWidth() == width && image->getHeight() == height) {
+		GLenum format = image->getFormat() == Image::RGB ? GL_RGB : GL_RGBA;
+        GL_ASSERT( glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, image->getData()) );
+	}
 }
 
-Image* FrameBuffer::createScreenshot()
+Image* FrameBuffer::createScreenshot(Image::Format format)
 {
-	Image* screenshot = Image::create(_currentFrameBuffer->getWidth(), _currentFrameBuffer->getHeight(), Image::RGBA, NULL);
-	getScreenshot(screenshot);
+    Image* screenshot = Image::create(_currentFrameBuffer->getWidth(), _currentFrameBuffer->getHeight(), format, NULL);
+    getScreenshot(screenshot);
 
-	return screenshot;
+    return screenshot;
 }
 
 FrameBuffer* FrameBuffer::bindDefault()

+ 27 - 16
gameplay/src/FrameBuffer.h

@@ -101,11 +101,20 @@ public:
     /**
      * Set a RenderTarget on this FrameBuffer's color attachment at the specified index.
      *
-     * @param target The RenderTarget to set.
+     * @param target The 2D RenderTarget to set.
      * @param index The index of the color attachment to set.
      */
     void setRenderTarget(RenderTarget* target, unsigned int index = 0);
 
+    /**
+    * Set a RenderTarget on this FrameBuffer's color attachment at the specified index.
+    *
+    * @param target The Cubemap RenderTarget to set.
+    * @param face The face of the cubemap to target.
+    * @param index The index of the color attachment to set.
+    */
+    void setRenderTarget(RenderTarget* target, Texture::CubeFace face, unsigned int index = 0);
+
     /**
      * Get the RenderTarget attached to the FrameBuffer's color attachment at the specified index.
      *
@@ -152,22 +161,22 @@ public:
      */
     FrameBuffer* bind();
 
-	/**
-	 * Records a screenshot of what is stored on the current FrameBuffer.
-	 *
-	 * @return A screenshot of the current framebuffer's content.
-	 */
-	static Image* createScreenshot();
+    /**
+     * Records a screenshot of what is stored on the current FrameBuffer.
+     *
+     * @param format The format the Image should be in.
+     * @return A screenshot of the current framebuffer's content.
+     */
+    static Image* createScreenshot(Image::Format format = Image::RGBA);
 
-	/**
-	 * Records a screenshot of what is stored on the current FrameBuffer to an Image.
-	 *
-	 * The Image must be the same size as the FrameBuffer, otherwise the operation will fail.
-	 * The Image must be format RGBA.
-	 *
-	 * @param image The Image to write the current framebuffer's content to.
-	 */
-	static void getScreenshot(Image* image);
+    /**
+     * Records a screenshot of what is stored on the current FrameBuffer to an Image.
+     *
+     * The Image must be the same size as the FrameBuffer, otherwise the operation will fail.
+     *
+     * @param image The Image to write the current framebuffer's content to.
+     */
+    static void getScreenshot(Image* image);
 
     /**
      * Binds the default FrameBuffer for rendering to the display.
@@ -200,6 +209,8 @@ private:
      */
     FrameBuffer& operator=(const FrameBuffer&);
 
+    void setRenderTarget(RenderTarget* target, unsigned int index, GLenum textureTarget);
+
     static void initialize();
 
     static void finalize();

+ 1 - 1
gameplay/src/Game.cpp

@@ -696,7 +696,7 @@ void Game::gestureDropEventInternal(int x, int y)
         _scriptTarget->fireScriptEvent<void>(GP_GET_SCRIPT_EVENT(GameScriptTarget, gestureDropEvent), x, y);
 }
 
-void Game::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
+void Game::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad)
 {
     gamepadEvent(evt, gamepad);
     if (_scriptTarget)

+ 2 - 1
gameplay/src/Game.h

@@ -31,6 +31,7 @@ class ScriptController;
 class Game
 {
     friend class Platform;
+    friend class Gamepad;
     friend class ShutdownListener;
 
 public:
@@ -740,7 +741,7 @@ private:
     void gestureLongTapEventInternal(int x, int y, float duration);
     void gestureDragEventInternal(int x, int y);
     void gestureDropEventInternal(int x, int y);
-    void gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex);
+    void gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad);
 
     bool _initialized;                          // If game has initialized yet.
     State _state;                               // The game state.

+ 25 - 56
gameplay/src/Gamepad.cpp

@@ -12,15 +12,13 @@ namespace gameplay
 static std::vector<Gamepad*> __gamepads;
 
 Gamepad::Gamepad(const char* formPath)
-    : _handle((GamepadHandle)INT_MAX), _buttonCount(0), _joystickCount(0), _triggerCount(0), _vendorId(0), _productId(0),
-      _form(NULL), _buttons(0)
+    : _handle((GamepadHandle)INT_MAX), _buttonCount(0), _joystickCount(0), _triggerCount(0), _form(NULL), _buttons(0)
 {
     GP_ASSERT(formPath);
     _form = Form::create(formPath);
     GP_ASSERT(_form);
     _form->setConsumeInputEvents(false);
-    _vendorString = "None";
-    _productString = "Virtual";
+    _name = "Virtual";
 
     for (int i = 0; i < 2; ++i)
     {
@@ -36,19 +34,13 @@ Gamepad::Gamepad(const char* formPath)
     bindGamepadControls(_form);
 }
 
-Gamepad::Gamepad(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
-                 unsigned int vendorId, unsigned int productId, const char* vendorString, const char* productString)
+Gamepad::Gamepad(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount, const char* name)
     : _handle(handle), _buttonCount(buttonCount), _joystickCount(joystickCount), _triggerCount(triggerCount),
-      _vendorId(vendorId), _productId(productId), _form(NULL), _buttons(0)
+      _form(NULL), _buttons(0)
 {
-    if (vendorString)
-    {
-        _vendorString = vendorString;
-    }
-    
-    if (productString)
+    if (name)
     {
-        _productString = productString;
+        _name = name;
     }
 
     for (int i = 0; i < 2; ++i)
@@ -65,14 +57,12 @@ Gamepad::~Gamepad()
     }
 }
 
-Gamepad* Gamepad::add(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
-                      unsigned int vendorId, unsigned int productId, 
-                      const char* vendorString, const char* productString)
+Gamepad* Gamepad::add(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount, const char* name)
 {
-    Gamepad* gamepad = new Gamepad(handle, buttonCount, joystickCount, triggerCount, vendorId, productId, vendorString, productString);
+    Gamepad* gamepad = new Gamepad(handle, buttonCount, joystickCount, triggerCount, name);
 
     __gamepads.push_back(gamepad);
-    Game::getInstance()->gamepadEvent(CONNECTED_EVENT, gamepad);
+    Game::getInstance()->gamepadEventInternal(CONNECTED_EVENT, gamepad);
     return gamepad;
 }
 
@@ -81,7 +71,7 @@ Gamepad* Gamepad::add(const char* formPath)
     Gamepad* gamepad = new Gamepad(formPath);
 
     __gamepads.push_back(gamepad);
-    Game::getInstance()->gamepadEvent(CONNECTED_EVENT, gamepad);
+    Game::getInstance()->gamepadEventInternal(CONNECTED_EVENT, gamepad);
     return gamepad;
 }
 
@@ -94,7 +84,7 @@ void Gamepad::remove(GamepadHandle handle)
         if (gamepad->_handle == handle)
         {
             it = __gamepads.erase(it);
-            Game::getInstance()->gamepadEvent(DISCONNECTED_EVENT, gamepad);
+            Game::getInstance()->gamepadEventInternal(DISCONNECTED_EVENT, gamepad);
             SAFE_DELETE(gamepad);
         }
         else
@@ -113,7 +103,7 @@ void Gamepad::remove(Gamepad* gamepad)
         if (g == gamepad)
         {
             it = __gamepads.erase(it);
-            Game::getInstance()->gamepadEvent(DISCONNECTED_EVENT, g);
+            Game::getInstance()->gamepadEventInternal(DISCONNECTED_EVENT, g);
             SAFE_DELETE(gamepad);
         }
         else
@@ -211,22 +201,10 @@ Gamepad::ButtonMapping Gamepad::getButtonMappingFromString(const char* string)
         return BUTTON_A;
     else if (strcmp(string, "B") == 0 || strcmp(string, "BUTTON_B") == 0)
         return BUTTON_B;
-    else if (strcmp(string, "C") == 0 || strcmp(string, "BUTTON_C") == 0)
-        return BUTTON_C;
     else if (strcmp(string, "X") == 0 || strcmp(string, "BUTTON_X") == 0)
         return BUTTON_X;
     else if (strcmp(string, "Y") == 0 || strcmp(string, "BUTTON_Y") == 0)
         return BUTTON_Y;
-    else if (strcmp(string, "Z") == 0 || strcmp(string, "BUTTON_Z") == 0)
-        return BUTTON_Z;
-    else if (strcmp(string, "MENU1") == 0 || strcmp(string, "BUTTON_MENU1") == 0)
-        return BUTTON_MENU1;
-    else if (strcmp(string, "MENU2") == 0 || strcmp(string, "BUTTON_MENU2") == 0)
-        return BUTTON_MENU2;
-    else if (strcmp(string, "MENU3") == 0 || strcmp(string, "BUTTON_MENU3") == 0)
-        return BUTTON_MENU3;
-    else if (strcmp(string, "MENU4") == 0 || strcmp(string, "BUTTON_MENU4") == 0)
-        return BUTTON_MENU4;
     else if (strcmp(string, "L1") == 0 || strcmp(string, "BUTTON_L1") == 0)
         return BUTTON_L1;
     else if (strcmp(string, "L2") == 0 || strcmp(string, "BUTTON_L2") == 0)
@@ -247,29 +225,20 @@ Gamepad::ButtonMapping Gamepad::getButtonMappingFromString(const char* string)
         return BUTTON_LEFT;
     else if (strcmp(string, "RIGHT") == 0 || strcmp(string, "BUTTON_RIGHT") == 0)
         return BUTTON_RIGHT;
+    else if (strcmp(string, "MENU1") == 0 || strcmp(string, "BUTTON_MENU1") == 0)
+        return BUTTON_MENU1;
+    else if (strcmp(string, "MENU2") == 0 || strcmp(string, "BUTTON_MENU2") == 0)
+        return BUTTON_MENU2;
+    else if (strcmp(string, "MENU3") == 0 || strcmp(string, "BUTTON_MENU3") == 0)
+        return BUTTON_MENU3;
 
-    GP_WARN("Unknown GamepadButton string.");
+    GP_WARN("Unknown string for ButtonMapping.");
     return BUTTON_A;
 }
 
-const unsigned int Gamepad::getVendorId() const
-{
-    return _vendorId;
-}
-
-const unsigned int Gamepad::getProductId() const
-{
-    return _productId;
-}
-
-const char* Gamepad::getVendorString() const
-{
-    return _vendorString.c_str();
-}
-
-const char* Gamepad::getProductString() const
+const char* Gamepad::getName() const
 {
-    return _productString.c_str();
+    return _name.c_str();
 }
 
 void Gamepad::update(float elapsedTime)
@@ -365,7 +334,7 @@ float Gamepad::getTriggerValue(unsigned int triggerId) const
 
     if (_form)
     {
-        // Triggers are currently not available for virtual gamepads.
+        // Triggers are not part of the virtual gamepad defintion
         return 0.0f;
     }
     else
@@ -389,7 +358,7 @@ void Gamepad::setButtons(unsigned int buttons)
     if (buttons != _buttons)
     {
         _buttons = buttons;
-        Platform::gamepadEventInternal(BUTTON_EVENT, this);
+        Form::gamepadButtonEventInternal(this);
     }
 }
 
@@ -398,7 +367,7 @@ void Gamepad::setJoystickValue(unsigned int index, float x, float y)
     if (_joysticks[index].x != x || _joysticks[index].y != y)
     {
         _joysticks[index].set(x, y);
-        Platform::gamepadEventInternal(JOYSTICK_EVENT, this, index);
+        Form::gamepadJoystickEventInternal(this, index);
     }
 }
 
@@ -407,7 +376,7 @@ void Gamepad::setTriggerValue(unsigned int index, float value)
     if (_triggers[index] != value)
     {
         _triggers[index] = value;
-        Platform::gamepadEventInternal(TRIGGER_EVENT, this, index);
+        Form::gamepadTriggerEventInternal(this, index);
     }
 }
 

+ 18 - 55
gameplay/src/Gamepad.h

@@ -32,27 +32,18 @@ public:
     enum GamepadEvent
     {
         CONNECTED_EVENT,
-        DISCONNECTED_EVENT,
-        BUTTON_EVENT,
-        JOYSTICK_EVENT,
-        TRIGGER_EVENT
+        DISCONNECTED_EVENT
     };
 
     /**
      * Gamepad buttons.
      */
     enum ButtonMapping
-    {
+    {        
         BUTTON_A,
         BUTTON_B,
-        BUTTON_C,
         BUTTON_X,
         BUTTON_Y,
-        BUTTON_Z,
-        BUTTON_MENU1,
-        BUTTON_MENU2,
-        BUTTON_MENU3,
-        BUTTON_MENU4,
         BUTTON_L1,
         BUTTON_L2,
         BUTTON_L3,
@@ -62,7 +53,10 @@ public:
         BUTTON_UP,
         BUTTON_DOWN,
         BUTTON_LEFT,
-        BUTTON_RIGHT
+        BUTTON_RIGHT,
+        BUTTON_MENU1,
+        BUTTON_MENU2,
+        BUTTON_MENU3
     };
 
     /**
@@ -113,33 +107,12 @@ public:
      */
     float getTriggerValue(unsigned int triggerId) const;
 
-   /**
-     * Get this gamepad's vendor ID.
-     *
-     * @return This gamepad's vendor ID.
-     */
-    const unsigned int getVendorId() const;
-
-    /**
-     * Get this gamepad's product ID.
-     *
-     * @return This gamepad's product ID.
-     */
-    const unsigned int getProductId() const;
-
-    /**
-     * Get this gamepad's vendor name.
-     *
-     * @return This gamepad's vendor name.
-     */
-    const char* getVendorString() const;
-
     /**
-     * Get this gamepad's product name.
+     * Get this gamepad's device/product name.
      *
-     * @return This gamepad's product name.
+     * @return This gamepad's device/product name.
      */
-    const char* getProductString() const;
+    const char* getName() const;
 
     /**
      * Returns whether the gamepad is currently represented with a UI form or not.
@@ -187,14 +160,9 @@ private:
      * @param buttonCount the number of buttons on the gamepad. 
      * @param joystickCount the number of joysticks on the gamepad.
      * @param triggerCount the number of triggers on the gamepad.
-     * @param vendorId The vendor id
-     * @param productId The product id
-     * @param vendorString The vendor string/name.
-     * @param productString The product string/name.
+     * @param name The product/device name.
      */
-    Gamepad(GamepadHandle handle, 
-            unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
-            unsigned int vendorId, unsigned int productId, const char* vendorString, const char* productString);
+    Gamepad(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount, const char* name);
 
     /**
      * Copy constructor.
@@ -208,9 +176,7 @@ private:
 
     static void updateInternal(float elapsedTime);
 
-    static Gamepad* add(GamepadHandle handle, 
-                        unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
-                        unsigned int vendorId, unsigned int productId, const char* vendorString, const char* productString);
+    static Gamepad* add(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount, const char* name);
 
     static Gamepad* add(const char* formPath);
 
@@ -220,7 +186,7 @@ private:
 
     static unsigned int getGamepadCount();
 
-    static Gamepad* getGamepad(unsigned int index, bool preferPhysical = true);
+    static Gamepad* getGamepad(unsigned int index, bool preferPhysical);
 
     static Gamepad* getGamepad(GamepadHandle handle);
 
@@ -234,14 +200,11 @@ private:
     
     void bindGamepadControls(Container* container);
 
-    GamepadHandle _handle;        // The handle of the Gamepad.
-    unsigned int _buttonCount;    // Number of buttons.
-    unsigned int _joystickCount;  // Number of joysticks.
-    unsigned int _triggerCount;   // Number of triggers.
-    unsigned int _vendorId;
-    unsigned int _productId;
-    std::string _vendorString;
-    std::string _productString;
+    GamepadHandle _handle;
+    unsigned int _buttonCount;
+    unsigned int _joystickCount;
+    unsigned int _triggerCount;
+    std::string _name;
     Form* _form;
     JoystickControl* _uiJoysticks[2];
     Button* _uiButtons[20];

+ 26 - 26
gameplay/src/Image.cpp

@@ -109,32 +109,32 @@ Image* Image::create(const char* path)
 
 Image* Image::create(unsigned int width, unsigned int height, Image::Format format, unsigned char* data)
 {
-	GP_ASSERT(width > 0 && height > 0);
-	GP_ASSERT(format >= RGB && format <= RGBA);
-
-	unsigned int pixelSize = 0;
-	switch(format)
-	{
-	case Image::RGB:
-		pixelSize = 3;
-		break;
-	case Image::RGBA:
-		pixelSize = 4;
-		break;
-	}
-
-	Image* image = new Image();
-
-	unsigned int dataSize = width * height * pixelSize;
-
-	image->_width = width;
-	image->_height = height;
-	image->_format = format;
-	image->_data = new unsigned char[dataSize];
-	if (data)
-		memcpy(image->_data, data, dataSize);
-
-	return image;
+    GP_ASSERT(width > 0 && height > 0);
+    GP_ASSERT(format >= RGB && format <= RGBA);
+
+    unsigned int pixelSize = 0;
+    switch(format)
+    {
+    case Image::RGB:
+        pixelSize = 3;
+        break;
+    case Image::RGBA:
+        pixelSize = 4;
+        break;
+    }
+
+    Image* image = new Image();
+
+    unsigned int dataSize = width * height * pixelSize;
+
+    image->_width = width;
+    image->_height = height;
+    image->_format = format;
+    image->_data = new unsigned char[dataSize];
+    if (data)
+        memcpy(image->_data, data, dataSize);
+
+    return image;
 }
 
 Image::Image() : _data(NULL), _format(RGB), _width(0), _height(0)

+ 5 - 5
gameplay/src/Image.h

@@ -33,17 +33,17 @@ public:
      */
     static Image* create(const char* path);
 
-	/**
+    /**
      * Creates an image from the data provided
      *
      * @param width The width of the image data.
-	 * @param height The height of the image data.
-	 * @param format The format of the image data.
-	 * @param data The image data. If NULL, the data will be allocated.
+     * @param height The height of the image data.
+     * @param format The format of the image data.
+     * @param data The image data. If NULL, the data will be allocated.
      * @return The newly created image.
      * @script{create}
      */
-	static Image* create(unsigned int width, unsigned int height, Format format, unsigned char* data = NULL);
+    static Image* create(unsigned int width, unsigned int height, Format format, unsigned char* data = NULL);
 
     /**
      * Gets the image's raw pixel data.

+ 6 - 1
gameplay/src/Material.cpp

@@ -464,6 +464,11 @@ void Material::loadRenderState(RenderState* renderState, Properties* properties)
             bool mipmap = ns->getBool("mipmap");
             Texture::Wrap wrapS = parseTextureWrapMode(ns->getString("wrapS"), Texture::REPEAT);
             Texture::Wrap wrapT = parseTextureWrapMode(ns->getString("wrapT"), Texture::REPEAT);
+            Texture::Wrap wrapR = Texture::REPEAT;
+            if(ns->exists("wrapR"))
+            {
+                wrapR = parseTextureWrapMode(ns->getString("wrapR"), Texture::REPEAT);
+            }
             Texture::Filter minFilter = parseTextureFilterMode(ns->getString("minFilter"), mipmap ? Texture::NEAREST_MIPMAP_LINEAR : Texture::LINEAR);
             Texture::Filter magFilter = parseTextureFilterMode(ns->getString("magFilter"), Texture::LINEAR);
 
@@ -472,7 +477,7 @@ void Material::loadRenderState(RenderState* renderState, Properties* properties)
             Texture::Sampler* sampler = renderState->getParameter(name)->setValue(path.c_str(), mipmap);
             if (sampler)
             {
-                sampler->setWrapMode(wrapS, wrapT);
+                sampler->setWrapMode(wrapS, wrapT, wrapR);
                 sampler->setFilterMode(minFilter, magFilter);
             }
         }

+ 31 - 17
gameplay/src/Platform.cpp

@@ -34,64 +34,78 @@ bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheel
 
 void Platform::gestureSwipeEventInternal(int x, int y, int direction)
 {
-    // TODO: Add support to Form for gestures
     Game::getInstance()->gestureSwipeEventInternal(x, y, direction);
 }
 
 void Platform::gesturePinchEventInternal(int x, int y, float scale)
 {
-    // TODO: Add support to Form for gestures
     Game::getInstance()->gesturePinchEventInternal(x, y, scale);
 }
 
 void Platform::gestureTapEventInternal(int x, int y)
 {
-    // TODO: Add support to Form for gestures
     Game::getInstance()->gestureTapEventInternal(x, y);
 }
 
 void Platform::gestureLongTapEventInternal(int x, int y, float duration)
 {
-    // TODO: Add support to Form for gestures
     Game::getInstance()->gestureLongTapEventInternal(x, y, duration);
 }
 
 void Platform::gestureDragEventInternal(int x, int y)
 {
-    // TODO: Add support to Form for gestures
     Game::getInstance()->gestureDragEventInternal(x, y);
 }
 
 void Platform::gestureDropEventInternal(int x, int y)
 {
-    // TODO: Add support to Form for gestures
     Game::getInstance()->gestureDropEventInternal(x, y);
 }
 
 void Platform::resizeEventInternal(unsigned int width, unsigned int height)
 {
     Game::getInstance()->resizeEventInternal(width, height);
-
     Form::resizeEventInternal(width, height);
 }
 
-void Platform::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
+void Platform::gamepadEventConnectedInternal(GamepadHandle handle,  unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount, const char* name)
 {
-    if (!Form::gamepadEventInternal(evt, gamepad, analogIndex))
-    {
-        Game::getInstance()->gamepadEventInternal(evt, gamepad, analogIndex);
-    }
+    Gamepad::add(handle, buttonCount, joystickCount, triggerCount, name);
 }
 
-void Platform::gamepadEventConnectedInternal(GamepadHandle handle,  unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
-                                             unsigned int vendorId, unsigned int productId, const char* vendorString, const char* productString)
+void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
 {
-    Gamepad::add(handle, buttonCount, joystickCount, triggerCount, vendorId, productId, vendorString, productString);
+    Gamepad::remove(handle);
 }
 
-void Platform::gamepadEventDisconnectedInternal(GamepadHandle handle)
+void Platform::gamepadButtonPressedEventInternal(GamepadHandle handle, Gamepad::ButtonMapping mapping)
 {
-    Gamepad::remove(handle);
+    Gamepad* gamepad = Gamepad::getGamepad(handle);
+    unsigned int newButtons = gamepad->_buttons | (1 << mapping);
+    gamepad->setButtons(newButtons);
+    Form::gamepadButtonEventInternal(gamepad);
+}
+
+void Platform::gamepadButtonReleasedEventInternal(GamepadHandle handle, Gamepad::ButtonMapping mapping)
+{
+    Gamepad* gamepad = Gamepad::getGamepad(handle);
+    unsigned int newButtons = gamepad->_buttons & ~(1 << mapping);
+    gamepad->setButtons(newButtons);
+    Form::gamepadButtonEventInternal(gamepad);
+}
+
+void Platform::gamepadTriggerChangedEventInternal(GamepadHandle handle, unsigned int index, float value)
+{
+    Gamepad* gamepad = Gamepad::getGamepad(handle);
+    gamepad->setTriggerValue(index, value);
+    Form::gamepadTriggerEventInternal(gamepad, index);
+}
+
+void Platform::gamepadJoystickChangedEventInternal(GamepadHandle handle, unsigned int index, float x, float y)
+{
+    Gamepad* gamepad = Gamepad::getGamepad(handle);
+    gamepad->setJoystickValue(index, x, y);
+    Form::gamepadJoystickEventInternal(gamepad, index);
 }
 
 }

+ 28 - 7
gameplay/src/Platform.h

@@ -370,27 +370,48 @@ public:
      *
      * @script{ignore}
      */
-    static void gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex = 0);
+    static void gamepadEventConnectedInternal(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount, const char* name);
 
     /**
      * Internal method used only from static code in various platform implementation.
      *
      * @script{ignore}
      */
-    static void gamepadEventConnectedInternal(GamepadHandle handle, unsigned int buttonCount, unsigned int joystickCount, unsigned int triggerCount,
-                                              unsigned int vendorId, unsigned int productId,
-                                              const char* vendorString, const char* productString);
+    static void gamepadEventDisconnectedInternal(GamepadHandle handle);
 
     /**
      * Internal method used only from static code in various platform implementation.
      *
      * @script{ignore}
      */
-    static void gamepadEventDisconnectedInternal(GamepadHandle handle);
+    static void gamepadButtonPressedEventInternal(GamepadHandle handle, Gamepad::ButtonMapping mapping);
 
     /**
-     * Internal method used by Gamepad that polls the platform for the updated Gamepad
-     * states such as joysticks, buttons and trigger values.
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gamepadButtonReleasedEventInternal(GamepadHandle handle, Gamepad::ButtonMapping button);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gamepadTriggerChangedEventInternal(GamepadHandle handle, unsigned int index, float value);
+
+    /**
+     * Internal method used only from static code in various platform implementation.
+     *
+     * @script{ignore}
+     */
+    static void gamepadJoystickChangedEventInternal(GamepadHandle handle, unsigned int index, float x, float y);
+
+    /**
+     * Internal method used to poll the platform for the updated Gamepad
+     * states such as buttons, joytick and trigger values.
+     *
+     * Some platforms require to poll the gamepad system to get deltas. 
      *
      * @param gamepad The gamepad to be returned with the latest polled values populated.
      * @script{ignore}

+ 443 - 300
gameplay/src/PlatformAndroid.cpp

@@ -4,6 +4,7 @@
 #include "Platform.h"
 #include "FileSystem.h"
 #include "Game.h"
+#include "Gamepad.h"
 #include "Form.h"
 #include "ScriptController.h"
 #include <unistd.h>
@@ -701,9 +702,63 @@ static int getUnicode(int keycode, int metastate)
     }
 }
 
+Gamepad::ButtonMapping getGamepadButtonMapping(jint keycode)
+{
+    switch (keycode)
+    {
+    case AKEYCODE_BUTTON_X:
+        return Gamepad::BUTTON_X;
+    case AKEYCODE_BUTTON_Y:
+        return Gamepad::BUTTON_Y;
+    case AKEYCODE_BUTTON_A:
+    case AKEYCODE_DPAD_CENTER:
+        return Gamepad::BUTTON_A;
+    case AKEYCODE_BUTTON_B:
+        return Gamepad::BUTTON_B;
+    case AKEYCODE_BUTTON_L1:
+        return Gamepad::BUTTON_L1;
+    case AKEYCODE_BUTTON_L2:
+        return Gamepad::BUTTON_L2;
+    case AKEYCODE_BUTTON_THUMBL:
+        return Gamepad::BUTTON_L3;
+    case AKEYCODE_BUTTON_R1:
+        return Gamepad::BUTTON_R1;
+    case AKEYCODE_BUTTON_R2:
+        return Gamepad::BUTTON_R2;
+    case AKEYCODE_BUTTON_THUMBR:
+        return Gamepad::BUTTON_R3;
+    case AKEYCODE_DPAD_UP:
+        return Gamepad::BUTTON_UP;
+    case AKEYCODE_DPAD_DOWN:
+        return Gamepad::BUTTON_DOWN;
+    case AKEYCODE_DPAD_LEFT:
+        return Gamepad::BUTTON_LEFT;
+    case AKEYCODE_DPAD_RIGHT:
+        return Gamepad::BUTTON_RIGHT;
+    case AKEYCODE_BUTTON_SELECT:
+        return Gamepad::BUTTON_MENU1;
+    case AKEYCODE_BUTTON_START:
+        return Gamepad::BUTTON_MENU2;
+    case AKEYCODE_BUTTON_MODE:
+        return Gamepad::BUTTON_MENU3;
+    default:
+        return Gamepad::BUTTON_A;
+    }
+}
+
+static float clampFuzz(float value, float fuzz)
+{
+    if (std::fabs(value) <= fuzz)
+        return 0.0f;
+    return value;
+}
+
 // Process the next input event.
 static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
 {
+    int32_t deviceId = AInputEvent_getDeviceId(event);
+    int32_t source = AInputEvent_getSource(event);
+
     if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
     {
         int32_t action = AMotionEvent_getAction(event);
@@ -713,305 +768,364 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
         int x;
         int y;
         
-        switch (action & AMOTION_EVENT_ACTION_MASK)
+        if (source & AINPUT_SOURCE_JOYSTICK)
         {
-            case AMOTION_EVENT_ACTION_DOWN:
-                {
-                    pointerId = AMotionEvent_getPointerId(event, 0);
-                    x = AMotionEvent_getX(event, 0);
-                    y = AMotionEvent_getY(event, 0);
-
-                    // Gesture handling
-                    if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_DRAG) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_DROP) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_PINCH) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP))
+            // DPAD handling (axis hats)
+            float xaxis = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_X, 0);
+            float yaxis = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_Y, 0);        
+            if (xaxis == -1.0f)
+            {
+                gameplay::Platform::gamepadButtonPressedEventInternal(deviceId, gameplay::Gamepad::BUTTON_LEFT);
+            }
+            else if(xaxis == 1.0f)
+            {
+                gameplay::Platform::gamepadButtonPressedEventInternal(deviceId, gameplay::Gamepad::BUTTON_RIGHT);
+            }
+            else if (xaxis == 0.0f)
+            {
+                gameplay::Platform::gamepadButtonReleasedEventInternal(deviceId, gameplay::Gamepad::BUTTON_LEFT);
+                gameplay::Platform::gamepadButtonReleasedEventInternal(deviceId, gameplay::Gamepad::BUTTON_RIGHT);
+            }
+
+            if(yaxis == -1.0f)
+            {
+                gameplay::Platform::gamepadButtonPressedEventInternal(deviceId, gameplay::Gamepad::BUTTON_UP);
+            }
+            else if(yaxis == 1.0f)
+            {
+                gameplay::Platform::gamepadButtonPressedEventInternal(deviceId, gameplay::Gamepad::BUTTON_DOWN);
+            }
+            else if (yaxis == 0.0f)
+            {
+                gameplay::Platform::gamepadButtonReleasedEventInternal(deviceId, gameplay::Gamepad::BUTTON_UP);
+                gameplay::Platform::gamepadButtonReleasedEventInternal(deviceId, gameplay::Gamepad::BUTTON_DOWN);
+            }
+
+            // Trigger handling
+            float leftTrigger = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_BRAKE, 0);
+            gameplay::Platform::gamepadTriggerChangedEventInternal(deviceId, 0, leftTrigger);
+            float rightTrigger = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_GAS, 0);
+            gameplay::Platform::gamepadTriggerChangedEventInternal(deviceId, 1, rightTrigger);
+
+            // jJoystick handling
+            float fuzz = 0.15f;
+            float x = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_X, 0);
+            float y = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Y, 0);
+            gameplay::Platform::gamepadJoystickChangedEventInternal(deviceId, 0, clampFuzz(x, fuzz), clampFuzz(y, fuzz));
+            float z = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Z, 0);
+            float rz = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_RZ, 0);
+            gameplay::Platform::gamepadJoystickChangedEventInternal(deviceId, 1, clampFuzz(z, fuzz), clampFuzz(rz, fuzz));
+        }
+        else
+        {
+            switch (action & AMOTION_EVENT_ACTION_MASK)
+            {
+                case AMOTION_EVENT_ACTION_DOWN:
                     {
-                        __pointer0.pressed = true;
-                        __pointer0.time = Game::getInstance()->getAbsoluteTime();
-                        __pointer0.pointerId = pointerId;
-                        __pointer0.x = x;
-                        __pointer0.y = y;
-						__gesturePointer0CurrentPosition = __gesturePointer0LastPosition = std::pair<int, int>(x, y);
-                    }
+                        pointerId = AMotionEvent_getPointerId(event, 0);
+                        x = AMotionEvent_getX(event, 0);
+                        y = AMotionEvent_getY(event, 0);
+
+                        // Gesture handling
+                        if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_DRAG) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_DROP) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_PINCH) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP))
+                        {
+                            __pointer0.pressed = true;
+                            __pointer0.time = Game::getInstance()->getAbsoluteTime();
+                            __pointer0.pointerId = pointerId;
+                            __pointer0.x = x;
+                            __pointer0.y = y;
+						    __gesturePointer0CurrentPosition = __gesturePointer0LastPosition = std::pair<int, int>(x, y);
+                        }
 
-                    // Primary pointer down.
-                    gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, x, y, pointerId);
-                    __primaryTouchId = pointerId;
-                }
-                break;
+                        // Primary pointer down.
+                        gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, x, y, pointerId);
+                        __primaryTouchId = pointerId;
+                    }
+                    break;
 
-            case AMOTION_EVENT_ACTION_UP:
-                {
-                    pointerId = AMotionEvent_getPointerId(event, 0);
-                    x = AMotionEvent_getX(event, 0);
-                    y = AMotionEvent_getY(event, 0);
-                    
-                    // Gestures
-                    bool gestureDetected = false;
-					if (__pointer0.pressed &&  __pointer0.pointerId == pointerId)
+                case AMOTION_EVENT_ACTION_UP:
                     {
-                        int deltaX = x - __pointer0.x;
-                        int deltaY = y - __pointer0.y;
-						
-                        // Test for drop
-                      	if (__gesturePinching)
-						{
-							__gesturePinching = false;
-							gestureDetected = true;
-						}
-						else if (__gestureDraging)
+                        pointerId = AMotionEvent_getPointerId(event, 0);
+                        x = AMotionEvent_getX(event, 0);
+                        y = AMotionEvent_getY(event, 0);
+                        
+                        // Gestures
+                        bool gestureDetected = false;
+					    if (__pointer0.pressed &&  __pointer0.pointerId == pointerId)
                         {
-                            if (__gestureEventsProcessed.test(Gesture::GESTURE_DROP))
+                            int deltaX = x - __pointer0.x;
+                            int deltaY = y - __pointer0.y;
+						
+                            // Test for drop
+                          	if (__gesturePinching)
+						    {
+							    __gesturePinching = false;
+							    gestureDetected = true;
+						    }
+						    else if (__gestureDraging)
                             {
-                                gameplay::Platform::gestureDropEventInternal(x, y);
-                                gestureDetected = true;
+                                if (__gestureEventsProcessed.test(Gesture::GESTURE_DROP))
+                                {
+                                    gameplay::Platform::gestureDropEventInternal(x, y);
+                                    gestureDetected = true;
+                                }
+                                __gestureDraging = false;
                             }
-                            __gestureDraging = false;
-                        }
-                        // Test for swipe
-                        else if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
-                            gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_SWIPE_DURATION_MAX && 
-                            (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
-                        {
-                            int direction = 0;
-                            if ( abs(deltaX) > abs(deltaY) )
+                            // Test for swipe
+                            else if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
+                                gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_SWIPE_DURATION_MAX && 
+                                (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
                             {
-                                if (deltaX > 0)
-                                    direction = gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
-                                else if (deltaX < 0)
-                                    direction = gameplay::Gesture::SWIPE_DIRECTION_LEFT;
+                                int direction = 0;
+                                if ( abs(deltaX) > abs(deltaY) )
+                                {
+                                    if (deltaX > 0)
+                                        direction = gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
+                                    else if (deltaX < 0)
+                                        direction = gameplay::Gesture::SWIPE_DIRECTION_LEFT;
+                                }
+                                else
+                                {
+                                    if (deltaY > 0)
+                                        direction = gameplay::Gesture::SWIPE_DIRECTION_DOWN;
+                                    else if (deltaY < 0)
+                                        direction = gameplay::Gesture::SWIPE_DIRECTION_UP;
+                                }
+                                gameplay::Platform::gestureSwipeEventInternal(x, y, direction);
+                                gestureDetected = true;
                             }
-                            else
+                            // Test for tap
+                            else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
+                                   gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_TAP_DURATION_MAX)
                             {
-                                if (deltaY > 0)
-                                    direction = gameplay::Gesture::SWIPE_DIRECTION_DOWN;
-                                else if (deltaY < 0)
-                                    direction = gameplay::Gesture::SWIPE_DIRECTION_UP;
+                                gameplay::Platform::gestureTapEventInternal(x, y);
+                                gestureDetected = true;
                             }
-                            gameplay::Platform::gestureSwipeEventInternal(x, y, direction);
-                            gestureDetected = true;
+                            // Test for long tap
+                            else if(__gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP) &&
+                                   gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time >= GESTURE_LONG_TAP_DURATION_MIN)
+                            {
+                                gameplay::Platform::gestureLongTapEventInternal(x, y, gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time);
+                                gestureDetected = true;
+                            }    
                         }
-                        // Test for tap
-                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
-                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_TAP_DURATION_MAX)
+					    __pointer0.pressed = false;
+
+                        if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
                         {
-                            gameplay::Platform::gestureTapEventInternal(x, y);
-                            gestureDetected = true;
+                            gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, x, y, pointerId);
                         }
-                        // Test for long tap
-                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP) &&
-                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time >= GESTURE_LONG_TAP_DURATION_MIN)
-                        {
-                            gameplay::Platform::gestureLongTapEventInternal(x, y, gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time);
-                            gestureDetected = true;
-                        }    
+                        __primaryTouchId = -1;
                     }
-					__pointer0.pressed = false;
+                    break;
 
-                    if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
+                case AMOTION_EVENT_ACTION_POINTER_DOWN:
                     {
-                        gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, x, y, pointerId);
+                        pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+                        pointerId = AMotionEvent_getPointerId(event, pointerIndex);
+                        x = AMotionEvent_getX(event, pointerIndex);
+                        y = AMotionEvent_getY(event, pointerIndex);
+
+                        // Gesture handling
+                        if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_DRAG) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_DROP) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_PINCH) ||
+                             __gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP))
+                        {
+                            __pointer1.pressed = true;
+                            __pointer1.time = Game::getInstance()->getAbsoluteTime();
+                            __pointer1.pointerId = pointerId;
+                            __pointer1.x = x;
+                            __pointer1.y = y;
+                        	__gesturePointer1CurrentPosition = __gesturePointer1LastPosition = std::pair<int, int>(x, y);
+					    }
+
+                        // Non-primary pointer down.
+                        if (__multiTouch)
+                        {
+                            gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, 
+                                                                   AMotionEvent_getX(event, pointerIndex), 
+                                                                   AMotionEvent_getY(event, pointerIndex), pointerId);
+                        }
                     }
-                    __primaryTouchId = -1;
-                }
-                break;
+                    break;
 
-            case AMOTION_EVENT_ACTION_POINTER_DOWN:
-                {
-                    pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-                    pointerId = AMotionEvent_getPointerId(event, pointerIndex);
-                    x = AMotionEvent_getX(event, pointerIndex);
-                    y = AMotionEvent_getY(event, pointerIndex);
-
-                    // Gesture handling
-                    if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_DRAG) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_DROP) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_PINCH) ||
-                         __gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP))
-                    {
-                        __pointer1.pressed = true;
-                        __pointer1.time = Game::getInstance()->getAbsoluteTime();
-                        __pointer1.pointerId = pointerId;
-                        __pointer1.x = x;
-                        __pointer1.y = y;
-                    	__gesturePointer1CurrentPosition = __gesturePointer1LastPosition = std::pair<int, int>(x, y);
-					}
-
-                    // Non-primary pointer down.
-                    if (__multiTouch)
+                case AMOTION_EVENT_ACTION_POINTER_UP:
                     {
-                        gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
-                    }
-                }
-                break;
+                        pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+                        pointerId = AMotionEvent_getPointerId(event, pointerIndex);
+                        x = AMotionEvent_getX(event, pointerIndex);
+                        y = AMotionEvent_getY(event, pointerIndex);
 
-            case AMOTION_EVENT_ACTION_POINTER_UP:
-                {
-                    pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-                    pointerId = AMotionEvent_getPointerId(event, pointerIndex);
-                    x = AMotionEvent_getX(event, pointerIndex);
-                    y = AMotionEvent_getY(event, pointerIndex);
-
-                    bool gestureDetected = false;
-                    if (__pointer1.pressed &&  __pointer1.pointerId == pointerId)
-                    {
-                        int deltaX = x - __pointer1.x;
-                        int deltaY = y - __pointer1.y;
-						
-						if (__gesturePinching)
-						{
-							__gesturePinching = false;
-							gestureDetected = true;
-						}
-						// Test for swipe
-						else if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
-                            gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_SWIPE_DURATION_MAX && 
-                            (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
+                        bool gestureDetected = false;
+                        if (__pointer1.pressed &&  __pointer1.pointerId == pointerId)
                         {
-                            int direction = 0;
-                            if (deltaX > 0)
-                                direction |= gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
-                            else if (deltaX < 0)
-                                direction |= gameplay::Gesture::SWIPE_DIRECTION_LEFT;
-                            
-                            if (deltaY > 0)
-                                direction |= gameplay::Gesture::SWIPE_DIRECTION_DOWN;
-                            else if (deltaY < 0)
-                                direction |= gameplay::Gesture::SWIPE_DIRECTION_UP;
+                            int deltaX = x - __pointer1.x;
+                            int deltaY = y - __pointer1.y;
+						
+						    if (__gesturePinching)
+						    {
+							    __gesturePinching = false;
+							    gestureDetected = true;
+						    }
+						    // Test for swipe
+						    else if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
+                                gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_SWIPE_DURATION_MAX && 
+                                (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
+                            {
+                                int direction = 0;
+                                if (deltaX > 0)
+                                    direction |= gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
+                                else if (deltaX < 0)
+                                    direction |= gameplay::Gesture::SWIPE_DIRECTION_LEFT;
+                                
+                                if (deltaY > 0)
+                                    direction |= gameplay::Gesture::SWIPE_DIRECTION_DOWN;
+                                else if (deltaY < 0)
+                                    direction |= gameplay::Gesture::SWIPE_DIRECTION_UP;
 
-                            gameplay::Platform::gestureSwipeEventInternal(x, y, direction);
-                            gestureDetected = true;
+                                gameplay::Platform::gestureSwipeEventInternal(x, y, direction);
+                                gestureDetected = true;
+                            }
+                            else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
+                                   gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_TAP_DURATION_MAX)
+                            {
+                                gameplay::Platform::gestureTapEventInternal(x, y);
+                                gestureDetected = true;
+                            }
+                            else if(__gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP) &&
+                                   gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time >= GESTURE_LONG_TAP_DURATION_MIN)
+                            {
+                                gameplay::Platform::gestureLongTapEventInternal(x, y, gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time);
+                                gestureDetected = true;
+                            }    
                         }
-                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
-                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_TAP_DURATION_MAX)
+					    __pointer1.pressed = false;
+
+                        if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
                         {
-                            gameplay::Platform::gestureTapEventInternal(x, y);
-                            gestureDetected = true;
+                            gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, 
+                                                                   AMotionEvent_getX(event, pointerIndex), 
+                                                                   AMotionEvent_getY(event, pointerIndex), pointerId);
                         }
-                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_LONG_TAP) &&
-                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time >= GESTURE_LONG_TAP_DURATION_MIN)
-                        {
-                            gameplay::Platform::gestureLongTapEventInternal(x, y, gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time);
-                            gestureDetected = true;
-                        }    
+                        if (__primaryTouchId == pointerId)
+                            __primaryTouchId = -1;
                     }
-					__pointer1.pressed = false;
-
-                    if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
-                    {
-                        gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
-                    }
-                    if (__primaryTouchId == pointerId)
-                        __primaryTouchId = -1;
-                }
-                break;
+                    break;
 
-            case AMOTION_EVENT_ACTION_MOVE:
-                {
-                    // ACTION_MOVE events are batched, unlike the other events.
-                    pointerCount = AMotionEvent_getPointerCount(event);
-                    for (size_t i = 0; i < pointerCount; ++i)
+                case AMOTION_EVENT_ACTION_MOVE:
                     {
-                        pointerId = AMotionEvent_getPointerId(event, i);
-                        x = AMotionEvent_getX(event, i);
-                        y = AMotionEvent_getY(event, i);
-                        
-                        bool gestureDetected = false;
-						if (__pointer0.pressed)
-						{
-							//The two pointers are pressed and the event was done by one of it
-							if (__pointer1.pressed && (pointerId == __pointer0.pointerId || pointerId == __pointer1.pointerId))
-							{
-								if (__pointer0.pointerId == __pointer1.pointerId)
-								{
-									__gesturePinching = false;
-									break;
-								}
-								//Test for pinch
-								if (__gestureEventsProcessed.test(Gesture::GESTURE_PINCH))
-								{
-									int pointer0Distance, pointer1Distance;
-
-									if (__pointer0.pointerId == pointerId)
-									{
-										__gesturePointer0LastPosition = __gesturePointer0CurrentPosition;
-										__gesturePointer0CurrentPosition = std::pair<int, int>(x, y);
-										__gesturePointer0Delta = sqrt(pow(static_cast<float>(x - __pointer0.x), 2) +
-																	pow(static_cast<float>(y - __pointer0.y), 2));
-									}
-									else
-									{
-										__gesturePointer1LastPosition = __gesturePointer1CurrentPosition;
-										__gesturePointer1CurrentPosition = std::pair<int, int>(x, y);
-										__gesturePointer1Delta = sqrt(pow(static_cast<float>(x - __pointer1.x), 2) +
-																	pow(static_cast<float>(y - __pointer1.y), 2));
-									}
-									if (!__gesturePinching &&
-										__gesturePointer0Delta >= GESTURE_PINCH_DISTANCE_MIN &&
-										__gesturePointer1Delta >= GESTURE_PINCH_DISTANCE_MIN)
-									{
-										__gesturePinching = true;
-										__gesturePinchCentroid = std::pair<int, int>((__pointer0.x + __pointer1.x) / 2,
-																					(__pointer0.y + __pointer1.y) / 2);
-									}
-									if (__gesturePinching)
-									{
-										int currentDistancePointer0, currentDistancePointer1;
-										int lastDistancePointer0, lastDistancePointer1;
-										float scale;
-
-										currentDistancePointer0 = sqrt(pow(static_cast<float>(__gesturePinchCentroid.first - __gesturePointer0CurrentPosition.first), 2) + pow(static_cast<float>(__gesturePinchCentroid.second - __gesturePointer0CurrentPosition.second), 2));
-										lastDistancePointer0 = sqrt(pow(static_cast<float>(__gesturePinchCentroid.first - __gesturePointer0LastPosition.first), 2) + pow(static_cast<float>(__gesturePinchCentroid.second - __gesturePointer0LastPosition.second), 2));
-										currentDistancePointer1 = sqrt(pow(static_cast<float>(__gesturePinchCentroid.first - __gesturePointer1CurrentPosition.first), 2) + pow(static_cast<float>(__gesturePinchCentroid.second - __gesturePointer1CurrentPosition.second), 2));
-										lastDistancePointer1 = sqrt(pow(static_cast<float>(__gesturePinchCentroid.first - __gesturePointer1LastPosition.first), 2) + pow(static_cast<float>(__gesturePinchCentroid.second - __gesturePointer1LastPosition.second), 2));
-										if (pointerId == __pointer0.pointerId)
-											scale = ((float) currentDistancePointer0) / ((float) lastDistancePointer0);
-										else
-											scale = ((float) currentDistancePointer1) / ((float) lastDistancePointer1);
-										if (((currentDistancePointer0 >= lastDistancePointer0) && (currentDistancePointer1 >= lastDistancePointer1)) ||
-											((currentDistancePointer0 <= lastDistancePointer0) && (currentDistancePointer1 <= lastDistancePointer1)))
-										{
-											gameplay::Platform::gesturePinchEventInternal(__gesturePinchCentroid.first, __gesturePinchCentroid.second, scale);	
-											gestureDetected = true;
-										}
-										else
-											__gesturePinching = false;
-									}
-								}
-							}
-							//Only the primary pointer is done and the event was done by it
-							else if (!gestureDetected && pointerId == __pointer0.pointerId)
-							{
-								//Test for drag
-								if (__gestureEventsProcessed.test(Gesture::GESTURE_DRAG))
-								{
-                            		int delta = sqrt(pow(static_cast<float>(x - __pointer0.x), 2) +
-													pow(static_cast<float>(y - __pointer0.y), 2));
-                            
-                            		if ((__gestureDraging || __gestureEventsProcessed.test(Gesture::GESTURE_DRAG)) &&
-                                 		(gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time >= GESTURE_DRAG_START_DURATION_MIN) &&
-                                		(delta >= GESTURE_DRAG_DISTANCE_MIN))
-                            		{
-                                		gameplay::Platform::gestureDragEventInternal(x, y);
-                                		__gestureDraging = true;
-                                		gestureDetected = true;
-                            		}
-								}
-							}
-						}
-
-                        if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId))
+                        // ACTION_MOVE events are batched, unlike the other events.
+                        pointerCount = AMotionEvent_getPointerCount(event);
+                        for (size_t i = 0; i < pointerCount; ++i)
                         {
-                            gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
-                        }
-                    }
-                }
-                break;
+                            pointerId = AMotionEvent_getPointerId(event, i);
+                            x = AMotionEvent_getX(event, i);
+                            y = AMotionEvent_getY(event, i);
+                            
+                            bool gestureDetected = false;
+						    if (__pointer0.pressed)
+						    {
+							    //The two pointers are pressed and the event was done by one of it
+							    if (__pointer1.pressed && (pointerId == __pointer0.pointerId || pointerId == __pointer1.pointerId))
+							    {
+								    if (__pointer0.pointerId == __pointer1.pointerId)
+								    {
+									    __gesturePinching = false;
+									    break;
+								    }
+								    //Test for pinch
+								    if (__gestureEventsProcessed.test(Gesture::GESTURE_PINCH))
+								    {
+									    int pointer0Distance, pointer1Distance;
+
+									    if (__pointer0.pointerId == pointerId)
+									    {
+										    __gesturePointer0LastPosition = __gesturePointer0CurrentPosition;
+										    __gesturePointer0CurrentPosition = std::pair<int, int>(x, y);
+										    __gesturePointer0Delta = sqrt(pow(static_cast<float>(x - __pointer0.x), 2) +
+																	    pow(static_cast<float>(y - __pointer0.y), 2));
+									    }
+									    else
+									    {
+										    __gesturePointer1LastPosition = __gesturePointer1CurrentPosition;
+										    __gesturePointer1CurrentPosition = std::pair<int, int>(x, y);
+										    __gesturePointer1Delta = sqrt(pow(static_cast<float>(x - __pointer1.x), 2) +
+																	    pow(static_cast<float>(y - __pointer1.y), 2));
+									    }
+									    if (!__gesturePinching &&
+										    __gesturePointer0Delta >= GESTURE_PINCH_DISTANCE_MIN &&
+										    __gesturePointer1Delta >= GESTURE_PINCH_DISTANCE_MIN)
+									    {
+										    __gesturePinching = true;
+										    __gesturePinchCentroid = std::pair<int, int>((__pointer0.x + __pointer1.x) / 2,
+																					    (__pointer0.y + __pointer1.y) / 2);
+									    }
+									    if (__gesturePinching)
+									    {
+										    int currentDistancePointer0, currentDistancePointer1;
+										    int lastDistancePointer0, lastDistancePointer1;
+										    float scale;
+
+										    currentDistancePointer0 = sqrt(pow(static_cast<float>(__gesturePinchCentroid.first - __gesturePointer0CurrentPosition.first), 2) + 
+                                                                           pow(static_cast<float>(__gesturePinchCentroid.second - __gesturePointer0CurrentPosition.second), 2));
+										    lastDistancePointer0 = sqrt(pow(static_cast<float>(__gesturePinchCentroid.first - __gesturePointer0LastPosition.first), 2) + 
+                                                                        pow(static_cast<float>(__gesturePinchCentroid.second - __gesturePointer0LastPosition.second), 2));
+										    currentDistancePointer1 = sqrt(pow(static_cast<float>(__gesturePinchCentroid.first - __gesturePointer1CurrentPosition.first), 2) + 
+                                                                           pow(static_cast<float>(__gesturePinchCentroid.second - __gesturePointer1CurrentPosition.second), 2));
+										    lastDistancePointer1 = sqrt(pow(static_cast<float>(__gesturePinchCentroid.first - __gesturePointer1LastPosition.first), 2) + 
+                                                                        pow(static_cast<float>(__gesturePinchCentroid.second - __gesturePointer1LastPosition.second), 2));
+										    if (pointerId == __pointer0.pointerId)
+											    scale = ((float) currentDistancePointer0) / ((float) lastDistancePointer0);
+										    else
+											    scale = ((float) currentDistancePointer1) / ((float) lastDistancePointer1);
+										    if (((currentDistancePointer0 >= lastDistancePointer0) && (currentDistancePointer1 >= lastDistancePointer1)) ||
+											    ((currentDistancePointer0 <= lastDistancePointer0) && (currentDistancePointer1 <= lastDistancePointer1)))
+										    {
+											    gameplay::Platform::gesturePinchEventInternal(__gesturePinchCentroid.first, __gesturePinchCentroid.second, scale);	
+											    gestureDetected = true;
+										    }
+										    else
+											    __gesturePinching = false;
+									    }
+								    }
+							    }
+							    // Only the primary pointer is done and the event was done by it
+							    else if (!gestureDetected && pointerId == __pointer0.pointerId)
+							    {
+								    //Test for drag
+								    if (__gestureEventsProcessed.test(Gesture::GESTURE_DRAG))
+								    {
+                                		int delta = sqrt(pow(static_cast<float>(x - __pointer0.x), 2) +
+													    pow(static_cast<float>(y - __pointer0.y), 2));
+                                
+                                		if ((__gestureDraging || __gestureEventsProcessed.test(Gesture::GESTURE_DRAG)) &&
+                                     		(gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time >= GESTURE_DRAG_START_DURATION_MIN) &&
+                                    		(delta >= GESTURE_DRAG_DISTANCE_MIN))
+                                		{
+                                    		gameplay::Platform::gestureDragEventInternal(x, y);
+                                    		__gestureDraging = true;
+                                    		gestureDetected = true;
+                                		}
+								    }
+							    }
+						    }
+
+                            if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId))
+                            {
+                                gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
+                            }
+                       }
+                   }
+                   break;
+            }
         }
         return 1;
     } 
@@ -1028,16 +1142,29 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
         switch(action)
         {
             case AKEY_EVENT_ACTION_DOWN:
-                gameplay::Platform::keyEventInternal(Keyboard::KEY_PRESS, getKey(keycode, metastate));
-                if (int character = getUnicode(keycode, metastate))
-                    gameplay::Platform::keyEventInternal(Keyboard::KEY_CHAR, character);
+                if ((source & AINPUT_SOURCE_GAMEPAD) || (source & AINPUT_SOURCE_JOYSTICK))
+                {
+                    gameplay::Platform::gamepadButtonPressedEventInternal(deviceId, gameplay::getGamepadButtonMapping(keycode));
+                }
+                else
+                {
+                    gameplay::Platform::keyEventInternal(Keyboard::KEY_PRESS, getKey(keycode, metastate));
+                    if (int character = getUnicode(keycode, metastate))
+                        gameplay::Platform::keyEventInternal(Keyboard::KEY_CHAR, character);
+                }
                 break;
                     
             case AKEY_EVENT_ACTION_UP:
-                gameplay::Platform::keyEventInternal(Keyboard::KEY_RELEASE, getKey(keycode, metastate));
+                if ((source & AINPUT_SOURCE_GAMEPAD) || (source & AINPUT_SOURCE_JOYSTICK) )
+                {
+                    gameplay::Platform::gamepadButtonReleasedEventInternal(deviceId, gameplay::getGamepadButtonMapping(keycode));
+                }
+                else
+                {
+                    gameplay::Platform::keyEventInternal(Keyboard::KEY_RELEASE, getKey(keycode, metastate));
+                }
                 break;
         }
-
         return 1;
     }
     return 0;
@@ -1049,7 +1176,6 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
     switch (cmd) 
     {
         case APP_CMD_INIT_WINDOW:
-            // The window is being shown, get it ready.
             if (app->window != NULL)
             {
                 initEGL();
@@ -1065,6 +1191,29 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
             destroyEGLMain();
             __initialized = false;
             break;
+        case APP_CMD_PAUSE:
+            Game::getInstance()->pause();
+            __suspended = true;
+            break;
+        case APP_CMD_RESUME:
+            if (__initialized)
+            {
+                Game::getInstance()->resume();
+            }
+            __suspended = false;
+            break;
+        case APP_CMD_LOST_FOCUS:
+            // When our app loses focus, we stop monitoring the sensors.
+            // This is to avoid consuming battery while not being used.
+            if (__accelerometerSensor != NULL)
+            {
+                ASensorEventQueue_disableSensor(__sensorEventQueue, __accelerometerSensor);
+            }
+            if (__gyroscopeSensor != NULL)
+            {
+                ASensorEventQueue_disableSensor(__sensorEventQueue, __gyroscopeSensor);
+            }
+            break;
         case APP_CMD_GAINED_FOCUS:
             // When our app gains focus, we start monitoring the sensors.
             if (__accelerometerSensor != NULL) 
@@ -1079,7 +1228,6 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
                 // We'd like to get 60 events per second (in microseconds).
                 ASensorEventQueue_setEventRate(__sensorEventQueue, __gyroscopeSensor, (1000L/60)*1000);
             }
-
             if (Game::getInstance()->getState() == Game::UNINITIALIZED)
             {
                 Game::getInstance()->run();
@@ -1089,29 +1237,6 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
                 Game::getInstance()->resume();
             }
             break;
-        case APP_CMD_RESUME:
-            if (__initialized)
-            {
-                Game::getInstance()->resume();
-            }
-            __suspended = false;
-            break;
-        case APP_CMD_PAUSE:
-            Game::getInstance()->pause();
-            __suspended = true;
-            break;
-        case APP_CMD_LOST_FOCUS:
-            // When our app loses focus, we stop monitoring the sensors.
-            // This is to avoid consuming battery while not being used.
-            if (__accelerometerSensor != NULL) 
-            {
-                ASensorEventQueue_disableSensor(__sensorEventQueue, __accelerometerSensor);
-            }
-            if (__gyroscopeSensor != NULL) 
-            {
-                ASensorEventQueue_disableSensor(__sensorEventQueue, __gyroscopeSensor);
-            }
-            break;
     }
 }
 
@@ -1343,8 +1468,6 @@ void Platform::setMultiSampling(bool enabled)
     {
         return;
     }
-
-    // TODO
     __multiSampling = enabled;
 }
 
@@ -1638,4 +1761,24 @@ std::string Platform::displayFileDialog(size_t mode, const char* title, const ch
 
 }
 
+extern "C"
+{
+
+JNIEXPORT void JNICALL Java_org_gameplay3d_GameNativeActivity_gamepadEventConnectedImpl(JNIEnv* env, jclass clazz, jint deviceId, jint buttonCount, jint joystickCount, jint triggerCount, jstring deviceName)
+{
+    const char* name = env->GetStringUTFChars(deviceName, JNI_FALSE);
+    
+	gameplay::Platform::gamepadEventConnectedInternal(deviceId, buttonCount, joystickCount, triggerCount, name);
+    
+    env->ReleaseStringUTFChars(deviceName, name);
+}
+
+JNIEXPORT void JNICALL Java_org_gameplay3d_GameNativeActivity_gamepadEventDisconnectedImpl(JNIEnv* env, jclass clazz, jint deviceId)
+{
+	gameplay::Platform::gamepadEventDisconnectedInternal(deviceId);
+}
+
+}
+
 #endif
+

+ 5 - 5
gameplay/src/PlatformLinux.cpp

@@ -1012,7 +1012,8 @@ void handleConnectedGamepad(dev_t devId, const char* devPath, const char* sysFSI
     unsigned int vendorId =readIntegerGamepadIdPropery(sysFSIdPath,"vendor");
     unsigned int productId =readIntegerGamepadIdPropery(sysFSIdPath,"product");
 
-    if (isBlackListed(vendorId,productId)) return;
+    if (isBlackListed(vendorId, productId))
+        return;
 
     GamepadHandle handle = ::open(devPath,O_RDONLY | O_NONBLOCK);
     if(handle < 0)
@@ -1029,18 +1030,17 @@ void handleConnectedGamepad(dev_t devId, const char* devPath, const char* sysFSI
     ioctl (handle, JSIOCGAXES, &axesNum);
     ioctl (handle, JSIOCGBUTTONS, &btnsNum);
 
-    const GamepadInfoEntry& gpInfo = getGamepadMappedInfo(vendorId,productId,(unsigned int)axesNum,(unsigned int)btnsNum);
+    const GamepadInfoEntry& gpInfo = getGamepadMappedInfo(vendorId, productId, (unsigned int)axesNum, (unsigned int)btnsNum);
     unsigned int numJS = gpInfo.numberOfJS;
     unsigned int numTR = gpInfo.numberOfTriggers;
 
-    // Ignore accelerometer devices that register themselves as joysticks. Ensure they have at least 2 buttons.s
+    // Ignore accelerometer devices that register themselves as joysticks. Ensure they have at least 2 buttons.
     if (btnsNum < 2)
         return;
 
-    Platform::gamepadEventConnectedInternal(handle,btnsNum,numJS,numTR,vendorId,productId,"",name);
+    Platform::gamepadEventConnectedInternal(handle, btnsNum, numJS, numTR, name);
     ConnectedGamepadDevInfo info = {devId,handle,gpInfo}; 
     __connectedGamepads.push_back(info);
-    
 }
 
 static float normalizeJoystickAxis(int axisValue, int deadZone, bool zeroToOne)

+ 6 - 49
gameplay/src/PlatformMacOSX.mm

@@ -22,8 +22,6 @@
 #define MICROSOFT_XBOX360_PRODUCT_ID    0x028e
 #define STEELSERIES_VENDOR_ID           0x1038
 #define STEELSERIES_FREE_PRODUCT_ID     0x1412
-#define FRUCTEL_VENDOR_ID               0x25B6
-#define FRUCTEL_GAMETEL_PRODUCT_ID      0x0001
 
 using namespace std;
 using namespace gameplay;
@@ -334,7 +332,6 @@ double getMachTimeInMilliseconds()
 
 - (NSString*)identifierName;
 - (NSString*)productName;
-- (NSString*)manufacturerName;
 - (NSString*)serialNumber;
 - (int)versionNumber;
 - (int)vendorID;
@@ -546,7 +543,6 @@ double getMachTimeInMilliseconds()
 {
     NSString* idName = NULL;
     if(idName == NULL) idName = [self productName];
-    if(idName == NULL) idName = [self manufacturerName];
     if(idName == NULL) idName = [self serialNumber];
     if(idName == NULL) idName = [NSString stringWithFormat:@"%d-%d", [self vendorID], [self productID]];
     return idName;
@@ -562,16 +558,6 @@ double getMachTimeInMilliseconds()
     return (NSString*)productName;
 }
 
-- (NSString*)manufacturerName
-{
-    CFStringRef manufacturerName = (CFStringRef)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDManufacturerKey));
-    if(manufacturerName == NULL || CFGetTypeID(manufacturerName) != CFStringGetTypeID())
-    {
-        return NULL;
-    }
-    return (NSString*)manufacturerName;
-}
-
 - (NSString*)serialNumber
 {
     CFStringRef serialNumber = (CFStringRef)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDSerialNumberKey));
@@ -786,9 +772,6 @@ double getMachTimeInMilliseconds()
                                                     [gamepad numberOfButtons],
                                                     [gamepad numberOfSticks],
                                                     [gamepad numberOfTriggerButtons],
-                                                    [gamepad vendorID],
-                                                    [gamepad productID],
-                                                    [[gamepad manufacturerName] cStringUsingEncoding:NSASCIIStringEncoding],
                                                     [[gamepad productName] cStringUsingEncoding:NSASCIIStringEncoding]);
 
             [__activeGamepads setObject:locationID forKey:locationID];
@@ -2054,52 +2037,26 @@ void Platform::pollGamepadState(Gamepad* gamepad)
             Gamepad::BUTTON_MENU1
         };
         
-        static const int GametelMapping103[12] = {
-            Gamepad::BUTTON_B,
-            Gamepad::BUTTON_X,
-            Gamepad::BUTTON_Y,
-            Gamepad::BUTTON_A,
-            Gamepad::BUTTON_L1,
-            Gamepad::BUTTON_R1,
-            Gamepad::BUTTON_MENU1,
-            Gamepad::BUTTON_MENU2,
-            Gamepad::BUTTON_RIGHT,
-            Gamepad::BUTTON_LEFT,
-            Gamepad::BUTTON_DOWN,
-            Gamepad::BUTTON_UP
-        };
-        
         const int* mapping = NULL;
         float axisDeadZone = 0.0f;
-        if (gamepad->_vendorId == SONY_USB_VENDOR_ID &&
-            gamepad->_productId == SONY_USB_PS3_PRODUCT_ID)
+        if ([gp vendorID] == SONY_USB_VENDOR_ID &&
+            [gp productID] == SONY_USB_PS3_PRODUCT_ID)
         {
             mapping = PS3Mapping;
             axisDeadZone = 0.07f;
         }
-        else if (gamepad->_vendorId == MICROSOFT_VENDOR_ID &&
-                 gamepad->_productId == MICROSOFT_XBOX360_PRODUCT_ID)
+        else if ([gp vendorID] == MICROSOFT_VENDOR_ID &&
+                 [gp productID] == MICROSOFT_XBOX360_PRODUCT_ID)
         {
             mapping = XBox360Mapping;
             axisDeadZone = 0.2f;
         }
-        else if (gamepad->_vendorId == STEELSERIES_VENDOR_ID &&
-                 gamepad->_productId == STEELSERIES_FREE_PRODUCT_ID)
+        else if ([gp vendorID] == STEELSERIES_VENDOR_ID &&
+                 [gp productID] == STEELSERIES_FREE_PRODUCT_ID)
         {
             mapping = SteelSeriesFreeMapping;
             axisDeadZone = 0.005f;
         }
-        else if (gamepad->_vendorId == FRUCTEL_VENDOR_ID &&
-                 gamepad->_productId == FRUCTEL_GAMETEL_PRODUCT_ID)
-        {
-            int ver = [gp versionNumber];
-            int major = ver >> 8;
-            int minor = ver & 0x00ff;
-            if (major >= 1 && minor > 1)
-            {
-                mapping = GametelMapping103;
-            }
-        }
         
         unsigned int buttons = 0;
         for (int i = 0; i < [gp numberOfButtons]; ++i)

+ 9 - 12
gameplay/src/PlatformWindows.cpp

@@ -951,7 +951,7 @@ Platform* Platform::create(Game* game)
             if (!__connectedXInput[i])
             {
                 // Gamepad is connected.
-                Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, 0, 0, "Microsoft", "XBox360 Controller");
+                Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, "Microsoft XBox360 Controller");
                 __connectedXInput[i] = true;
             }
         }
@@ -1008,7 +1008,7 @@ int Platform::enterMessagePump()
                 if (XInputGetState(i, &__xInputState) == NO_ERROR && !__connectedXInput[i])
                 {
                     // Gamepad was just connected.
-                    Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, 0, 0, "Microsoft", "XBox360 Controller");
+                    Platform::gamepadEventConnectedInternal(i, XINPUT_BUTTON_COUNT, XINPUT_JOYSTICK_COUNT, XINPUT_TRIGGER_COUNT, "Microsoft XBox360 Controller");
                     __connectedXInput[i] = true;
                 }
                 else if (XInputGetState(i, &__xInputState) != NO_ERROR && __connectedXInput[i])
@@ -1372,18 +1372,18 @@ std::string Platform::displayFileDialog(size_t mode, const char* title, const ch
     OPENFILENAMEA ofn;
     memset(&ofn, 0, sizeof(ofn));
 
-    // Set initial directory
+    char currentDir[1024];
+    char absPath[1024];
     std::string initialDirectoryStr;
-    char currentDir[256];
     if (initialDirectory == NULL)
     {
-        char currentDir[512];
-        GetCurrentDirectoryA(512, currentDir);
+        GetCurrentDirectoryA(1024, currentDir);
         initialDirectoryStr = currentDir;
     }
     else
     {
-        initialDirectoryStr = initialDirectory;
+        GetFullPathNameA(initialDirectory, 1024, absPath, 0);
+        initialDirectoryStr = absPath;
     }
 
     // Filter on extensions
@@ -1408,14 +1408,14 @@ std::string Platform::displayFileDialog(size_t mode, const char* title, const ch
     strcpy(filter, descStr.c_str());
     strcpy(filter + descStr.length() + 1, extStr.c_str());
 
-    char szFileName[512] = "";
+    char szFileName[1024] = "";
     ofn.lpstrFile = szFileName;
     ofn.lStructSize = sizeof(ofn);
     ofn.hwndOwner = GetForegroundWindow();
     ofn.lpstrTitle = title;
     ofn.lpstrFilter = filter;
     ofn.lpstrInitialDir = initialDirectoryStr.c_str();
-    ofn.nMaxFile = 512;
+    ofn.nMaxFile = 1024;
     ofn.lpstrDefExt = filter;
 
     if (mode == FileSystem::OPEN)
@@ -1430,9 +1430,6 @@ std::string Platform::displayFileDialog(size_t mode, const char* title, const ch
     }
 
     filename = szFileName;
-        
-    if (initialDirectory == NULL)
-        SetCurrentDirectoryA(currentDir);
 
     return filename;
 }

+ 14 - 10
gameplay/src/PlatformiOS.mm

@@ -1511,29 +1511,33 @@ bool Platform::canExit()
 
 unsigned int Platform::getDisplayWidth()
 {
-    if(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
+#ifdef NSFoundationVersionNumber_iOS_7_1
+    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
     {
-        CGSize size = DeviceOrientedSize([__appDelegate.viewController interfaceOrientation]);
-        return size.width;
+        //iOS 8+
+        return [[UIScreen mainScreen] bounds].size.width * [[UIScreen mainScreen] scale];
     }
     else
+#endif
     {
-        //iOS 8+
-        return [[UIScreen mainScreen] bounds].size.width * [[UIScreen mainScreen] scale];
+        CGSize size = DeviceOrientedSize([__appDelegate.viewController interfaceOrientation]);
+        return size.width;
     }
 }
 
 unsigned int Platform::getDisplayHeight()
 {
-    if(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
+#ifdef NSFoundationVersionNumber_iOS_7_1
+    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
     {
-        CGSize size = DeviceOrientedSize([__appDelegate.viewController interfaceOrientation]);
-        return size.height;
+        //iOS 8+
+        return [[UIScreen mainScreen] bounds].size.height * [[UIScreen mainScreen] scale];
     }
     else
+#endif
     {
-        //iOS 8+
-        return [[UIScreen mainScreen] bounds].size.height * [[UIScreen mainScreen] scale];
+        CGSize size = DeviceOrientedSize([__appDelegate.viewController interfaceOrientation]);
+        return size.height;
     }
 }
 

+ 9 - 17
gameplay/src/Slider.cpp

@@ -257,26 +257,18 @@ bool Slider::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
     return false;
 }
 
-bool Slider::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
+bool Slider::gamepadJoystickEvent(Gamepad* gamepad, unsigned int index)
 {
-    switch (evt)
+    // The right analog stick can be used to change a slider's value.
+    if (index == 1)
     {
-        case Gamepad::JOYSTICK_EVENT:
-        {
-            // The right analog stick can be used to change a slider's value.
-            if (analogIndex == 1)
-            {
-                Vector2 joy;
-                gamepad->getJoystickValues(analogIndex, &joy);
-                _gamepadValue = _value;
-                _delta = joy.x;
-                return true;
-            }
-            break;
-        }
+        Vector2 joy;
+        gamepad->getJoystickValues(index, &joy);
+        _gamepadValue = _value;
+        _delta = joy.x;
+        return true;
     }
-
-    return Label::gamepadEvent(evt, gamepad, analogIndex);
+    return Label::gamepadJoystickEvent(gamepad, index);
 }
 
 bool Slider::keyEvent(Keyboard::KeyEvent evt, int key)

+ 8 - 31
gameplay/src/Slider.h

@@ -185,47 +185,24 @@ protected:
     void initialize(const char* typeName, Theme::Style* style, Properties* properties);
 
     /**
-     * Touch callback on touch events.  Controls return true if they consume the touch event.
-     *
-     * @param evt The touch event that occurred.
-     * @param x The x position of the touch in pixels. Left edge is zero.
-     * @param y The y position of the touch in pixels. Top edge is zero.
-     * @param contactIndex The order of occurrence for multiple touch contacts starting at zero.
-     *
-     * @return Whether the touch event was consumed by the control.
-     *
-     * @see Touch::TouchEvent
+     * @see Control::KeyEvent
      */
-    bool touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
+    bool keyEvent(Keyboard::KeyEvent evt, int key);
 
     /**
-     * Mouse callback on mouse events.
-     *
-     * @param evt The mouse event that occurred.
-     * @param x The x position of the mouse in pixels. Left edge is zero.
-     * @param y The y position of the mouse in pixels. Top edge is zero.
-     * @param wheelDelta The number of mouse wheel ticks. Positive is up (forward), negative is down (backward).
-     *
-     * @return True if the mouse event is consumed or false if it is not consumed.
-     *
-     * @see Mouse::MouseEvent
+     * @see Control::TouchEvent
      */
-    bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
+    bool touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex);
 
     /**
-     * Gamepad callback on gamepad events.
-     *
-     * @see Control::gamepadEvent
+     * @see Control::MouseEvent
      */
-    bool gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex);
+    bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta);
 
     /**
-     * Keyboard callback on key events.
-     *
-     * @see Keyboard::KeyEvent
-     * @see Keyboard::Key
+     * @see Control::gamepadJoystickEvent
      */
-    bool keyEvent(Keyboard::KeyEvent evt, int key);
+    bool gamepadJoystickEvent(Gamepad* gamepad, unsigned int index);
 
     /**
      * @see Control::drawImages

+ 1 - 0
gameplay/src/SpriteBatch.cpp

@@ -58,6 +58,7 @@ SpriteBatch* SpriteBatch::create(const char* texturePath, Effect* effect, unsign
 SpriteBatch* SpriteBatch::create(Texture* texture,  Effect* effect, unsigned int initialCapacity)
 {
     GP_ASSERT(texture != NULL);
+    GP_ASSERT(texture->getType() == Texture::TEXTURE_2D);
 
     bool customEffect = (effect != NULL);
     if (!customEffect)

+ 3 - 0
gameplay/src/Terrain.cpp

@@ -259,7 +259,10 @@ Terrain* Terrain::create(HeightField* heightfield, const Vector3& scale,
     BoundingBox& bounds = terrain->_boundingBox;
 
     if (normalMapPath)
+    {
         terrain->_normalMap = Texture::Sampler::create(normalMapPath, true);
+        GP_ASSERT( terrain->_normalMap->getTexture()->getType() == Texture::TEXTURE_2D );
+    }
 
     float halfWidth = (width - 1) * 0.5f;
     float halfHeight = (height - 1) * 0.5f;

+ 7 - 0
gameplay/src/TerrainPatch.cpp

@@ -384,6 +384,13 @@ int TerrainPatch::addSampler(const char* path)
     if (!texture)
         return -1;
 
+    // Textures should only be 2D
+    if (texture->getType() != Texture::TEXTURE_2D)
+    {
+        SAFE_RELEASE(texture);
+        return -1;
+    }
+
     int firstAvailableIndex = -1;
     for (size_t i = 0, count = _samplers.size(); i < count; ++i)
     {

+ 396 - 114
gameplay/src/Texture.cpp

@@ -48,10 +48,11 @@ namespace gameplay
 {
 
 static std::vector<Texture*> __textureCache;
-static TextureHandle __currentTextureId;
+static TextureHandle __currentTextureId = 0;
+static Texture::Type __currentTextureType = Texture::TEXTURE_2D;
 
-Texture::Texture() : _handle(0), _format(UNKNOWN), _width(0), _height(0), _mipmapped(false), _cached(false), _compressed(false),
-    _wrapS(Texture::REPEAT), _wrapT(Texture::REPEAT), _minFilter(Texture::NEAREST_MIPMAP_LINEAR), _magFilter(Texture::LINEAR)
+Texture::Texture() : _handle(0), _format(UNKNOWN), _type((Texture::Type)0), _width(0), _height(0), _mipmapped(false), _cached(false), _compressed(false),
+    _wrapS(Texture::REPEAT), _wrapT(Texture::REPEAT), _wrapR(Texture::REPEAT), _minFilter(Texture::NEAREST_MIPMAP_LINEAR), _magFilter(Texture::LINEAR)
 {
 }
 
@@ -76,13 +77,13 @@ Texture::~Texture()
 
 Texture* Texture::create(const char* path, bool generateMipmaps)
 {
-    GP_ASSERT(path);
+    GP_ASSERT( path );
 
     // Search texture cache first.
     for (size_t i = 0, count = __textureCache.size(); i < count; ++i)
     {
         Texture* t = __textureCache[i];
-        GP_ASSERT(t);
+        GP_ASSERT( t );
         if (t->_path == path)
         {
             // If 'generateMipmaps' is true, call Texture::generateMipamps() to force the
@@ -146,7 +147,7 @@ Texture* Texture::create(const char* path, bool generateMipmaps)
 
 Texture* Texture::create(Image* image, bool generateMipmaps)
 {
-    GP_ASSERT(image);
+    GP_ASSERT( image );
 
     switch (image->getFormat())
     {
@@ -160,28 +161,69 @@ Texture* Texture::create(Image* image, bool generateMipmaps)
     }
 }
 
-Texture* Texture::create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps)
+Texture* Texture::create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps, Texture::Type type)
 {
-    // Create and load the texture.
+    GP_ASSERT( type == Texture::TEXTURE_2D || type == Texture::TEXTURE_CUBE );
+
+    GLenum target = (GLenum)type;
+
+    // Create the texture.
     GLuint textureId;
     GL_ASSERT( glGenTextures(1, &textureId) );
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) );
+    GL_ASSERT( glBindTexture(target, textureId) );
     GL_ASSERT( glPixelStorei(GL_UNPACK_ALIGNMENT, 1) );
 #ifndef OPENGL_ES
     // glGenerateMipmap is new in OpenGL 3.0. For OpenGL 2.0 we must fallback to use glTexParameteri
     // with GL_GENERATE_MIPMAP prior to actual texture creation (glTexImage2D)
-    if ( generateMipmaps && glGenerateMipmap == NULL )
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE) );
+    if ( generateMipmaps && !std::addressof(glGenerateMipmap) )
+        GL_ASSERT( glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE) );
 #endif
-    GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) );
+
+    // Load the texture
+    if (type == Texture::TEXTURE_2D)
+    {
+        // Texture 2D
+        GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) );
+    }
+    else
+    {
+        // Get texture size
+        unsigned int textureSize = width * height;
+        switch (format)
+        {
+            case Texture::RGB:
+                textureSize *= 3;
+                break;
+            case Texture::RGBA:
+                textureSize *= 4;
+                break;
+            case Texture::ALPHA:
+                break;
+            case Texture::UNKNOWN:
+                if (data)
+                {
+                    glDeleteTextures(1, &textureId);
+                    GP_ERROR("Failed to determine texture size because format is UNKNOWN.");
+                    return NULL;
+                }
+                break;
+        }
+        // Texture Cube
+        for (unsigned int i = 0; i < 6; i++)
+        {
+            const unsigned char* texturePtr = (data == NULL) ? NULL : &data[i * textureSize];
+            GL_ASSERT( glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, texturePtr) );
+        }
+    }
 
     // Set initial minification filter based on whether or not mipmaping was enabled.
     Filter minFilter = generateMipmaps ? NEAREST_MIPMAP_LINEAR : LINEAR;
-    GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter) );
+    GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter) );
 
     Texture* texture = new Texture();
     texture->_handle = textureId;
     texture->_format = format;
+    texture->_type = type;
     texture->_width = width;
     texture->_height = height;
     texture->_minFilter = minFilter;
@@ -191,16 +233,33 @@ Texture* Texture::create(Format format, unsigned int width, unsigned int height,
     }
 
     // Restore the texture id
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, __currentTextureId) );
+    GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
 
     return texture;
 }
 
 Texture* Texture::create(TextureHandle handle, int width, int height, Format format)
 {
-    GP_ASSERT(handle);
+    GP_ASSERT( handle );
 
     Texture* texture = new Texture();
+    if (glIsTexture(handle))
+    {
+        // There is no real way to query for texture type, but an error will be returned if a cube texture is bound to a 2D texture... so check for that
+        glBindTexture(GL_TEXTURE_CUBE_MAP, handle);
+        if (glGetError() == GL_NO_ERROR)
+        {
+            texture->_type = TEXTURE_CUBE;
+        }
+        else
+        {
+            // For now, it's either or. But if 3D textures and others are added, it might be useful to simply test a bunch of bindings and seeing which one doesn't error out
+            texture->_type = TEXTURE_2D;
+        }
+
+        // Restore the texture id
+        GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
+    }
     texture->_handle = handle;
     texture->_format = format;
     texture->_width = width;
@@ -209,6 +268,50 @@ Texture* Texture::create(TextureHandle handle, int width, int height, Format for
     return texture;
 }
 
+void Texture::setData(const unsigned char* data)
+{
+    // Don't work with any compressed or cached textures
+    GP_ASSERT( data );
+    GP_ASSERT( (!_compressed) );
+    GP_ASSERT( (!_cached) );
+
+    GL_ASSERT( glBindTexture((GLenum)_type, _handle) );
+
+    if (_type == Texture::TEXTURE_2D)
+    {
+        GL_ASSERT( glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, (GLenum)_format, GL_UNSIGNED_BYTE, data) );
+    }
+    else
+    {
+        // Get texture size
+        unsigned int textureSize = _width * _height;
+        switch (_format)
+        {
+            case Texture::RGB:
+                textureSize *= 3;
+                break;
+            case Texture::RGBA:
+                textureSize *= 4;
+                break;
+            case Texture::ALPHA:
+                break;
+        }
+        // Texture Cube
+        for (unsigned int i = 0; i < 6; i++)
+        {
+            GL_ASSERT( glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _width, _height, (GLenum)_format, GL_UNSIGNED_BYTE, &data[i * textureSize]) );
+        }
+    }
+
+    if (_mipmapped)
+    {
+        generateMipmaps();
+    }
+
+    // Restore the texture id
+    GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
+}
+
 // Computes the size of a PVRTC data chunk for a mipmap level of the given size.
 static unsigned int computePVRTCDataSize(int width, int height, int bpp)
 {
@@ -263,16 +366,18 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     GLenum format;
     GLubyte* data = NULL;
     unsigned int mipMapCount;
+    unsigned int faceCount;
+    GLenum faces[6] = { GL_TEXTURE_2D };
 
     if (version == 0x03525650)
     {
         // Modern PVR file format.
-        data = readCompressedPVRTC(path, stream.get(), &width, &height, &format, &mipMapCount);
+        data = readCompressedPVRTC(path, stream.get(), &width, &height, &format, &mipMapCount, &faceCount, faces);
     }
     else
     {
         // Legacy PVR file format.
-        data = readCompressedPVRTCLegacy(path, stream.get(), &width, &height, &format, &mipMapCount);
+        data = readCompressedPVRTCLegacy(path, stream.get(), &width, &height, &format, &mipMapCount, &faceCount, faces);
     }
     if (data == NULL)
     {
@@ -284,15 +389,17 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     int bpp = (format == GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG || format == GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG) ? 2 : 4;
 
     // Generate our texture.
+    GLenum target = faceCount > 1 ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
     GLuint textureId;
     GL_ASSERT( glGenTextures(1, &textureId) );
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) );
+    GL_ASSERT( glBindTexture(target, textureId) );
 
     Filter minFilter = mipMapCount > 1 ? NEAREST_MIPMAP_LINEAR : LINEAR;
-    GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter) );
+    GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter) );
 
     Texture* texture = new Texture();
     texture->_handle = textureId;
+    texture->_type = faceCount > 1 ? TEXTURE_CUBE : TEXTURE_2D;
     texture->_width = width;
     texture->_height = height;
     texture->_mipmapped = mipMapCount > 1;
@@ -305,28 +412,36 @@ Texture* Texture::createCompressedPVRTC(const char* path)
     {
         unsigned int dataSize = computePVRTCDataSize(width, height, bpp);
 
-        // Upload data to GL.
-        GL_ASSERT( glCompressedTexImage2D(GL_TEXTURE_2D, level, format, width, height, 0, dataSize, ptr) );
+        for (unsigned int face = 0; face < faceCount; ++face)
+        {
+            // Upload data to GL.
+            GL_ASSERT(glCompressedTexImage2D(faces[face], level, format, width, height, 0, dataSize, &ptr[face * dataSize]));
+        }
 
         width = std::max(width >> 1, 1);
         height = std::max(height >> 1, 1);
-        ptr += dataSize;
+        ptr += dataSize * faceCount;
     }
 
     // Free data.
     SAFE_DELETE_ARRAY(data);
 
+    // Restore the texture id
+    GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
+
     return texture;
 }
 
-GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount)
+GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum* faces)
 {
-    GP_ASSERT(stream);
-    GP_ASSERT(path);
-    GP_ASSERT(width);
-    GP_ASSERT(height);
-    GP_ASSERT(format);
-    GP_ASSERT(mipMapCount);
+    GP_ASSERT( stream );
+    GP_ASSERT( path );
+    GP_ASSERT( width );
+    GP_ASSERT( height );
+    GP_ASSERT( format );
+    GP_ASSERT( mipMapCount );
+    GP_ASSERT( faceCount );
+    GP_ASSERT( faces );
 
     struct pvrtc_file_header
     {
@@ -344,6 +459,13 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei*
         unsigned int metaDataSize;
     };
 
+    struct pvrtc_metadata
+    {
+        char fourCC[4];
+        unsigned int key;
+        unsigned int dataSize;
+    };
+
     size_t read;
 
     // Read header data.
@@ -390,12 +512,78 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei*
     *width = (GLsizei)header.width;
     *height = (GLsizei)header.height;
     *mipMapCount = header.mipMapCount;
+    *faceCount = std::min(header.faceCount, 6u);
 
-    // Skip meta-data.
-    if (stream->seek(header.metaDataSize, SEEK_CUR) == false)
+    if ((*faceCount) > 1)
     {
-        GP_ERROR("Failed to seek past header meta data in PVR file '%s'.", path);
-        return NULL;
+        // Look for cubemap metadata and setup faces
+        unsigned int remainingMetadata = header.metaDataSize;
+        pvrtc_metadata mdHeader;
+        bool foundTextureCubeMeta = false;
+        while (remainingMetadata > 0)
+        {
+            read = stream->read(&mdHeader, sizeof(pvrtc_metadata), 1);
+            if (read != 1)
+            {
+                GP_ERROR("Failed to read PVR metadata header data for file '%s'.", path);
+                return NULL;
+            }
+            remainingMetadata -= sizeof(pvrtc_metadata) + mdHeader.dataSize;
+
+            // Check that it's a known metadata type (specifically, cubemap order), otherwise skip to next metadata
+            if ((mdHeader.fourCC[0] != 'P') ||
+                (mdHeader.fourCC[1] != 'V') ||
+                (mdHeader.fourCC[2] != 'R') ||
+                (mdHeader.fourCC[3] != 3) ||
+                (mdHeader.key != 2) || // Everything except cubemap order (cubemap order key is 2)
+                (mdHeader.dataSize != 6)) // Cubemap order datasize should be 6
+            {
+                if (stream->seek(mdHeader.dataSize, SEEK_CUR) == false)
+                {
+                    GP_ERROR("Failed to seek to next meta data header in PVR file '%s'.", path);
+                    return NULL;
+                }
+                continue;
+            }
+
+            // Get cubemap order
+            foundTextureCubeMeta = true;
+            char faceOrder[6];
+            read = stream->read(faceOrder, 1, sizeof(faceOrder));
+            if (read != sizeof(faceOrder))
+            {
+                GP_ERROR("Failed to read cubemap face order meta data for file '%s'.", path);
+                return NULL;
+            }
+            for (unsigned int face = 0; face < (*faceCount); ++face)
+            {
+                faces[face] = GL_TEXTURE_CUBE_MAP_POSITIVE_X + (faceOrder[face] <= 'Z' ?
+                    ((faceOrder[face] - 'X') * 2) :
+                    (((faceOrder[face] - 'x') * 2) + 1));
+                if (faces[face] < GL_TEXTURE_CUBE_MAP_POSITIVE_X)
+                {
+                    // Just overwrite this face
+                    faces[face] = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+                }
+            }
+        }
+        if (!foundTextureCubeMeta)
+        {
+            // Didn't find cubemap metadata. Just assume it's "in order"
+            for (unsigned int face = 0; face < (*faceCount); ++face)
+            {
+                faces[face] = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+            }
+        }
+    }
+    else
+    {
+        // Skip meta-data.
+        if (stream->seek(header.metaDataSize, SEEK_CUR) == false)
+        {
+            GP_ERROR("Failed to seek past header meta data in PVR file '%s'.", path);
+            return NULL;
+        }
     }
 
     // Compute total size of data to be read.
@@ -404,7 +592,7 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei*
     size_t dataSize = 0;
     for (unsigned int level = 0; level < header.mipMapCount; ++level)
     {
-        dataSize += computePVRTCDataSize(w, h, bpp);
+        dataSize += computePVRTCDataSize(w, h, bpp) * (*faceCount);
         w = std::max(w>>1, 1);
         h = std::max(h>>1, 1);
     }
@@ -422,7 +610,7 @@ GLubyte* Texture::readCompressedPVRTC(const char* path, Stream* stream, GLsizei*
     return data;
 }
 
-GLubyte* Texture::readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount)
+GLubyte* Texture::readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum* faces)
 {
     char PVRTCIdentifier[] = "PVR!";
 
@@ -481,13 +669,32 @@ GLubyte* Texture::readCompressedPVRTCLegacy(const char* path, Stream* stream, GL
     *width = (GLsizei)header.width;
     *height = (GLsizei)header.height;
     *mipMapCount = header.mipmapCount + 1; // +1 because mipmapCount does not include the base level
+    *faceCount = 1;
 
-    GLubyte* data = new GLubyte[header.dataSize];
-    read = (int)stream->read(data, 1, header.dataSize);
-    if (read != header.dataSize)
+    // Flags (needed legacy documentation on format, pre-PVR Format 3.0)
+    if ((header.formatflags & 0x1000) != 0)
+    {
+        // Texture cube
+        *faceCount = std::min(header.surfaceCount, 6u);
+        for (unsigned int face = 0; face < (*faceCount); ++face)
+        {
+            faces[face] = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+        }
+    }
+    else if ((header.formatflags & 0x4000) != 0)
+    {
+        // Volume texture
+        GP_ERROR("Failed to load pvrtc file '%s': volume texture is not supported.", path);
+        return NULL;
+    }
+
+    unsigned int totalSize = header.dataSize; // Docs say dataSize is the size of the whole surface, or one face of a texture cube. But this does not appear to be the case with the latest PVRTexTool
+    GLubyte* data = new GLubyte[totalSize];
+    read = (int)stream->read(data, 1, totalSize);
+    if (read != totalSize)
     {
-        GP_ERROR("Failed to load texture data for pvrtc file '%s'.", path);
         SAFE_DELETE_ARRAY(data);
+        GP_ERROR("Failed to load texture data for pvrtc file '%s'.", path);
         return NULL;
     }
 
@@ -513,7 +720,7 @@ int Texture::getMaskByteIndex(unsigned int mask)
 
 Texture* Texture::createCompressedDDS(const char* path)
 {
-    GP_ASSERT(path);
+    GP_ASSERT( path );
 
     // DDS file structures.
     struct dds_pixel_format
@@ -586,9 +793,32 @@ Texture* Texture::createCompressedDDS(const char* path)
         header.dwMipMapCount = 1;
     }
 
+    // Check type of images. Default is a regular texture
+    unsigned int facecount = 1;
+    GLenum faces[6] = { GL_TEXTURE_2D };
+    GLenum target = GL_TEXTURE_2D;
+    if ((header.dwCaps2 & 0x200/*DDSCAPS2_CUBEMAP*/) != 0)
+    {
+        facecount = 0;
+        for (unsigned int off = 0, flag = 0x400/*DDSCAPS2_CUBEMAP_POSITIVEX*/; off < 6; ++off, flag <<= 1)
+        {
+            if ((header.dwCaps2 & flag) != 0)
+            {
+                faces[facecount++] = GL_TEXTURE_CUBE_MAP_POSITIVE_X + off;
+            }
+        }
+        target = GL_TEXTURE_CUBE_MAP;
+    }
+    else if ((header.dwCaps2 & 0x200000/*DDSCAPS2_VOLUME*/) != 0)
+    {
+        // Volume textures unsupported.
+        GP_ERROR("Failed to create texture from DDS file '%s': volume textures are unsupported.", path);
+        return NULL;
+    }
+
     // Allocate mip level structures.
-    dds_mip_level* mipLevels = new dds_mip_level[header.dwMipMapCount];
-    memset(mipLevels, 0, sizeof(dds_mip_level) * header.dwMipMapCount);
+    dds_mip_level* mipLevels = new dds_mip_level[header.dwMipMapCount * facecount];
+    memset(mipLevels, 0, sizeof(dds_mip_level) * header.dwMipMapCount * facecount);
 
     GLenum format = 0;
     GLenum internalFormat = 0;
@@ -639,28 +869,34 @@ Texture* Texture::createCompressedDDS(const char* path)
             return NULL;
         }
 
-        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+        for (unsigned int face = 0; face < facecount; ++face)
         {
-            dds_mip_level& level = mipLevels[i];
+            for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+            {
+                dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
 
-            level.width = width;
-            level.height = height;
-            level.size =  std::max(1, (width+3) >> 2) * std::max(1, (height+3) >> 2) * bytesPerBlock;
-            level.data = new GLubyte[level.size];
+                level.width = width;
+                level.height = height;
+                level.size = std::max(1, (width + 3) >> 2) * std::max(1, (height + 3) >> 2) * bytesPerBlock;
+                level.data = new GLubyte[level.size];
 
-            if (stream->read(level.data, 1, level.size) != (unsigned int)level.size)
-            {
-                GP_ERROR("Failed to load dds compressed texture bytes for texture: %s", path);
+                if (stream->read(level.data, 1, level.size) != (unsigned int)level.size)
+                {
+                    GP_ERROR("Failed to load dds compressed texture bytes for texture: %s", path);
+
+                    // Cleanup mip data.
+                    for (unsigned int face = 0; face < facecount; ++face)
+                        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+                            SAFE_DELETE_ARRAY(mipLevels[i + face * header.dwMipMapCount].data);
+                    SAFE_DELETE_ARRAY(mipLevels);
+                    return texture;
+                }
 
-                // Cleanup mip data.
-                for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
-                    SAFE_DELETE_ARRAY(level.data);
-                SAFE_DELETE_ARRAY(mipLevels);
-                return texture;
+                width = std::max(1, width >> 1);
+                height = std::max(1, height >> 1);
             }
-
-            width  = std::max(1, width >> 1);
-            height = std::max(1, height >> 1);
+            width = header.dwWidth;
+            height = header.dwHeight;
         }
     }
     else if (header.ddspf.dwFlags & 0x40/*DDPF_RGB*/)
@@ -710,28 +946,34 @@ Texture* Texture::createCompressedDDS(const char* path)
         }
 
         // Read data.
-        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+        for (unsigned int face = 0; face < facecount; ++face)
         {
-            dds_mip_level& level = mipLevels[i];
+            for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+            {
+                dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
 
-            level.width = width;
-            level.height = height;
-            level.size =  width * height * (header.ddspf.dwRGBBitCount >> 3);
-            level.data = new GLubyte[level.size];
+                level.width = width;
+                level.height = height;
+                level.size = width * height * (header.ddspf.dwRGBBitCount >> 3);
+                level.data = new GLubyte[level.size];
 
-            if (stream->read(level.data, 1, level.size) != (unsigned int)level.size)
-            {
-                GP_ERROR("Failed to load bytes for RGB dds texture: %s", path);
+                if (stream->read(level.data, 1, level.size) != (unsigned int)level.size)
+                {
+                    GP_ERROR("Failed to load bytes for RGB dds texture: %s", path);
+
+                    // Cleanup mip data.
+                    for (unsigned int face = 0; face < facecount; ++face)
+                        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+                            SAFE_DELETE_ARRAY(mipLevels[i + face * header.dwMipMapCount].data);
+                    SAFE_DELETE_ARRAY(mipLevels);
+                    return texture;
+                }
 
-                // Cleanup mip data.
-                for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
-                    SAFE_DELETE_ARRAY(level.data);
-                SAFE_DELETE_ARRAY(mipLevels);
-                return texture;
+                width = std::max(1, width >> 1);
+                height = std::max(1, height >> 1);
             }
-
-            width  = std::max(1, width >> 1);
-            height = std::max(1, height >> 1);
+            width = header.dwWidth;
+            height = header.dwHeight;
         }
 
         // Perform color conversion.
@@ -746,27 +988,33 @@ Texture* Texture::createCompressedDDS(const char* path)
             GLubyte *pixel, r, g, b, a;
             if (format == GL_RGB)
             {
-                for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+                for (unsigned int face = 0; face < facecount; ++face)
                 {
-                    dds_mip_level& level = mipLevels[i];
-                    for (int j = 0; j < level.size; j += 3)
+                    for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
                     {
-                        pixel = &level.data[j];
-                        r = pixel[ridx]; g = pixel[gidx]; b = pixel[bidx];
-                        pixel[0] = r; pixel[1] = g; pixel[2] = b;
+                        dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
+                        for (int j = 0; j < level.size; j += 3)
+                        {
+                            pixel = &level.data[j];
+                            r = pixel[ridx]; g = pixel[gidx]; b = pixel[bidx];
+                            pixel[0] = r; pixel[1] = g; pixel[2] = b;
+                        }
                     }
                 }
             }
             else if (format == GL_RGBA)
             {
-                for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+                for (unsigned int face = 0; face < facecount; ++face)
                 {
-                    dds_mip_level& level = mipLevels[i];
-                    for (int j = 0; j < level.size; j += 4)
+                    for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
                     {
-                        pixel = &level.data[j];
-                        r = pixel[ridx]; g = pixel[gidx]; b = pixel[bidx]; a = pixel[aidx];
-                        pixel[0] = r; pixel[1] = g; pixel[2] = b; pixel[3] = a;
+                        dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
+                        for (int j = 0; j < level.size; j += 4)
+                        {
+                            pixel = &level.data[j];
+                            r = pixel[ridx]; g = pixel[gidx]; b = pixel[bidx]; a = pixel[aidx];
+                            pixel[0] = r; pixel[1] = g; pixel[2] = b; pixel[3] = a;
+                        }
                     }
                 }
             }
@@ -786,14 +1034,15 @@ Texture* Texture::createCompressedDDS(const char* path)
     // Generate GL texture.
     GLuint textureId;
     GL_ASSERT( glGenTextures(1, &textureId) );
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) );
+    GL_ASSERT( glBindTexture(target, textureId) );
 
     Filter minFilter = header.dwMipMapCount > 1 ? NEAREST_MIPMAP_LINEAR : LINEAR;
-    GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter ) );
+    GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter ) );
 
     // Create gameplay texture.
     texture = new Texture();
     texture->_handle = textureId;
+    texture->_type = (Type)target;
     texture->_width = header.dwWidth;
     texture->_height = header.dwHeight;
     texture->_compressed = compressed;
@@ -801,25 +1050,32 @@ Texture* Texture::createCompressedDDS(const char* path)
     texture->_minFilter = minFilter;
 
     // Load texture data.
-    for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
+    for (unsigned int face = 0; face < facecount; ++face)
     {
-        dds_mip_level& level = mipLevels[i];
-        if (compressed)
-        {
-            GL_ASSERT( glCompressedTexImage2D(GL_TEXTURE_2D, i, format, level.width, level.height, 0, level.size, level.data) );
-        }
-        else
+        GLenum texImageTarget = faces[face];
+        for (unsigned int i = 0; i < header.dwMipMapCount; ++i)
         {
-            GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, i, internalFormat, level.width, level.height, 0, format, GL_UNSIGNED_BYTE, level.data) );
-        }
+            dds_mip_level& level = mipLevels[i + face * header.dwMipMapCount];
+            if (compressed)
+            {
+                GL_ASSERT(glCompressedTexImage2D(texImageTarget, i, format, level.width, level.height, 0, level.size, level.data));
+            }
+            else
+            {
+                GL_ASSERT(glTexImage2D(texImageTarget, i, internalFormat, level.width, level.height, 0, format, GL_UNSIGNED_BYTE, level.data));
+            }
 
-        // Clean up the texture data.
-        SAFE_DELETE_ARRAY(level.data);
+            // Clean up the texture data.
+            SAFE_DELETE_ARRAY(level.data);
+        }
     }
 
     // Clean up mip levels structure.
     SAFE_DELETE_ARRAY(mipLevels);
 
+    // Restore the texture id
+    GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
+
     return texture;
 }
 
@@ -828,6 +1084,11 @@ Texture::Format Texture::getFormat() const
     return _format;
 }
 
+Texture::Type Texture::getType() const
+{
+    return _type;
+}
+
 const char* Texture::getPath() const
 {
     return _path.c_str();
@@ -852,12 +1113,16 @@ void Texture::generateMipmaps()
 {
     if (!_mipmapped)
     {
-        GL_ASSERT( glBindTexture(GL_TEXTURE_2D, _handle) );
+        GLenum target = (GLenum)_type;
+        GL_ASSERT( glBindTexture(target, _handle) );
         GL_ASSERT( glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST) );
-        if (std::addressof(glGenerateMipmap))
-            GL_ASSERT( glGenerateMipmap(GL_TEXTURE_2D) );
+        if( std::addressof(glGenerateMipmap) )
+            GL_ASSERT( glGenerateMipmap(target) );
 
         _mipmapped = true;
+
+        // Restore the texture id
+        GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) );
     }
 }
 
@@ -872,9 +1137,9 @@ bool Texture::isCompressed() const
 }
 
 Texture::Sampler::Sampler(Texture* texture)
-    : _texture(texture), _wrapS(Texture::REPEAT), _wrapT(Texture::REPEAT)
+    : _texture(texture), _wrapS(Texture::REPEAT), _wrapT(Texture::REPEAT), _wrapR(Texture::REPEAT)
 {
-    GP_ASSERT(texture);
+    GP_ASSERT( texture );
     _minFilter = texture->_minFilter;
     _magFilter = texture->_magFilter;
 }
@@ -886,7 +1151,8 @@ Texture::Sampler::~Sampler()
 
 Texture::Sampler* Texture::Sampler::create(Texture* texture)
 {
-    GP_ASSERT(texture);
+    GP_ASSERT( texture );
+    GP_ASSERT( texture->_type == Texture::TEXTURE_2D || texture->_type == Texture::TEXTURE_CUBE );
     texture->addRef();
     return new Sampler(texture);
 }
@@ -897,10 +1163,11 @@ Texture::Sampler* Texture::Sampler::create(const char* path, bool generateMipmap
     return texture ? new Sampler(texture) : NULL;
 }
 
-void Texture::Sampler::setWrapMode(Wrap wrapS, Wrap wrapT)
+void Texture::Sampler::setWrapMode(Wrap wrapS, Wrap wrapT, Wrap wrapR)
 {
     _wrapS = wrapS;
     _wrapT = wrapT;
+    _wrapR = wrapR;
 }
 
 void Texture::Sampler::setFilterMode(Filter minificationFilter, Filter magnificationFilter)
@@ -916,33 +1183,48 @@ Texture* Texture::Sampler::getTexture() const
 
 void Texture::Sampler::bind()
 {
-    GP_ASSERT(_texture);
+    GP_ASSERT( _texture );
 
-    GL_ASSERT( glBindTexture(GL_TEXTURE_2D, _texture->_handle) );
+    GLenum target = (GLenum)_texture->_type;
+    if (__currentTextureId != _texture->_handle)
+    {
+        GL_ASSERT( glBindTexture(target, _texture->_handle) );
+        __currentTextureId = _texture->_handle;
+        __currentTextureType = _texture->_type;
+    }
 
     if (_texture->_minFilter != _minFilter)
     {
         _texture->_minFilter = _minFilter;
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLenum)_minFilter) );
+        GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, (GLenum)_minFilter) );
     }
 
     if (_texture->_magFilter != _magFilter)
     {
         _texture->_magFilter = _magFilter;
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLenum)_magFilter) );
+        GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MAG_FILTER, (GLenum)_magFilter) );
     }
 
     if (_texture->_wrapS != _wrapS)
     {
         _texture->_wrapS = _wrapS;
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLenum)_wrapS) );
+        GL_ASSERT( glTexParameteri(target, GL_TEXTURE_WRAP_S, (GLenum)_wrapS) );
     }
 
     if (_texture->_wrapT != _wrapT)
     {
         _texture->_wrapT = _wrapT;
-        GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLenum)_wrapT) );
+        GL_ASSERT( glTexParameteri(target, GL_TEXTURE_WRAP_T, (GLenum)_wrapT) );
     }
+
+#if defined(GL_TEXTURE_WRAP_R) // OpenGL ES 3.x and up, OpenGL 1.2 and up
+    if (_texture->_wrapR != _wrapR)
+    {
+        _texture->_wrapR = _wrapR;
+        if (target == GL_TEXTURE_CUBE_MAP) // We don't want to run this on something that we know will fail
+            GL_ASSERT( glTexParameteri(target, GL_TEXTURE_WRAP_R, (GLenum)_wrapR) );
+    }
+#endif
 }
 
 }

+ 52 - 7
gameplay/src/Texture.h

@@ -50,6 +50,28 @@ public:
         REPEAT = GL_REPEAT,
         CLAMP = GL_CLAMP_TO_EDGE
     };
+
+    /**
+     * Defines the type of Texture in use.
+     */
+    enum Type
+    {
+        TEXTURE_2D = GL_TEXTURE_2D,
+        TEXTURE_CUBE = GL_TEXTURE_CUBE_MAP
+    };
+
+    /**
+     * Defines a face of a Texture of Type: cube.
+     */
+    enum CubeFace
+    {
+        POSITIVE_X,
+        NEGATIVE_X,
+        POSITIVE_Y,
+        NEGATIVE_Y,
+        POSITIVE_Z,
+        NEGATIVE_Z
+    };
     
     /**
      * Defines a texture sampler.
@@ -96,8 +118,9 @@ public:
          *
          * @param wrapS The horizontal wrap mode.
          * @param wrapT The vertical wrap mode.
+         * @param wrapR The depth wrap mode.
          */
-        void setWrapMode(Wrap wrapS, Wrap wrapT);
+        void setWrapMode(Wrap wrapS, Wrap wrapT, Wrap wrapR = REPEAT);
 
         /**
          * Sets the texture filter modes for this sampler.
@@ -134,6 +157,7 @@ public:
         Texture* _texture;
         Wrap _wrapS;
         Wrap _wrapT;
+        Wrap _wrapR;
         Filter _minFilter;
         Filter _magFilter;
     };
@@ -169,15 +193,18 @@ public:
      * The data in the texture is expected to be tightly packed (no padding at the end of rows).
      *
      * @param format Format of the texture data.
-     * @param width Width of the texture data.
-     * @param height Height of the texture data.
-     * @param data Raw texture data (expected to be tightly packed).
+     * @param width Width of the texture data. If type is TEX_CUBE, then this is the cube face width.
+     * @param height Height of the texture data. If type is TEX_CUBE, then this is the cube face height.
+     * @param data Raw texture data (expected to be tightly packed). If the type parameter is set 
+     *   to TEXTURE_CUBE, then data is expected to be each face stored back contiguously within the
+     *   array.
      * @param generateMipmaps True to generate a full mipmap chain, false otherwise.
+     * @param type What type of Texture should be created.
      *
      * @return The new texture.
      * @script{create}
      */
-    static Texture* create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps = false);
+    static Texture* create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps = false, Type type = TEXTURE_2D);
 
     /**
      * Creates a texture object to wrap the specified pre-created native texture handle.
@@ -199,6 +226,15 @@ public:
      */
     static Texture* create(TextureHandle handle, int width, int height, Format format = UNKNOWN);
 
+    /**
+     * Set texture data to replace current texture image.
+     * 
+     * @param data Raw texture data (expected to be tightly packed). If the type parameter is set 
+     *   to TEXTURE_CUBE, then data is expected to be each face stored back contiguously within the
+     *   array.
+     */
+    void setData(const unsigned char* data);
+
     /**
      * Returns the path that the texture was originally loaded from (if applicable).
      *
@@ -213,6 +249,13 @@ public:
      */
     Format getFormat() const;
 
+    /**
+     * Gets the texture type.
+     *
+     * @return The texture type.
+     */
+    Type getType() const;
+
     /**
      * Gets the texture width.
      *
@@ -277,15 +320,16 @@ private:
 
     static Texture* createCompressedDDS(const char* path);
 
-    static GLubyte* readCompressedPVRTC(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount);
+    static GLubyte* readCompressedPVRTC(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum faces[6]);
 
-    static GLubyte* readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount);
+    static GLubyte* readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum faces[6]);
 
     static int getMaskByteIndex(unsigned int mask);
 
     std::string _path;
     TextureHandle _handle;
     Format _format;
+    Type _type;
     unsigned int _width;
     unsigned int _height;
     bool _mipmapped;
@@ -293,6 +337,7 @@ private:
     bool _compressed;
     Wrap _wrapS;
     Wrap _wrapT;
+    Wrap _wrapR;
     Filter _minFilter;
     Filter _magFilter;
 };

+ 114 - 32
gameplay/src/lua/lua_FrameBuffer.cpp

@@ -578,23 +578,23 @@ int lua_FrameBuffer_setRenderTarget(lua_State* state)
     {
         case 2:
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
+            do
             {
-                // Get parameter 1 off the stack.
-                bool param1Valid;
-                gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
-                if (!param1Valid)
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL))
                 {
-                    lua_pushstring(state, "Failed to convert parameter 1 to type 'RenderTarget'.");
-                    lua_error(state);
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    FrameBuffer* instance = getInstance(state);
+                    instance->setRenderTarget(param1);
+                    
+                    return 0;
                 }
-
-                FrameBuffer* instance = getInstance(state);
-                instance->setRenderTarget(param1);
-                
-                return 0;
-            }
+            } while (0);
 
             lua_pushstring(state, "lua_FrameBuffer_setRenderTarget - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
@@ -602,27 +602,81 @@ int lua_FrameBuffer_setRenderTarget(lua_State* state)
         }
         case 3:
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
-                lua_type(state, 3) == LUA_TNUMBER)
+            do
             {
-                // Get parameter 1 off the stack.
-                bool param1Valid;
-                gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
-                if (!param1Valid)
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER)
                 {
-                    lua_pushstring(state, "Failed to convert parameter 1 to type 'RenderTarget'.");
-                    lua_error(state);
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                    FrameBuffer* instance = getInstance(state);
+                    instance->setRenderTarget(param1, param2);
+                    
+                    return 0;
                 }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
 
-                // Get parameter 2 off the stack.
-                unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 3);
+                    // Get parameter 2 off the stack.
+                    Texture::CubeFace param2 = (Texture::CubeFace)luaL_checkint(state, 3);
 
-                FrameBuffer* instance = getInstance(state);
-                instance->setRenderTarget(param1, param2);
-                
-                return 0;
-            }
+                    FrameBuffer* instance = getInstance(state);
+                    instance->setRenderTarget(param1, param2);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_FrameBuffer_setRenderTarget - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 4:
+        {
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) &&
+                    lua_type(state, 3) == LUA_TNUMBER &&
+                    lua_type(state, 4) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1Valid;
+                    gameplay::ScriptUtil::LuaArray<RenderTarget> param1 = gameplay::ScriptUtil::getObjectPointer<RenderTarget>(2, "RenderTarget", false, &param1Valid);
+                    if (!param1Valid)
+                        break;
+
+                    // Get parameter 2 off the stack.
+                    Texture::CubeFace param2 = (Texture::CubeFace)luaL_checkint(state, 3);
+
+                    // Get parameter 3 off the stack.
+                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 4);
+
+                    FrameBuffer* instance = getInstance(state);
+                    instance->setRenderTarget(param1, param2, param3);
+                    
+                    return 0;
+                }
+            } while (0);
 
             lua_pushstring(state, "lua_FrameBuffer_setRenderTarget - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
@@ -630,7 +684,7 @@ int lua_FrameBuffer_setRenderTarget(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2, 3 or 4).");
             lua_error(state);
             break;
         }
@@ -790,9 +844,37 @@ int lua_FrameBuffer_static_createScreenshot(lua_State* state)
             return 1;
             break;
         }
+        case 1:
+        {
+            if (lua_type(state, 1) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                Image::Format param1 = (Image::Format)luaL_checkint(state, 1);
+
+                void* returnPtr = ((void*)FrameBuffer::createScreenshot(param1));
+                if (returnPtr)
+                {
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "Image");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FrameBuffer_static_createScreenshot - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_pushstring(state, "Invalid number of parameters (expected 0 or 1).");
             lua_error(state);
             break;
         }

+ 4 - 112
gameplay/src/lua/lua_Gamepad.cpp

@@ -22,12 +22,9 @@ void luaRegister_Gamepad()
         {"getForm", lua_Gamepad_getForm},
         {"getJoystickCount", lua_Gamepad_getJoystickCount},
         {"getJoystickValues", lua_Gamepad_getJoystickValues},
-        {"getProductId", lua_Gamepad_getProductId},
-        {"getProductString", lua_Gamepad_getProductString},
+        {"getName", lua_Gamepad_getName},
         {"getTriggerCount", lua_Gamepad_getTriggerCount},
         {"getTriggerValue", lua_Gamepad_getTriggerValue},
-        {"getVendorId", lua_Gamepad_getVendorId},
-        {"getVendorString", lua_Gamepad_getVendorString},
         {"isButtonDown", lua_Gamepad_isButtonDown},
         {"isVirtual", lua_Gamepad_isVirtual},
         {"update", lua_Gamepad_update},
@@ -238,7 +235,7 @@ int lua_Gamepad_getJoystickValues(lua_State* state)
     return 0;
 }
 
-int lua_Gamepad_getProductId(lua_State* state)
+int lua_Gamepad_getName(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -251,42 +248,7 @@ int lua_Gamepad_getProductId(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 Gamepad* instance = getInstance(state);
-                unsigned int result = instance->getProductId();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Gamepad_getProductId - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Gamepad_getProductString(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Gamepad* instance = getInstance(state);
-                const char* result = instance->getProductString();
+                const char* result = instance->getName();
 
                 // Push the return value onto the stack.
                 lua_pushstring(state, result);
@@ -294,7 +256,7 @@ int lua_Gamepad_getProductString(lua_State* state)
                 return 1;
             }
 
-            lua_pushstring(state, "lua_Gamepad_getProductString - Failed to match the given parameters to a valid function signature.");
+            lua_pushstring(state, "lua_Gamepad_getName - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             break;
         }
@@ -382,76 +344,6 @@ int lua_Gamepad_getTriggerValue(lua_State* state)
     return 0;
 }
 
-int lua_Gamepad_getVendorId(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Gamepad* instance = getInstance(state);
-                unsigned int result = instance->getVendorId();
-
-                // Push the return value onto the stack.
-                lua_pushunsigned(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Gamepad_getVendorId - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
-int lua_Gamepad_getVendorString(lua_State* state)
-{
-    // Get the number of parameters.
-    int paramCount = lua_gettop(state);
-
-    // Attempt to match the parameters to a valid binding.
-    switch (paramCount)
-    {
-        case 1:
-        {
-            if ((lua_type(state, 1) == LUA_TUSERDATA))
-            {
-                Gamepad* instance = getInstance(state);
-                const char* result = instance->getVendorString();
-
-                // Push the return value onto the stack.
-                lua_pushstring(state, result);
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Gamepad_getVendorString - Failed to match the given parameters to a valid function signature.");
-            lua_error(state);
-            break;
-        }
-        default:
-        {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
-            lua_error(state);
-            break;
-        }
-    }
-    return 0;
-}
-
 int lua_Gamepad_isButtonDown(lua_State* state)
 {
     // Get the number of parameters.

+ 1 - 4
gameplay/src/lua/lua_Gamepad.h

@@ -11,12 +11,9 @@ int lua_Gamepad_getButtonCount(lua_State* state);
 int lua_Gamepad_getForm(lua_State* state);
 int lua_Gamepad_getJoystickCount(lua_State* state);
 int lua_Gamepad_getJoystickValues(lua_State* state);
-int lua_Gamepad_getProductId(lua_State* state);
-int lua_Gamepad_getProductString(lua_State* state);
+int lua_Gamepad_getName(lua_State* state);
 int lua_Gamepad_getTriggerCount(lua_State* state);
 int lua_Gamepad_getTriggerValue(lua_State* state);
-int lua_Gamepad_getVendorId(lua_State* state);
-int lua_Gamepad_getVendorString(lua_State* state);
 int lua_Gamepad_isButtonDown(lua_State* state);
 int lua_Gamepad_isVirtual(lua_State* state);
 int lua_Gamepad_update(lua_State* state);

+ 23 - 9
gameplay/src/lua/lua_Global.cpp

@@ -423,14 +423,8 @@ void luaRegister_lua_Global()
         scopePath.push_back("Gamepad");
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_A, "BUTTON_A", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_B, "BUTTON_B", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_C, "BUTTON_C", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_X, "BUTTON_X", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_Y, "BUTTON_Y", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_Z, "BUTTON_Z", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_MENU1, "BUTTON_MENU1", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_MENU2, "BUTTON_MENU2", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_MENU3, "BUTTON_MENU3", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_MENU4, "BUTTON_MENU4", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_L1, "BUTTON_L1", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_L2, "BUTTON_L2", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_L3, "BUTTON_L3", scopePath);
@@ -441,6 +435,9 @@ void luaRegister_lua_Global()
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_DOWN, "BUTTON_DOWN", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_LEFT, "BUTTON_LEFT", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_RIGHT, "BUTTON_RIGHT", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_MENU1, "BUTTON_MENU1", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_MENU2, "BUTTON_MENU2", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_MENU3, "BUTTON_MENU3", scopePath);
     }
 
     // Register enumeration Gamepad::GamepadEvent.
@@ -449,9 +446,6 @@ void luaRegister_lua_Global()
         scopePath.push_back("Gamepad");
         gameplay::ScriptUtil::registerEnumValue(Gamepad::CONNECTED_EVENT, "CONNECTED_EVENT", scopePath);
         gameplay::ScriptUtil::registerEnumValue(Gamepad::DISCONNECTED_EVENT, "DISCONNECTED_EVENT", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::BUTTON_EVENT, "BUTTON_EVENT", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::JOYSTICK_EVENT, "JOYSTICK_EVENT", scopePath);
-        gameplay::ScriptUtil::registerEnumValue(Gamepad::TRIGGER_EVENT, "TRIGGER_EVENT", scopePath);
     }
 
     // Register enumeration Gesture::GestureEvent.
@@ -902,6 +896,18 @@ void luaRegister_lua_Global()
         gameplay::ScriptUtil::registerEnumValue(TextBox::PASSWORD, "PASSWORD", scopePath);
     }
 
+    // Register enumeration Texture::CubeFace.
+    {
+        std::vector<std::string> scopePath;
+        scopePath.push_back("Texture");
+        gameplay::ScriptUtil::registerEnumValue(Texture::POSITIVE_X, "POSITIVE_X", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Texture::NEGATIVE_X, "NEGATIVE_X", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Texture::POSITIVE_Y, "POSITIVE_Y", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Texture::NEGATIVE_Y, "NEGATIVE_Y", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Texture::POSITIVE_Z, "POSITIVE_Z", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Texture::NEGATIVE_Z, "NEGATIVE_Z", scopePath);
+    }
+
     // Register enumeration Texture::Filter.
     {
         std::vector<std::string> scopePath;
@@ -924,6 +930,14 @@ void luaRegister_lua_Global()
         gameplay::ScriptUtil::registerEnumValue(Texture::ALPHA, "ALPHA", scopePath);
     }
 
+    // Register enumeration Texture::Type.
+    {
+        std::vector<std::string> scopePath;
+        scopePath.push_back("Texture");
+        gameplay::ScriptUtil::registerEnumValue(Texture::TEXTURE_2D, "TEXTURE_2D", scopePath);
+        gameplay::ScriptUtil::registerEnumValue(Texture::TEXTURE_CUBE, "TEXTURE_CUBE", scopePath);
+    }
+
     // Register enumeration Texture::Wrap.
     {
         std::vector<std::string> scopePath;

+ 37 - 0
gameplay/src/lua/lua_Joint.cpp

@@ -155,6 +155,7 @@ void luaRegister_Joint()
         {"translateX", lua_Joint_translateX},
         {"translateY", lua_Joint_translateY},
         {"translateZ", lua_Joint_translateZ},
+        {"update", lua_Joint_update},
         {NULL, NULL}
     };
     const luaL_Reg lua_statics[] = 
@@ -7171,4 +7172,40 @@ int lua_Joint_translateZ(lua_State* state)
     return 0;
 }
 
+int lua_Joint_update(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Joint* instance = getInstance(state);
+                instance->update(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Joint_update - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 }

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

@@ -150,6 +150,7 @@ int lua_Joint_translateUp(lua_State* state);
 int lua_Joint_translateX(lua_State* state);
 int lua_Joint_translateY(lua_State* state);
 int lua_Joint_translateZ(lua_State* state);
+int lua_Joint_update(lua_State* state);
 
 void luaRegister_Joint();
 

+ 37 - 0
gameplay/src/lua/lua_Node.cpp

@@ -153,6 +153,7 @@ void luaRegister_Node()
         {"translateX", lua_Node_translateX},
         {"translateY", lua_Node_translateY},
         {"translateZ", lua_Node_translateZ},
+        {"update", lua_Node_update},
         {NULL, NULL}
     };
     const luaL_Reg lua_statics[] = 
@@ -7191,4 +7192,40 @@ int lua_Node_translateZ(lua_State* state)
     return 0;
 }
 
+int lua_Node_update(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Node* instance = getInstance(state);
+                instance->update(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Node_update - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 }

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

@@ -150,6 +150,7 @@ int lua_Node_translateUp(lua_State* state);
 int lua_Node_translateX(lua_State* state);
 int lua_Node_translateY(lua_State* state);
 int lua_Node_translateZ(lua_State* state);
+int lua_Node_update(lua_State* state);
 
 void luaRegister_Node();
 

+ 37 - 0
gameplay/src/lua/lua_Scene.cpp

@@ -38,6 +38,7 @@ void luaRegister_Scene()
         {"setActiveCamera", lua_Scene_setActiveCamera},
         {"setAmbientColor", lua_Scene_setAmbientColor},
         {"setId", lua_Scene_setId},
+        {"update", lua_Scene_update},
         {"visit", lua_Scene_visit},
         {NULL, NULL}
     };
@@ -1101,6 +1102,42 @@ int lua_Scene_static_load(lua_State* state)
     return 0;
 }
 
+int lua_Scene_update(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Scene* instance = getInstance(state);
+                instance->update(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Scene_update - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Scene_visit(lua_State* state)
 {
     // Get the number of parameters.

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

@@ -28,6 +28,7 @@ int lua_Scene_setId(lua_State* state);
 int lua_Scene_static_create(lua_State* state);
 int lua_Scene_static_getScene(lua_State* state);
 int lua_Scene_static_load(lua_State* state);
+int lua_Scene_update(lua_State* state);
 int lua_Scene_visit(lua_State* state);
 
 void luaRegister_Scene();

+ 125 - 1
gameplay/src/lua/lua_Texture.cpp

@@ -23,10 +23,12 @@ void luaRegister_Texture()
         {"getHeight", lua_Texture_getHeight},
         {"getPath", lua_Texture_getPath},
         {"getRefCount", lua_Texture_getRefCount},
+        {"getType", lua_Texture_getType},
         {"getWidth", lua_Texture_getWidth},
         {"isCompressed", lua_Texture_isCompressed},
         {"isMipmapped", lua_Texture_isMipmapped},
         {"release", lua_Texture_release},
+        {"setData", lua_Texture_setData},
         {NULL, NULL}
     };
     const luaL_Reg lua_statics[] = 
@@ -332,6 +334,41 @@ int lua_Texture_getRefCount(lua_State* state)
     return 0;
 }
 
+int lua_Texture_getType(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Texture* instance = getInstance(state);
+                Texture::Type result = instance->getType();
+
+                // Push the return value onto the stack.
+                lua_pushnumber(state, (int)result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Texture_getType - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Texture_getWidth(lua_State* state)
 {
     // Get the number of parameters.
@@ -469,6 +506,42 @@ int lua_Texture_release(lua_State* state)
     return 0;
 }
 
+int lua_Texture_setData(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                (lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TLIGHTUSERDATA))
+            {
+                // Get parameter 1 off the stack.
+                gameplay::ScriptUtil::LuaArray<unsigned char> param1 = gameplay::ScriptUtil::getUnsignedCharPointer(2);
+
+                Texture* instance = getInstance(state);
+                instance->setData(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Texture_setData - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Texture_static_create(lua_State* state)
 {
     // Get the number of parameters.
@@ -775,9 +848,60 @@ int lua_Texture_static_create(lua_State* state)
             lua_error(state);
             break;
         }
+        case 6:
+        {
+            do
+            {
+                if (lua_type(state, 1) == LUA_TNUMBER &&
+                    lua_type(state, 2) == LUA_TNUMBER &&
+                    lua_type(state, 3) == LUA_TNUMBER &&
+                    (lua_type(state, 4) == LUA_TTABLE || lua_type(state, 4) == LUA_TLIGHTUSERDATA) &&
+                    lua_type(state, 5) == LUA_TBOOLEAN &&
+                    lua_type(state, 6) == LUA_TNUMBER)
+                {
+                    // Get parameter 1 off the stack.
+                    Texture::Format param1 = (Texture::Format)luaL_checkint(state, 1);
+
+                    // Get parameter 2 off the stack.
+                    unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                    // Get parameter 3 off the stack.
+                    unsigned int param3 = (unsigned int)luaL_checkunsigned(state, 3);
+
+                    // Get parameter 4 off the stack.
+                    gameplay::ScriptUtil::LuaArray<unsigned char> param4 = gameplay::ScriptUtil::getUnsignedCharPointer(4);
+
+                    // Get parameter 5 off the stack.
+                    bool param5 = gameplay::ScriptUtil::luaCheckBool(state, 5);
+
+                    // Get parameter 6 off the stack.
+                    Texture::Type param6 = (Texture::Type)luaL_checkint(state, 6);
+
+                    void* returnPtr = ((void*)Texture::create(param1, param2, param3, param4, param5, param6));
+                    if (returnPtr)
+                    {
+                        gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Texture");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Texture_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 1, 2, 3, 4 or 5).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1, 2, 3, 4, 5 or 6).");
             lua_error(state);
             break;
         }

+ 2 - 0
gameplay/src/lua/lua_Texture.h

@@ -14,10 +14,12 @@ int lua_Texture_getHandle(lua_State* state);
 int lua_Texture_getHeight(lua_State* state);
 int lua_Texture_getPath(lua_State* state);
 int lua_Texture_getRefCount(lua_State* state);
+int lua_Texture_getType(lua_State* state);
 int lua_Texture_getWidth(lua_State* state);
 int lua_Texture_isCompressed(lua_State* state);
 int lua_Texture_isMipmapped(lua_State* state);
 int lua_Texture_release(lua_State* state);
+int lua_Texture_setData(lua_State* state);
 int lua_Texture_static_create(lua_State* state);
 
 void luaRegister_Texture();

+ 27 - 1
gameplay/src/lua/lua_TextureSampler.cpp

@@ -326,9 +326,35 @@ int lua_TextureSampler_setWrapMode(lua_State* state)
             lua_error(state);
             break;
         }
+        case 4:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER &&
+                lua_type(state, 4) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                Texture::Wrap param1 = (Texture::Wrap)luaL_checkint(state, 2);
+
+                // Get parameter 2 off the stack.
+                Texture::Wrap param2 = (Texture::Wrap)luaL_checkint(state, 3);
+
+                // Get parameter 3 off the stack.
+                Texture::Wrap param3 = (Texture::Wrap)luaL_checkint(state, 4);
+
+                Texture::Sampler* instance = getInstance(state);
+                instance->setWrapMode(param1, param2, param3);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_TextureSampler_setWrapMode - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 3).");
+            lua_pushstring(state, "Invalid number of parameters (expected 3 or 4).");
             lua_error(state);
             break;
         }

+ 127 - 0
gameplay/src/org/gameplay3d/GameNativeActivity.java

@@ -0,0 +1,127 @@
+package org.gameplay3d;
+
+import android.app.NativeActivity;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.hardware.input.InputManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * Game extension for Android platform.
+ * 
+ * Handles any platform features that cannot be handled natively in PlatformAndroid.cpp 
+ * 
+ * Developers may choose to directly modify/extend this for any addition platform features 
+ * that are not offered directly the gameplay3d framework such as platform events, access to 
+ * android user-interface, life-cycle events for saving game state and custom plug-ins/extensions.
+ */
+public class GameNativeActivity extends NativeActivity
+    implements InputManager.InputDeviceListener {
+    
+    static {
+        System.loadLibrary("gameplay");
+    }
+    
+    private static final String TAG = "GameNativeActivity";
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        Log.i(TAG, "onCreate");
+        super.onCreate(savedInstanceState);
+        _gamepadDevices = new SparseArray<InputDevice>();
+        _inputManager = (InputManager)getSystemService(Context.INPUT_SERVICE);
+
+        View decorView = getWindow().getDecorView();
+        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
+        if (Build.VERSION.SDK_INT >= 18) 
+            uiOptions ^= 0x00000800; // View.SYSTEM_UI_FLAG_IMMERSIVE;
+        decorView.setSystemUiVisibility(uiOptions);
+    }
+    
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+    }
+    
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+    } 
+    
+    @Override
+    protected void onResume() {
+        super.onResume();
+        _inputManager.registerInputDeviceListener(this, null);
+        int[] ids = InputDevice.getDeviceIds();
+        for (int i = 0; i < ids.length; i++) {
+            getGamepadDevice(ids[i]);
+        }
+    }
+    
+    @Override
+    protected void onPause() {
+        _inputManager.unregisterInputDeviceListener(this);
+        super.onPause();
+    }
+    
+    @Override
+    public void onInputDeviceAdded(int deviceId) {
+        getGamepadDevice(deviceId);
+    }
+
+    @Override
+    public void onInputDeviceRemoved(int deviceId) {
+        InputDevice device = _gamepadDevices.get(deviceId);
+        if (device != null) {
+            _gamepadDevices.remove(deviceId);
+            Log.v(TAG, "Gamepad disconnected:id=" + deviceId);
+            gamepadEventDisconnectedImpl(deviceId);
+        }
+    }
+    
+    @Override
+    public void onInputDeviceChanged(int deviceId) {
+    }
+    
+    private void onGamepadConnected(int deviceId, String deviceName) {
+        int buttonCount = 17;
+        int joystickCount = 2;
+        int triggerCount = 2;
+        
+        Log.v(TAG, "Gamepad connected:id=" + deviceId + ", name=" + deviceName);
+        
+        gamepadEventConnectedImpl(deviceId, buttonCount, joystickCount, triggerCount, deviceName);
+    }
+    
+    private InputDevice getGamepadDevice(int deviceId) {
+        InputDevice device = _gamepadDevices.get(deviceId);
+        if (device == null) {
+            device = InputDevice.getDevice(deviceId);
+            if (device == null)
+                return null;
+            int sources = device.getSources();
+            if (((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) || 
+                ((sources & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK)) {
+                _gamepadDevices.put(deviceId, device);
+                
+                onGamepadConnected(deviceId, device.getName());
+            }
+        }
+        return device;
+    }
+    
+    
+    // JNI calls to PlatformAndroid.cpp
+    private static native void gamepadEventConnectedImpl(int deviceId, int buttonCount, int joystickCount, int triggerCount, String deviceName);
+    private static native void gamepadEventDisconnectedImpl(int deviceId);
+    
+    private InputManager _inputManager;
+    private SparseArray<InputDevice> _gamepadDevices;
+}

+ 38 - 52
newproject.bat

@@ -2,7 +2,7 @@
 
 REM ********************************************************************
 REM
-REM generate-project.bat
+REM newproject.bat
 REM
 REM This windows batch script generates a set of gameplay project files.
 REM The new project will be based of the template project and 
@@ -20,6 +20,7 @@ echo.
 echo    This name will be given to the project 
 echo    executable and a folder with this name
 echo    will be created to store all project files.
+echo    Ex. foobar
 echo.
 set /p projName=Project name: 
 if "%projName%" == "" (
@@ -37,6 +38,7 @@ echo.
 echo    On some platforms, this title is used to
 echo    identify the game during installation and
 echo    on shortcuts/icons.
+echo    Ex. Foo Bar
 echo.
 set /p title=Title: 
 if "%title%" == "" (
@@ -49,20 +51,12 @@ if "%title%" == "" (
 echo.
 
 echo.
-echo 3. Enter a short game description.
-echo.
-set /p desc=Description: 
-if "%desc%" == "" (
-    set desc=%title%
-)
-echo.
-
-echo.
-echo 4. Enter a unique identifier for your project.
+echo 3. Enter a unique identifier for your project.
 echo.
 echo    This should be a human readable package name,
 echo    containing at least two words separated by a
-echo    period (eg. com.surname.gamename).
+echo    period.
+echo    Ex. com.example.foobar
 echo.
 set /p uuid=Unique ID: 
 if "%uuid%" == "" (
@@ -75,28 +69,12 @@ if "%uuid%" == "" (
 echo.
 
 echo.
-echo 5. Enter author name.
-echo.
-echo    On BlackBerry targets, this is used for
-echo    signing and must match the developer name
-echo    of your development certificate.
-echo.
-set /p author=Author: 
-if "%author%" == "" (
-    echo.
-    echo ERROR: No author specified.
-    echo.
-    pause
-    goto done
-)
-echo.
-
-echo.
-echo 6. Enter your game's main class name.
+echo 4. Enter your game's main class name.
 echo.
 echo    Your initial game header and source file
 echo    will be given this name and a class with 
 echo    this name will be created in these files.
+echo    Ex. FooBarGame
 echo.
 set /p className=Class name: 
 if "%className%" == "" (
@@ -109,12 +87,13 @@ if "%className%" == "" (
 echo.
 
 echo.
-echo 7. Enter the project path.
+echo 5. Enter the project path.
 echo.
 echo    This can be a relative path, absolute path,
 echo    or empty for the current folder. Note that
 echo    a project folder named %projName% will also
 echo    be created inside this folder.
+echo    Ex. ./samples
 echo.
 set /p location=Path: 
 if "%location%" == "" (
@@ -180,47 +159,31 @@ call:replace "%projPath%\%projName%.xcodeproj\project.pbxproj" TEMPLATE_PROJECT
 
 copy template\TEMPLATE_PROJECT-macosx.plist "%projPath%\%projName%-macosx.plist"
 call:replace "%projPath%\%projName%-macosx.plist" TEMPLATE_UUID "%uuid%"
-call:replace "%projPath%\%projName%-macosx.plist" TEMPLATE_AUTHOR "%author%"
 
 copy template\TEMPLATE_PROJECT-ios.plist "%projPath%\%projName%-ios.plist"
 copy 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%"
-
-REM Copy BlackBerry NDK project files
-copy template\template.cproject "%projPath%\.cproject"
-call:replace "%projPath%\.cproject" TEMPLATE_PROJECT "%projName%"
-call:replace "%projPath%\.cproject" TEMPLATE_UUID "%uuid%"
-call:replace "%projPath%\.cproject" GAMEPLAY_PATH "%gpPath%"
-
-copy template\template.project "%projPath%\.project"
-call:replace "%projPath%\.project" TEMPLATE_PROJECT "%projName%"
 
-copy template\template.bar-descriptor.xml "%projPath%\bar-descriptor.xml"
-call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_PROJECT "%projName%"
-call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_TITLE "%title%"
-call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_UUID "%uuid%"
-call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_AUTHOR "%author%"
-call:replace "%projPath%\bar-descriptor.xml" TEMPLATE_DESCRIPTION "%desc%"
-call:replace "%projPath%\bar-descriptor.xml" GAMEPLAY_PATH "%gpPath%"
 
 REM Copy Android NDK project files
 mkdir "%projPath%\android"
 
-copy template\android\template.AndroidManifest.xml "%projPath%\android\AndroidManifest.xml"
+copy template\android\AndroidManifest.xml "%projPath%\android\AndroidManifest.xml"
 call:replace "%projPath%\android\AndroidManifest.xml" TEMPLATE_PROJECT "%projName%"
 call:replace "%projPath%\android\AndroidManifest.xml" TEMPLATE_UUID "%uuid%"
 
-copy template\android\template.build.xml "%projPath%\android\build.xml"
+copy template\android\build.xml "%projPath%\android\build.xml"
 call:replace "%projPath%\android\build.xml" TEMPLATE_PROJECT "%projName%"
 call:replace "%projPath%\android\build.xml" GAMEPLAY_PATH "%gpPath%"
 
+copy template\android\project.properties "%projPath%\android\project.properties"
+
 mkdir "%projPath%\android\jni"
 
 copy template\android\jni\Application.mk "%projPath%\android\jni\Application.mk"
 
-copy template\android\jni\template.Android.mk "%projPath%\android\jni\Android.mk"
+copy template\android\jni\Android.mk "%projPath%\android\jni\Android.mk"
 call:replace "%projPath%\android\jni\Android.mk" TemplateGame "%className%"
 call:replace "%projPath%\android\jni\Android.mk" TEMPLATE_PROJECT "%projName%"
 call:replace "%projPath%\android\jni\Android.mk" GAMEPLAY_PATH "%gpPath%"
@@ -234,6 +197,29 @@ mkdir "%projPath%\android\res\values"
 copy template\android\res\values\template.strings.xml "%projPath%\android\res\values\strings.xml"
 call:replace "%projPath%\android\res\values\strings.xml" TEMPLATE_TITLE "%title%"
 
+REM Copy Android Eclipse files
+copy template\android\.cproject "%projPath%\android\.cproject"
+call:replace "%projPath%\android\.cproject" TEMPLATE_PROJECT "%projName%"
+call:replace "%projPath%\android\.cproject" TEMPLATE_UUID "%uuid%"
+call:replace "%projPath%\android\.cproject" GAMEPLAY_PATH "%gpPath%"
+
+copy template\android\.project "%projPath%\android\.project"
+call:replace "%projPath%\android\.project" TEMPLATE_PROJECT "%projName%"
+
+copy template\android\.classpath "%projPath%\android\.classpath"
+call:replace "%projPath%\android\.classpath" TEMPLATE_PROJECT "%projName%"
+
+REM Copy Linux Eclipse files
+copy template\.cproject "%projPath%\.cproject"
+call:replace "%projPath%\.cproject" TEMPLATE_PROJECT "%projName%"
+call:replace "%projPath%\.cproject" TEMPLATE_UUID "%uuid%"
+call:replace "%projPath%\.cproject" GAMEPLAY_PATH "%gpPath%"
+
+copy template\.project "%projPath%\.project"
+call:replace "%projPath%\.project" TEMPLATE_PROJECT "%projName%"
+
+
+REM Copy CMake files
 mkdir "%projPath%\build"
 copy "template\template-CMakeLists.txt" "%projPath%\CMakeLists.txt"
 call:replace "%projPath%\CMakeLists.txt" TEMPLATE_PROJECT %projName%

+ 43 - 55
newproject.sh

@@ -27,13 +27,13 @@ else
 	alias aliassedinplace='sed -i""'
 fi
 
-
 echo
 echo "1. Enter a name for the new project."
 echo
 echo "   This name will be given to the project"
 echo "   executable and a folder with this name"
 echo "   will be created to store all project files."
+echo "   Ex. foobar"
 echo
 read -p "Project Name: " projName 
 if [[ "$projName" == "" ]]; then
@@ -42,13 +42,15 @@ if [[ "$projName" == "" ]]; then
 	echo
 	exit -1;
 fi
-echo 
+echo
+
 echo
 echo "2. Enter a game title."
 echo
 echo "   On some platforms, this title is used to"
 echo "   identify the game during installation and"
 echo "   on shortcuts/icons."
+echo "   Ex. Foo Bar"
 echo
 read -p "Title: " title 
 if [[ "$title" == "" ]]; then
@@ -60,20 +62,12 @@ fi
 echo 
 
 echo
-echo "3. Enter a short game description."
-echo
-read -p "Description: " desc
-if [[ "$desc" == "" ]]; then
-	desc=$title
-fi
-echo 
-
-echo
-echo "4. Enter a unique identifier for your project."
+echo "3. Enter a unique identifier for your project."
 echo
 echo "   This should be a human readable package name,"
 echo "   containing at least two words separated by a"
-echo "   period (eg. com.surname.gamename)."
+echo "   period."
+echo "   Ex. com.example.foobar"
 echo
 read -p "Unique ID: " uuid
 if [[ "$uuid" == "" ]]; then
@@ -82,30 +76,15 @@ if [[ "$uuid" == "" ]]; then
 	echo
 	exit -1;
 fi
-echo 
-
 echo
-echo "5. Enter author name."
-echo
-echo "   On BlackBerry targets, this is used for"
-echo "   signing and must match the developer name"
-echo "   of your development certificate."
-echo
-read -p "Author: " author
-if [[ "$author" == "" ]]; then
-	echo
-	echo "ERROR: No author specified."
-	echo
-	exit -1;
-fi
-echo 
 
 echo
-echo "6. Enter your game's main class name."
+echo "4. Enter your game's main class name."
 echo
 echo "   Your initial game header and source file"
 echo "   will be given this name and a class with"
 echo "   this name will be created in these files."
+echo "   Ex. FooBarGame"
 echo
 read -p "Class name: " className
 if [[ "$className" == "" ]]; then
@@ -117,12 +96,13 @@ fi
 echo 
 
 echo
-echo "7. Enter the project path."
+echo "5. Enter the project path."
 echo
 echo "   This can be a relative path, absolute path,"
 echo "   or empty for the current folder. Note that"
 echo "   a project folder named $projName will also"
 echo "   be created inside this folder."
+echo "   Ex. ./samples"
 echo
 read -p "Path: " location
 if [[ "$location" == "" ]]; then
@@ -197,32 +177,11 @@ aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/$projName.xcodeproj/proje
 
 cp "template/TEMPLATE_PROJECT-macosx.plist" "$projPath/$projName-macosx.plist"
 aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/$projName-macosx.plist"
-aliassedinplace "s*TEMPLATE_AUTHOR*$author*g" "$projPath/$projName-macosx.plist"
 
 cp "template/TEMPLATE_PROJECT-ios.plist" "$projPath/$projName-ios.plist"
 cp "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"
-
-#############################################
-# Copy BlackBerry NDK project files
-#############################################
-cp "template/template.cproject" "$projPath/.cproject"
-aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/.cproject"
-aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/.cproject"
-aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/.cproject"
-
-cp "template/template.project" "$projPath/.project"
-aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/.project"
-
-cp "template/template.bar-descriptor.xml" "$projPath/bar-descriptor.xml"
-aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/bar-descriptor.xml"
-aliassedinplace "s*TEMPLATE_TITLE*$title*g" "$projPath/bar-descriptor.xml"
-aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/bar-descriptor.xml"
-aliassedinplace "s*TEMPLATE_AUTHOR*$author*g" "$projPath/bar-descriptor.xml"
-aliassedinplace "s*TEMPLATE_DESCRIPTION*$desc*g" "$projPath/bar-descriptor.xml"
-aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/bar-descriptor.xml"
 
 #############################################
 # Copy Android NDK project files
@@ -232,16 +191,18 @@ mkdir -p "$projPath/android/jni"
 mkdir -p "$projPath/android/res/values"
 mkdir -p "$projPath/android/res/drawable"
 
-cp "template/android/template.AndroidManifest.xml" "$projPath/android/AndroidManifest.xml"
+cp "template/android/AndroidManifest.xml" "$projPath/android/AndroidManifest.xml"
 aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/AndroidManifest.xml"
 aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/android/AndroidManifest.xml"
 
-cp "template/android/template.build.xml" "$projPath/android/build.xml"
+cp "template/android/build.xml" "$projPath/android/build.xml"
 aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/build.xml"
 aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/android/build.xml"
 
+cp "template/android/project.properties" "$projPath/android/project.properties"
+
 cp "template/android/jni/Application.mk" "$projPath/android/jni/Application.mk"
-cp "template/android/jni/template.Android.mk" "$projPath/android/jni/Android.mk"
+cp "template/android/jni/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"
@@ -250,6 +211,32 @@ cp "template/icon.png" "$projPath/android/res/drawable/icon.png"
 cp "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 Android Eclipse files
+#############################################
+cp "template/android/.cproject" "$projPath/android/.cproject"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/.cproject"
+aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/android/.cproject"
+aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/android/.cproject"
+
+cp "template/android/.project" "$projPath/android/.project"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/.project"
+
+cp "template/android/.classpath" "$projPath/android/.classpath"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/android/.classpath"
+
+#############################################
+# Copy Linux Eclipse files
+#############################################
+
+cp "template/.cproject" "$projPath/.cproject"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/.cproject"
+aliassedinplace "s*TEMPLATE_UUID*$uuid*g" "$projPath/.cproject"
+aliassedinplace "s*GAMEPLAY_PATH*$gpPath*g" "$projPath/.cproject"
+
+cp "template/.project" "$projPath/.project"
+aliassedinplace "s*TEMPLATE_PROJECT*$projName*g" "$projPath/.project"
+
 #############################################
 # Copy CMake files
 #############################################
@@ -259,6 +246,7 @@ 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
 #############################################

+ 3 - 0
samples/browser/android/.cproject

@@ -55,4 +55,7 @@
 		</configuration>
 	</storageModule>
 	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+	<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
+		<buildTargets/>
+	</storageModule>
 </cproject>

+ 49 - 1
samples/browser/android/.project

@@ -10,6 +10,54 @@
 			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
 			<triggers>clean,full,incremental,</triggers>
 			<arguments>
+				<dictionary>
+					<key>?children?</key>
+					<value>?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\||</value>
+				</dictionary>
+				<dictionary>
+					<key>?name?</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.append_environment</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildArguments</key>
+					<value>NDK_DEBUG=1 -j4</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildCommand</key>
+					<value>ndk-build</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+					<value>clean</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.contents</key>
+					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.stopOnError</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+					<value>false</value>
+				</dictionary>
 			</arguments>
 		</buildCommand>
 		<buildCommand>
@@ -51,7 +99,7 @@
 		<link>
 			<name>src</name>
 			<type>2</type>
-			<location>$%7BPARENT-2-PROJECT_LOC%7D/browser/src</location>
+			<locationURI>$%257BPARENT-2-PROJECT_LOC%257D/browser/src</locationURI>
 		</link>
 	</linkedResources>
 </projectDescription>

+ 4 - 4
samples/browser/android/AndroidManifest.xml

@@ -4,14 +4,14 @@
         android:versionCode="1"
         android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="15" />
-	<uses-feature android:glEsVersion="0x00020000"/>
+    <uses-sdk android:minSdkVersion="16" />
+    <uses-feature android:glEsVersion="0x00020000"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="true">
-        <activity android:name="android.app.NativeActivity"
+        <activity android:name="org.gameplay3d.GameNativeActivity"
                   android:label="@string/app_name"
-                  android:configChanges="screenSize|orientation|keyboardHidden"
+                  android:configChanges="orientation|keyboardHidden"
 				  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
 				  android:screenOrientation="landscape">
             <meta-data android:name="android.app.lib_name" android:value="sample-browser" />

+ 32 - 5
samples/browser/android/build.xml

@@ -6,10 +6,40 @@
     
     <loadproperties srcFile="project.properties" />
     
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'" unless="sdk.dir" />
+    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project -t 1 -p . -s'" unless="sdk.dir" />
+	<fail message="OS not supported. Supported platforms: Windows, MacOS X or Linux.">
+	    <condition>
+	      <not>
+	        <or>
+	          <os family="unix"/>
+	          <os family="windows"/>
+	        </or>
+	      </not>
+	    </condition>
+	</fail>
+	<macrodef name="build-native">
+		<attribute name="location"/>
+	     <sequential>
+            <exec osfamily="unix" dir="@{location}/android" executable="ndk-build">
+                <arg value="-j4"/>
+            </exec>
+			<exec osfamily="windows" dir="@{location}/android" executable="cmd">
+				<arg value="/c"/>
+				<arg value="ndk-build -j4"/>
+			</exec> 
+	    </sequential>
+	</macrodef>
 
     <target name="-pre-build">
-        <mkdir dir="src"/>
+		<build-native location="../../../gameplay"/>
+    	<build-native location=".."/>
+        <mkdir dir="../src/org/gameplay3d"/>
+	    <copy todir="../src/org/gameplay3d">
+            <fileset dir="../../../gameplay/src/org/gameplay3d"/>
+	    </copy>
+    </target>
+	
+    <target name="-post-compile">
         <copy file="../game.config" tofile="assets/game.config"/>
         <copy todir="assets/res/common">
             <fileset dir="../res/common"/>
@@ -25,9 +55,6 @@
             <fileset dir="../../../gameplay/res/ui"/>
         </copy>
     </target>
-	
-    <target name="-post-compile">
-    </target>
 
     <!-- version-tag: 1 -->
     <import file="${sdk.dir}/tools/ant/build.xml" />

+ 7 - 6
samples/browser/android/jni/Android.mk

@@ -9,12 +9,12 @@ OGG_PATH := $(call my-dir)/../../../../external-deps/ogg/lib/android/arm
 VORBIS_PATH := $(call my-dir)/../../../../external-deps/vorbis/lib/android/arm
 OPENAL_PATH := $(call my-dir)/../../../../external-deps/openal/lib/android/arm
 
-# gameplay
-LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/obj/local/armeabi-v7a
+# libgameplay
+LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/libs/armeabi-v7a
 include $(CLEAR_VARS)
 LOCAL_MODULE    := libgameplay
-LOCAL_SRC_FILES := libgameplay.a
-include $(PREBUILT_STATIC_LIBRARY)
+LOCAL_SRC_FILES := libgameplay.so
+include $(PREBUILT_SHARED_LIBRARY)
 
 # libpng
 LOCAL_PATH := $(PNG_PATH)
@@ -112,7 +112,8 @@ LOCAL_CPPFLAGS += -std=c++11 -Wno-switch-enum -Wno-switch
 LOCAL_ARM_MODE := arm
 LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv2 -lOpenSLES
 LOCAL_CFLAGS    := -D__ANDROID__ -I"../../../external-deps/lua/include" -I"../../../external-deps/bullet/include" -I"../../../external-deps/png/include" -I"../../../external-deps/ogg/include" -I"../../../external-deps/vorbis/include" -I"../../../external-deps/openal/include" -I"../../../gameplay/src"
-LOCAL_STATIC_LIBRARIES := android_native_app_glue libgameplay libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
-
+LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
+LOCAL_SHARED_LIBRARIES := gameplay
 include $(BUILD_SHARED_LIBRARY)
+
 $(call import-module,android/native_app_glue)

+ 1 - 1
samples/browser/android/jni/Application.mk

@@ -2,4 +2,4 @@ NDK_TOOLCHAIN_VERSION := 4.8
 APP_CPPFLAGS += -std=c++11
 APP_STL      := gnustl_static
 APP_ABI      := armeabi-v7a
-APP_PLATFORM := android-14
+APP_PLATFORM := android-16

+ 2 - 1
samples/browser/android/project.properties

@@ -1,2 +1,3 @@
-target=android-20
+target=android-16
 android.library=false
+source.dir=../src

+ 0 - 75
samples/browser/bar-descriptor.xml

@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
-
-<!-- BlackBerry OS application descriptor file.
-    Specifies parameters for identifying, installing, and launching native applications on BlackBerry OS.
--->
-
-    <!-- A universally unique application identifier. Must be unique across all BlackBerry OS applications.
-         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
-    <id>org.gameplay3d.sample_browser</id>
-
-    <!-- The name that is displayed in the BlackBerry OS application installer. 
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <name>Samples</name>
-
-    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
-         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
-         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
-    <versionNumber>1.0.0</versionNumber>
-
-    <!-- Fourth digit segment of the package version. First three segments are taken from the 
-         <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
-    <buildId>1</buildId>
-
-    <!-- Description, displayed in the BlackBerry OS application installer.
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <description>Samples</description>
-
-    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
-    <author>RIM Canada</author>
-
-    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
-    <!-- <authorId>gYAAgLDcDLxX077jVWRVnDpywiU</authorId> -->
-
-    <initialWindow>
-        <aspectRatio>landscape</aspectRatio>
-        <autoOrients>false</autoOrients>
-        <systemChrome>none</systemChrome>
-    </initialWindow>
-
-    <category>core.games</category>
-
-    <asset path="icon.png">icon.png</asset>
-	<asset path="game.config">game.config</asset>
-	<asset path="res/common">res/common</asset>
-	<asset path="res/png">res/png</asset>
-    <asset path="../../gameplay/res/logo_powered_white.png">res/logo_powered_white.png</asset>
-    <asset path="../../gameplay/res/shaders">res/shaders</asset>
-    <asset path="../../gameplay/res/ui">res/ui</asset>
-    
-    <configuration name="Device-Debug">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Debug/sample-browser" entry="true" type="Qnx/Elf">sample-browser</asset>
-    </configuration>
-    <configuration name="Device-Release">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Release/sample-browser" entry="true" type="Qnx/Elf">sample-browser</asset>
-    </configuration>
-    <configuration name="Simulator">
-        <platformArchitecture>x86</platformArchitecture>
-       <asset path="Simulator/sample-browser" entry="true" type="Qnx/Elf">sample-browser</asset>
-    </configuration>
-
-    <!-- The icon for the application, which should be 114x114. -->
-    <icon>
-        <image>icon.png</image>
-    </icon>
-
-    <!-- The splash screen that will appear when your application is launching, which should be 1280x720. -->
-    <!-- <splashscreen></splashscreen> -->
-
-    <!-- Ensure that shared libraries in the package are found at run-time. -->
-    <env var="LD_LIBRARY_PATH" value="app/native/lib"/>
-
-</qnx>

+ 4 - 4
samples/browser/sample-browser.xcodeproj/project.pbxproj

@@ -669,7 +669,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
 				VALID_ARCHS = x86_64;
@@ -704,7 +704,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
 				VALID_ARCHS = x86_64;
@@ -731,7 +731,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-browser-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",
@@ -769,7 +769,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-browser-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",

+ 12 - 21
samples/browser/src/GamepadSample.cpp

@@ -30,16 +30,13 @@ void GamepadSample::finalize()
 void GamepadSample::updateGamepad(float elapsedTime, Gamepad* gamepad, unsigned int player)
 {
     char s[128];
-    sprintf(s, "Player: %d - VendorID: %d, %s, Product ID: %d, %s\nButtons: ",
-                player,
-                gamepad->getVendorId(), gamepad->getVendorString(),
-                gamepad->getProductId(), gamepad->getProductString());
+    sprintf(s, "Player: %d - %s\nButtons: ", player, gamepad->getName());
     _status += s;
-    for (int j = 0; j < 20; ++j)
+    for (int i = 0; i < 20; ++i)
     {
-        if (gamepad->isButtonDown((Gamepad::ButtonMapping)j))
+        if (gamepad->isButtonDown((Gamepad::ButtonMapping)i))
         {
-            sprintf(s, "%s ", getStringFromButtonMapping((Gamepad::ButtonMapping)j));
+            sprintf(s, "%s ", getStringFromButtonMapping((Gamepad::ButtonMapping)i));
             _status += s;
         }
     }
@@ -51,9 +48,9 @@ void GamepadSample::updateGamepad(float elapsedTime, Gamepad* gamepad, unsigned
         sprintf(s, "Joystick %d: (%f, %f)\n", j, joystick.x, joystick.y);
         _status += s;
     }
-    for (unsigned int j = 0; j < gamepad->getTriggerCount(); ++j)
+    for (unsigned int k = 0; k < gamepad->getTriggerCount(); ++k)
     {
-        sprintf(s, "Trigger %d: %f\n", j, gamepad->getTriggerValue(j));
+        sprintf(s, "Trigger %d: %f\n", k, gamepad->getTriggerValue(k));
         _status += s;
     }
     _status += "\n";
@@ -103,22 +100,10 @@ const char* GamepadSample::getStringFromButtonMapping(Gamepad::ButtonMapping map
             return "A";
         case Gamepad::BUTTON_B:
             return "B";
-        case Gamepad::BUTTON_C:
-            return "C";
         case Gamepad::BUTTON_X:
             return "X";
         case Gamepad::BUTTON_Y:
             return "Y";
-        case Gamepad::BUTTON_Z:
-            return "Z";
-        case Gamepad::BUTTON_MENU1:
-            return "MENU1";
-        case Gamepad::BUTTON_MENU2:
-            return "MENU2";
-        case Gamepad::BUTTON_MENU3:
-            return "MENU3";
-        case Gamepad::BUTTON_MENU4:
-            return "MENU4";
         case Gamepad::BUTTON_L1:
             return "L1";
         case Gamepad::BUTTON_L2:
@@ -139,6 +124,12 @@ const char* GamepadSample::getStringFromButtonMapping(Gamepad::ButtonMapping map
             return "LEFT";
         case Gamepad::BUTTON_RIGHT:
             return "RIGHT";
+        case Gamepad::BUTTON_MENU1:
+            return "MENU1";
+        case Gamepad::BUTTON_MENU2:
+            return "MENU2";
+        case Gamepad::BUTTON_MENU3:
+            return "MENU3";
         default:
             return "";
     }

+ 17 - 16
samples/browser/src/GestureSample.cpp

@@ -86,15 +86,16 @@ void GestureSample::render(float elapsedTime)
 
     // Draw text
     Vector4 fontColor(1.0f, 1.0f, 1.0f, 1.0f);
-
+    unsigned int fontSize = 18;
+    
     _font->start();
     int y = 0;
     size_t count = 0;
     for (std::list<std::string>::const_iterator it = _eventLog.begin(); it != _eventLog.end(); ++it)
     {
         ++count;
-        _font->drawText(it->c_str(), 0, y, fontColor, _font->getSize());
-        y += _font->getSize();
+        _font->drawText(it->c_str(), 0, y, fontColor, fontSize);
+        y += fontSize;
 
         if (y > (int)getHeight())
         {
@@ -104,37 +105,37 @@ void GestureSample::render(float elapsedTime)
     }
     
     int x = getWidth() - 200;
-    y = getHeight() - _font->getSize() * 6;
+    y = getHeight() - fontSize * 6;
 
     if (isGestureSupported(Gesture::GESTURE_TAP))
     {
-        _font->drawText("Tap supported", x, y, fontColor, _font->getSize());
-        y += _font->getSize();
+        _font->drawText("Tap supported", x, y, fontColor, fontSize);
+        y += fontSize;
     }
     if (isGestureSupported(Gesture::GESTURE_SWIPE))
     {
-        _font->drawText("Swipe supported", x, y, fontColor, _font->getSize());
-        y += _font->getSize();
+        _font->drawText("Swipe supported", x, y, fontColor, fontSize);
+        y += fontSize;
     }
     if (isGestureSupported(Gesture::GESTURE_PINCH))
     {
-        _font->drawText("Pinch supported", x, y, fontColor, _font->getSize());
-        y += _font->getSize();
+        _font->drawText("Pinch supported", x, y, fontColor, fontSize);
+        y += fontSize;
     }
     if (isGestureSupported(Gesture::GESTURE_LONG_TAP))
     {
-        _font->drawText("Long tap supported", x, y, fontColor, _font->getSize());
-        y += _font->getSize();
+        _font->drawText("Long tap supported", x, y, fontColor, fontSize);
+        y += fontSize;
     }
     if (isGestureSupported(Gesture::GESTURE_DRAG))
     {
-        _font->drawText("Drag supported", x, y, fontColor, _font->getSize());
-        y += _font->getSize();
+        _font->drawText("Drag supported", x, y, fontColor, fontSize);
+        y += fontSize;
     }
     if (isGestureSupported(Gesture::GESTURE_DROP))
     {
-        _font->drawText("Drop supported", x, y, fontColor, _font->getSize());
-        y += _font->getSize();
+        _font->drawText("Drop supported", x, y, fontColor, fontSize);
+        y += fontSize;
     }
 
     _font->finish();

+ 4 - 4
samples/character/android/AndroidManifest.xml

@@ -1,17 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="org.gameplay3d.sample_character"
+        package="org.gameplay3d.sample_mesh"
         android:versionCode="1"
         android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="15"/>
+    <uses-sdk android:minSdkVersion="16" />
 	<uses-feature android:glEsVersion="0x00020000"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="true">
-        <activity android:name="android.app.NativeActivity"
+        <activity android:name="org.gameplay3d.GameNativeActivity"
                   android:label="@string/app_name"
-                  android:configChanges="screenSize|orientation|keyboardHidden"
+                  android:configChanges="orientation|keyboardHidden"
 				  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
 				  android:screenOrientation="landscape">
             <meta-data android:name="android.app.lib_name" android:value="sample-character" />

+ 33 - 6
samples/character/android/build.xml

@@ -6,10 +6,40 @@
     
     <loadproperties srcFile="project.properties" />
 
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'" unless="sdk.dir" />
-
+    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project -t 1 -p . -s'" unless="sdk.dir" />
+	<fail message="OS not supported. Supported platforms: Windows, MacOS X or Linux.">
+	    <condition>
+	      <not>
+	        <or>
+	          <os family="unix"/>
+	          <os family="windows"/>
+	        </or>
+	      </not>
+	    </condition>
+	</fail>
+	<macrodef name="build-native">
+		<attribute name="location"/>
+	     <sequential>
+            <exec osfamily="unix" dir="@{location}/android" executable="ndk-build">
+                <arg value="-j4"/>
+            </exec>
+			<exec osfamily="windows" dir="@{location}/android" executable="cmd">
+				<arg value="/c"/>
+				<arg value="ndk-build -j4"/>
+			</exec> 
+	    </sequential>
+	</macrodef>
+    
     <target name="-pre-build">
-		<mkdir dir="src"/>
+		<build-native location="../../../gameplay"/>
+    	<build-native location=".."/>
+        <mkdir dir="../src/org/gameplay3d"/>
+	    <copy todir="../src/org/gameplay3d">
+            <fileset dir="../../../gameplay/src/org/gameplay3d"/>
+	    </copy>
+    </target>
+	
+    <target name="-post-compile">
         <copy file="../game.png.config" tofile="assets/game.config"/>
         <copy file="../res/design/backboard.png" tofile="assets/res/png/backboard.png"/>
         <copy file="../res/design/basketball.png" tofile="assets/res/png/basketball.png"/>
@@ -55,9 +85,6 @@
             <fileset dir="../../../gameplay/res/ui"/>
         </copy>
     </target>
-	
-    <target name="-post-compile">
-    </target>
 
     <!-- version-tag: 1 -->
     <import file="${sdk.dir}/tools/ant/build.xml" />

+ 7 - 8
samples/character/android/jni/Android.mk

@@ -9,12 +9,12 @@ OGG_PATH := $(call my-dir)/../../../../external-deps/ogg/lib/android/arm
 VORBIS_PATH := $(call my-dir)/../../../../external-deps/vorbis/lib/android/arm
 OPENAL_PATH := $(call my-dir)/../../../../external-deps/openal/lib/android/arm
 
-# gameplay
-LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/obj/local/armeabi-v7a
+# libgameplay
+LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/libs/armeabi-v7a
 include $(CLEAR_VARS)
 LOCAL_MODULE    := libgameplay
-LOCAL_SRC_FILES := libgameplay.a
-include $(PREBUILT_STATIC_LIBRARY)
+LOCAL_SRC_FILES := libgameplay.so
+include $(PREBUILT_SHARED_LIBRARY)
 
 # libpng
 LOCAL_PATH := $(PNG_PATH)
@@ -82,15 +82,14 @@ include $(PREBUILT_STATIC_LIBRARY)
 # sample-character
 LOCAL_PATH := $(SAMPLE_PATH)
 include $(CLEAR_VARS)
-
 LOCAL_MODULE    := sample-character
 LOCAL_SRC_FILES := ../../../gameplay/src/gameplay-main-android.cpp CharacterGame.cpp
-
 LOCAL_CPPFLAGS += -std=c++11 -Wno-switch-enum -Wno-switch
 LOCAL_ARM_MODE := arm
 LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv2 -lOpenSLES
 LOCAL_CFLAGS    := -D__ANDROID__ -I"../../../external-deps/lua/include" -I"../../../external-deps/bullet/include" -I"../../../external-deps/png/include" -I"../../../external-deps/ogg/include" -I"../../../external-deps/vorbis/include" -I"../../../external-deps/openal/include" -I"../../../gameplay/src"
-LOCAL_STATIC_LIBRARIES := android_native_app_glue libgameplay libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
-
+LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
+LOCAL_SHARED_LIBRARIES := gameplay
 include $(BUILD_SHARED_LIBRARY)
+
 $(call import-module,android/native_app_glue)

+ 1 - 1
samples/character/android/jni/Application.mk

@@ -2,5 +2,5 @@ NDK_TOOLCHAIN_VERSION := 4.8
 APP_CPPFLAGS += -std=c++11
 APP_STL      := gnustl_static
 APP_ABI      := armeabi-v7a
-APP_PLATFORM := android-14
+APP_PLATFORM := android-16
 

+ 2 - 1
samples/character/android/project.properties

@@ -1,2 +1,3 @@
-target=android-20
+target=android-16
 android.library=false
+source.dir=../src

+ 0 - 117
samples/character/bar-descriptor.xml

@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
-
-<!-- BlackBerry OS application descriptor file.
-    Specifies parameters for identifying, installing, and launching native applications on BlackBerry OS.
--->
-
-    <!-- A universally unique application identifier. Must be unique across all BlackBerry OS applications.
-         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
-    <id>org.gameplay3d.sample_character</id>
-
-    <!-- The name that is displayed in the BlackBerry OS application installer. 
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <name>Character</name>
-    
-    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
-         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
-         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
-    <versionNumber>1.0.0</versionNumber>
-
-    <!-- Fourth digit segment of the package version. First three segments are taken from the 
-         <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
-    <buildId>1</buildId>
-
-    <!-- Description, displayed in the BlackBerry OS application installer.
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <description>Character</description>
-
-    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
-    <author>RIM Canada</author>
-
-    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
-    <!-- <authorId>gYAAgLDcDLxX077jVWRVnDpywiU</authorId> -->
-
-    <initialWindow>
-        <aspectRatio>landscape</aspectRatio>
-        <autoOrients>false</autoOrients>
-        <systemChrome>none</systemChrome>
-    </initialWindow>
-
-    <category>core.games</category>
-    
-    <asset path="icon.png">icon.png</asset>
-    <asset path="res/common">res/common</asset>
-    <asset path="res/design/backboard.png">res/png/backboard.png</asset>
-    <asset path="res/design/basketball.png">res/png/basketball.png</asset>
-    <asset path="res/design/basketballnet.png">res/png/basketballnet.png</asset>
-    <asset path="res/design/book.png">res/png/book.png</asset>
-    <asset path="res/design/bookshelf.png">res/png/bookshelf.png</asset>
-    <asset path="res/design/boy.png">res/png/boy.png</asset>
-    <asset path="res/design/decals.png">res/png/decals.png</asset>
-    <asset path="res/design/door.png">res/png/door.png</asset>
-    <asset path="res/design/doorframe.png">res/png/doorframe.png</asset>
-    <asset path="res/design/easel.png">res/png/easel.png</asset>
-    <asset path="res/design/floor.png">res/png/floor.png</asset>
-    <asset path="res/design/floortiles.png">res/png/floortiles.png</asset>
-    <asset path="res/design/gamepad.png">res/png/gamepad.png</asset>
-    <asset path="res/design/playtable.png">res/png/playtable.png</asset>
-    <asset path="res/design/shadow.png">res/png/shadow.png</asset>
-    <asset path="res/design/storageorganizer.png">res/png/storageorganizer.png</asset>
-    <asset path="res/design/tableleg1.png">res/png/tableleg1.png</asset>
-    <asset path="res/design/tableleg2.png">res/png/tableleg2.png</asset>
-    <asset path="res/design/tableleg3.png">res/png/tableleg3.png</asset>
-    <asset path="res/design/tableleg4.png">res/png/tableleg4.png</asset>
-    <asset path="res/design/tabletop.png">res/png/tabletop.png</asset>
-    <asset path="res/design/tiles.png">res/png/tiles.png</asset>
-    <asset path="res/design/tilesn.png">res/png/tilesn.png</asset>
-    <asset path="res/design/toybox.png">res/png/toybox.png</asset>
-    <asset path="res/design/walleast.png">res/png/walleast.png</asset>
-    <asset path="res/design/wallnorth.png">res/png/wallnorth.png</asset>
-    <asset path="res/design/walloverhang.png">res/png/walloverhang.png</asset>
-    <asset path="res/design/wallsouth.png">res/png/wallsouth.png</asset>
-    <asset path="res/design/wallwest.png">res/png/wallwest.png</asset>
-    <asset path="res/design/windowledge.png">res/png/windowledge.png</asset>
-    <asset path="res/design/wood.png">res/png/wood.png</asset>
-    <asset path="res/design/woodn.png">res/png/woodn.png</asset>
-    <asset path="game.png.config">game.config</asset>
-    <asset path="../../gameplay/res/logo_powered_white.png">res/logo_powered_white.png</asset>
-    <asset path="../../gameplay/res/shaders">res/shaders</asset>
-    <asset path="../../gameplay/res/ui">res/ui</asset>
-    
-    <configuration name="Device-Debug">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Debug/sample-character" entry="true" type="Qnx/Elf">sample-character</asset>
-    </configuration>
-    <configuration name="Device-Release">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Release/sample-character" entry="true" type="Qnx/Elf">sample-character</asset>
-    </configuration>
-    <configuration name="Simulator">
-       <platformArchitecture>x86</platformArchitecture>
-       <asset path="Simulator/sample-character" entry="true" type="Qnx/Elf">sample-character</asset>
-    </configuration>
-  
-    <!-- The icon for the application, which should be 114x114. -->
-    <icon>
-        <image>icon.png</image>
-    </icon>
-    
-    <!-- The splash screen that will appear when your application is launching. Should be 1280x720. -->
-    <!-- <splashscreen></splashscreen> -->
-    
-    <!-- The permissions requested by your application. -->
-    <!--  <action>access_shared</action> -->
-    <!--  <action>record_audio</action> -->
-    <!--  <action>read_geolocation</action> -->
-    <!--  <action>use_camera</action> -->
-    <!--  <action>access_internet</action> -->
-    <!--  <action>play_audio</action> -->
-    <!--  <action>post_notification</action> -->
-    <!--  <action>set_audio_volume</action> -->
-    <!--  <action>read_device_identifying_information</action> -->
-    
-    <!-- Ensure that shared libraries in the package are found at run-time. -->
-    <env var="LD_LIBRARY_PATH" value="app/native/lib"/>
-
-</qnx>

+ 4 - 4
samples/character/sample-character.xcodeproj/project.pbxproj

@@ -493,7 +493,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				VALID_ARCHS = x86_64;
@@ -531,7 +531,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				VALID_ARCHS = x86_64;
@@ -560,7 +560,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-character-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",
@@ -601,7 +601,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-character-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",

+ 3 - 3
samples/lua/android/AndroidManifest.xml

@@ -4,14 +4,14 @@
         android:versionCode="1"
         android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="15" />
+    <uses-sdk android:minSdkVersion="16" />
 	<uses-feature android:glEsVersion="0x00020000"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="true">
-        <activity android:name="android.app.NativeActivity"
+        <activity android:name="org.gameplay3d.GameNativeActivity"
                 android:label="@string/app_name"
-                android:configChanges="screenSize|orientation|keyboardHidden"
+                android:configChanges="orientation|keyboardHidden"
 				android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
 				android:screenOrientation="landscape">
             <meta-data android:name="android.app.lib_name" android:value="sample-lua" />

+ 33 - 6
samples/lua/android/build.xml

@@ -6,10 +6,40 @@
 
     <loadproperties srcFile="project.properties" />
 
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'" unless="sdk.dir" />
-
+    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project -t 1 -p . -s'" unless="sdk.dir" />
+	<fail message="OS not supported. Supported platforms: Windows, MacOS X or Linux.">
+	    <condition>
+	      <not>
+	        <or>
+	          <os family="unix"/>
+	          <os family="windows"/>
+	        </or>
+	      </not>
+	    </condition>
+	</fail>
+	<macrodef name="build-native">
+		<attribute name="location"/>
+	     <sequential>
+            <exec osfamily="unix" dir="@{location}/android" executable="ndk-build">
+                <arg value="-j4"/>
+            </exec>
+			<exec osfamily="windows" dir="@{location}/android" executable="cmd">
+				<arg value="/c"/>
+				<arg value="ndk-build -j4"/>
+			</exec> 
+	    </sequential>
+	</macrodef>
+    
     <target name="-pre-build">
-		<mkdir dir="src"/>
+		<build-native location="../../../gameplay"/>
+    	<build-native location=".."/>
+        <mkdir dir="../src/org/gameplay3d"/>
+	    <copy todir="../src/org/gameplay3d">
+            <fileset dir="../../../gameplay/src/org/gameplay3d"/>
+	    </copy>
+    </target>
+
+    <target name="-post-compile">
         <copy file="../game.config" tofile="assets/game.config"/>
         <copy file="../res/ai.lua" tofile="assets/res/ai.lua"/>
         <copy file="../res/game.lua" tofile="assets/res/game.lua"/>
@@ -26,9 +56,6 @@
         </copy>
     </target>
 
-    <target name="-post-compile">
-    </target>
-
     <!-- version-tag: 1 -->
     <import file="${sdk.dir}/tools/ant/build.xml" />
 

+ 7 - 8
samples/lua/android/jni/Android.mk

@@ -9,12 +9,12 @@ OGG_PATH := $(call my-dir)/../../../../external-deps/ogg/lib/android/arm
 VORBIS_PATH := $(call my-dir)/../../../../external-deps/vorbis/lib/android/arm
 OPENAL_PATH := $(call my-dir)/../../../../external-deps/openal/lib/android/arm
 
-# gameplay
-LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/obj/local/armeabi-v7a
+# libgameplay
+LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/libs/armeabi-v7a
 include $(CLEAR_VARS)
 LOCAL_MODULE    := libgameplay
-LOCAL_SRC_FILES := libgameplay.a
-include $(PREBUILT_STATIC_LIBRARY)
+LOCAL_SRC_FILES := libgameplay.so
+include $(PREBUILT_SHARED_LIBRARY)
 
 # libpng
 LOCAL_PATH := $(PNG_PATH)
@@ -82,15 +82,14 @@ include $(PREBUILT_STATIC_LIBRARY)
 # sample-lua
 LOCAL_PATH := $(SAMPLE_PATH)
 include $(CLEAR_VARS)
-
 LOCAL_MODULE    := sample-lua
 LOCAL_SRC_FILES := ../../../gameplay/src/gameplay-main-android.cpp LuaGame.cpp
-
 LOCAL_CPPFLAGS += -std=c++11 -Wno-switch-enum -Wno-switch
 LOCAL_ARM_MODE := arm
 LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv2 -lOpenSLES
 LOCAL_CFLAGS    := -D__ANDROID__ -I"../../../external-deps/lua/include" -I"../../../external-deps/bullet/include" -I"../../../external-deps/png/include" -I"../../../external-deps/ogg/include" -I"../../../external-deps/vorbis/include" -I"../../../external-deps/openal/include" -I"../../../gameplay/src"
-LOCAL_STATIC_LIBRARIES := android_native_app_glue libgameplay libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
-
+LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
+LOCAL_SHARED_LIBRARIES := gameplay
 include $(BUILD_SHARED_LIBRARY)
+
 $(call import-module,android/native_app_glue)

+ 1 - 1
samples/lua/android/jni/Application.mk

@@ -2,5 +2,5 @@ NDK_TOOLCHAIN_VERSION := 4.8
 APP_CPPFLAGS += -std=c++11
 APP_STL      := gnustl_static
 APP_ABI      := armeabi-v7a
-APP_PLATFORM := android-14
+APP_PLATFORM := android-16
 

+ 2 - 1
samples/lua/android/project.properties

@@ -1,3 +1,4 @@
-target=android-20
+target=android-16
 android.library=false
+source.dir=../src
 

+ 0 - 90
samples/lua/bar-descriptor.xml

@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
-
-<!-- BlackBerry OS application descriptor file.
-    Specifies parameters for identifying, installing, and launching native applications on BlackBerry OS.
--->
-
-    <!-- A universally unique application identifier. Must be unique across all BlackBerry OS applications.
-         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
-    <id>org.gameplay3d.sample_lua</id>
-
-    <!-- The name that is displayed in the BlackBerry OS application installer. 
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <name>Lua</name>
-
-    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
-         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
-         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
-    <versionNumber>1.0.0</versionNumber>
-
-    <!-- Fourth digit segment of the package version. First three segments are taken from the 
-         <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
-    <buildId>1</buildId>
-
-    <!-- Description, displayed in the BlackBerry OS application installer.
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <description>Lua</description>
-
-    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
-    <author>RIM Canada</author>
-
-    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
-    <!-- <authorId>gYAAgLDcDLxX077jVWRVnDpywiU</authorId> -->
-
-    <initialWindow>
-        <aspectRatio>landscape</aspectRatio>
-        <autoOrients>false</autoOrients>
-        <systemChrome>none</systemChrome>
-    </initialWindow>
-
-    <category>core.games</category>
-
-    <asset path="icon.png">icon.png</asset>
-    <asset path="game.config">game.config</asset>
-    <asset path="res/ai.lua">res/ai.lua</asset>
-    <asset path="res/game.lua">res/game.lua</asset>
-    <asset path="res/lua.gpb">res/lua.gpb</asset>
-    <asset path="res/lua.material">res/lua.material</asset>
-    <asset path="res/lua.scene">res/lua.scene</asset>
-    <asset path="res/lua-logo.png">res/lua-logo.png</asset>
-    <asset path="../../gameplay/res/logo_powered_white.png">res/logo_powered_white.png</asset>
-    <asset path="../../gameplay/res/shaders">res/shaders</asset>
-    <asset path="../../gameplay/res/ui">res/ui</asset>
-
-    <configuration name="Device-Debug">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Debug/sample-lua" entry="true" type="Qnx/Elf">sample-lua</asset>
-    </configuration>
-    <configuration name="Device-Release">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Release/sample-lua" entry="true" type="Qnx/Elf">sample-lua</asset>
-    </configuration>
-    <configuration name="Simulator">
-        <platformArchitecture>x86</platformArchitecture>
-       <asset path="Simulator/sample-lua" entry="true" type="Qnx/Elf">sample-lua</asset>
-    </configuration>
-
-    <!-- The icon for the application, which should be 114x114. -->
-    <icon>
-        <image>icon.png</image>
-    </icon>
-
-    <!-- The splash screen that will appear when your application is launching. Should be 1280x720. -->
-    <!-- <splashscreen></splashscreen> -->
-
-    <!-- The permissions requested by your application. -->
-    <!--  <action>access_shared</action> -->
-    <!--  <action>record_audio</action> -->
-    <!--  <action>read_geolocation</action> -->
-    <!--  <action>use_camera</action> -->
-    <!--  <action>access_internet</action> -->
-    <!--  <action>play_audio</action> -->
-    <!--  <action>post_notification</action> -->
-    <!--  <action>set_audio_volume</action> -->
-    <!--  <action>read_device_identifying_information</action> -->
-
-    <!-- Ensure that shared libraries in the package are found at run-time. -->
-    <env var="LD_LIBRARY_PATH" value="app/native/lib"/>
-
-</qnx>

+ 4 - 4
samples/lua/sample-lua.xcodeproj/project.pbxproj

@@ -491,7 +491,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
 				VALID_ARCHS = x86_64;
@@ -526,7 +526,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				USER_HEADER_SEARCH_PATHS = "";
 				VALID_ARCHS = x86_64;
@@ -552,7 +552,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-lua-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",
@@ -588,7 +588,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-lua-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",

+ 48 - 0
samples/mesh/android/.project

@@ -10,6 +10,54 @@
 			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
 			<triggers>clean,full,incremental,</triggers>
 			<arguments>
+				<dictionary>
+					<key>?children?</key>
+					<value>?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\||</value>
+				</dictionary>
+				<dictionary>
+					<key>?name?</key>
+					<value></value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.append_environment</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildArguments</key>
+					<value>NDK_DEBUG=1 -j4</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.buildCommand</key>
+					<value>ndk-build</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+					<value>clean</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.contents</key>
+					<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+					<value>false</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.enableFullBuild</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.stopOnError</key>
+					<value>true</value>
+				</dictionary>
+				<dictionary>
+					<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+					<value>false</value>
+				</dictionary>
 			</arguments>
 		</buildCommand>
 		<buildCommand>

+ 3 - 3
samples/mesh/android/AndroidManifest.xml

@@ -4,14 +4,14 @@
         android:versionCode="1"
         android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="15" />
+    <uses-sdk android:minSdkVersion="16" />
 	<uses-feature android:glEsVersion="0x00020000"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="true">
-        <activity android:name="android.app.NativeActivity"
+        <activity android:name="org.gameplay3d.GameNativeActivity"
                   android:label="@string/app_name"
-                  android:configChanges="screenSize|orientation|keyboardHidden"
+                  android:configChanges="orientation|keyboardHidden"
 				  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
 				  android:screenOrientation="landscape">
             <meta-data android:name="android.app.lib_name" android:value="sample-mesh" />

+ 35 - 8
samples/mesh/android/build.xml

@@ -3,14 +3,44 @@
 
     <property file="local.properties" />
     <property file="ant.properties" />
-    
-    <loadproperties srcFile="project.properties" />
 
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'" unless="sdk.dir" />
+    <loadproperties srcFile="project.properties" />
 
+    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project -t 1 -p . -s'" unless="sdk.dir" />
+	<fail message="OS not supported. Supported platforms: Windows, MacOS X or Linux.">
+	    <condition>
+	      <not>
+	        <or>
+	          <os family="unix"/>
+	          <os family="windows"/>
+	        </or>
+	      </not>
+	    </condition>
+	</fail>
+	<macrodef name="build-native">
+		<attribute name="location"/>
+	     <sequential>
+            <exec osfamily="unix" dir="@{location}/android" executable="ndk-build">
+                <arg value="-j4"/>
+            </exec>
+			<exec osfamily="windows" dir="@{location}/android" executable="cmd">
+				<arg value="/c"/>
+				<arg value="ndk-build -j4"/>
+			</exec> 
+	    </sequential>
+	</macrodef>
+    
     <target name="-pre-build">
-		<mkdir dir="src"/>
-        <copy file="../game.config" tofile="assets/game.config"/>
+		<build-native location="../../../gameplay"/>
+    	<build-native location=".."/>
+        <mkdir dir="../src/org/gameplay3d"/>
+	    <copy todir="../src/org/gameplay3d">
+            <fileset dir="../../../gameplay/src/org/gameplay3d"/>
+	    </copy>
+    </target>
+	
+    <target name="-post-compile">
+     	<copy file="../game.config" tofile="assets/game.config"/>
         <copy file="../res/mesh.scene" tofile="assets/res/mesh.scene"/>
         <copy file="../res/mesh.gpb" tofile="assets/res/mesh.gpb"/>
         <copy file="../res/mesh.material" tofile="assets/res/mesh.material"/>
@@ -23,9 +53,6 @@
             <fileset dir="../../../gameplay/res/ui"/>
         </copy>
     </target>
-	
-    <target name="-post-compile">
-    </target>
 
     <!-- version-tag: 1 -->
     <import file="${sdk.dir}/tools/ant/build.xml" />

+ 7 - 8
samples/mesh/android/jni/Android.mk

@@ -9,12 +9,12 @@ OGG_PATH := $(call my-dir)/../../../../external-deps/ogg/lib/android/arm
 VORBIS_PATH := $(call my-dir)/../../../../external-deps/vorbis/lib/android/arm
 OPENAL_PATH := $(call my-dir)/../../../../external-deps/openal/lib/android/arm
 
-# gameplay
-LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/obj/local/armeabi-v7a
+# libgameplay
+LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/libs/armeabi-v7a
 include $(CLEAR_VARS)
 LOCAL_MODULE    := libgameplay
-LOCAL_SRC_FILES := libgameplay.a
-include $(PREBUILT_STATIC_LIBRARY)
+LOCAL_SRC_FILES := libgameplay.so
+include $(PREBUILT_SHARED_LIBRARY)
 
 # libpng
 LOCAL_PATH := $(PNG_PATH)
@@ -82,15 +82,14 @@ include $(PREBUILT_STATIC_LIBRARY)
 # sample-mesh
 LOCAL_PATH := $(SAMPLE_PATH)
 include $(CLEAR_VARS)
-
 LOCAL_MODULE    := sample-mesh
 LOCAL_SRC_FILES := ../../../gameplay/src/gameplay-main-android.cpp MeshGame.cpp
-
 LOCAL_CPPFLAGS += -std=c++11 -Wno-switch-enum -Wno-switch
 LOCAL_ARM_MODE := arm
 LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv2 -lOpenSLES
 LOCAL_CFLAGS    := -D__ANDROID__ -I"../../../external-deps/lua/include" -I"../../../external-deps/bullet/include" -I"../../../external-deps/png/include" -I"../../../external-deps/ogg/include" -I"../../../external-deps/vorbis/include" -I"../../../external-deps/openal/include" -I"../../../gameplay/src"
-LOCAL_STATIC_LIBRARIES := android_native_app_glue libgameplay libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
-
+LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
+LOCAL_SHARED_LIBRARIES := gameplay
 include $(BUILD_SHARED_LIBRARY)
+
 $(call import-module,android/native_app_glue)

+ 1 - 1
samples/mesh/android/jni/Application.mk

@@ -2,5 +2,5 @@ NDK_TOOLCHAIN_VERSION := 4.8
 APP_CPPFLAGS += -std=c++11
 APP_STL      := gnustl_static
 APP_ABI      := armeabi-v7a
-APP_PLATFORM := android-14
+APP_PLATFORM := android-16
 

+ 2 - 1
samples/mesh/android/project.properties

@@ -1,2 +1,3 @@
-target=android-20
+target=android-16
 android.library=false
+source.dir=../src

+ 0 - 88
samples/mesh/bar-descriptor.xml

@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
-
-<!-- BlackBerry OS application descriptor file.
-    Specifies parameters for identifying, installing, and launching native applications on BlackBerry OS.
--->
-
-    <!-- A universally unique application identifier. Must be unique across all BlackBerry OS applications.
-         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
-    <id>org.gameplay3d.sample_mesh</id>
-
-    <!-- The name that is displayed in the BlackBerry OS application installer. 
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <name>Mesh</name>
-    
-    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
-         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
-         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
-    <versionNumber>1.0.0</versionNumber>
-
-    <!-- Fourth digit segment of the package version. First three segments are taken from the 
-         <versionNumber> element.  Must be an integer from 0 to 2^16-1 -->
-    <buildId>1</buildId>
-
-    <!-- Description, displayed in the BlackBerry OS application installer.
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <description>Mesh</description>
-
-    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
-    <author>RIM Canada</author>
-
-    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
-    <!-- <authorId>gYAAgLDcDLxX077jVWRVnDpywiU</authorId> -->
-
-    <initialWindow>
-        <aspectRatio>landscape</aspectRatio>
-        <autoOrients>false</autoOrients>
-        <systemChrome>none</systemChrome>
-    </initialWindow>
-    
-    <category>core.games</category>
-    
-    <asset path="icon.png">icon.png</asset>
-    <asset path="res/duck.png">res/duck.png</asset>
-    <asset path="res/mesh.scene">res/mesh.scene</asset>
-    <asset path="res/mesh.gpb">res/mesh.gpb</asset>
-    <asset path="res/mesh.material">res/mesh.material</asset>
-    <asset path="game.config">game.config</asset>
-    <asset path="../../gameplay/res/logo_powered_white.png">res/logo_powered_white.png</asset>
-    <asset path="../../gameplay/res/shaders">res/shaders</asset>
-    <asset path="../../gameplay/res/ui">res/ui</asset>
-    
-    <configuration name="Device-Debug">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Debug/sample-mesh" entry="true" type="Qnx/Elf">sample-mesh</asset>
-    </configuration>
-    <configuration name="Device-Release">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Release/sample-mesh" entry="true" type="Qnx/Elf">sample-mesh</asset>
-    </configuration>
-    <configuration name="Simulator">
-        <platformArchitecture>x86</platformArchitecture>
-       <asset path="Simulator/sample-mesh" entry="true" type="Qnx/Elf">sample-mesh</asset>
-    </configuration>
-    
-    <!-- The icon for the application, which should be 114x114. -->
-    <icon>
-        <image>icon.png</image>
-    </icon>
-    
-    <!-- The splash screen that will appear when your application is launching, which should be 1280x720. -->
-    <!-- <splashscreen></splashscreen> -->
-    
-    <!-- The permissions requested by your application. -->
-    <!--  <action>access_shared</action> -->
-    <!--  <action>record_audio</action> -->
-    <!--  <action>read_geolocation</action> -->
-    <!--  <action>use_camera</action> -->
-    <!--  <action>access_internet</action> -->
-    <!--  <action>play_audio</action> -->
-    <!--  <action>post_notification</action> -->
-    <!--  <action>set_audio_volume</action> -->
-    <!--  <action>read_device_identifying_information</action> -->
-    
-    <!-- Ensure that shared libraries in the package are found at run-time. -->
-    <env var="LD_LIBRARY_PATH" value="app/native/lib"/>
-    
-</qnx>

+ 4 - 4
samples/mesh/sample-mesh.xcodeproj/project.pbxproj

@@ -495,7 +495,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SHARED_PRECOMPS_DIR = "";
 				SUPPORTED_PLATFORMS = macosx;
@@ -533,7 +533,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SHARED_PRECOMPS_DIR = "";
 				SUPPORTED_PLATFORMS = macosx;
@@ -562,7 +562,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-mesh-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",
@@ -604,7 +604,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-mesh-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",

+ 3 - 3
samples/particles/android/AndroidManifest.xml

@@ -4,14 +4,14 @@
         android:versionCode="1"
         android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="15" />
+    <uses-sdk android:minSdkVersion="16" />
 	<uses-feature android:glEsVersion="0x00020000"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="true">
-        <activity android:name="android.app.NativeActivity"
+        <activity android:name="org.gameplay3d.GameNativeActivity"
                   android:label="@string/app_name"
-                  android:configChanges="screenSize|orientation|keyboardHidden"
+                  android:configChanges="orientation|keyboardHidden"
 				  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
 				  android:screenOrientation="landscape">
             <meta-data android:name="android.app.lib_name" android:value="sample-particles" />

+ 33 - 6
samples/particles/android/build.xml

@@ -6,10 +6,40 @@
     
     <loadproperties srcFile="project.properties" />
     
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'" unless="sdk.dir" />
-
+    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project -t 1 -p . -s'" unless="sdk.dir" />
+	<fail message="OS not supported. Supported platforms: Windows, MacOS X or Linux.">
+	    <condition>
+	      <not>
+	        <or>
+	          <os family="unix"/>
+	          <os family="windows"/>
+	        </or>
+	      </not>
+	    </condition>
+	</fail>
+	<macrodef name="build-native">
+		<attribute name="location"/>
+	     <sequential>
+            <exec osfamily="unix" dir="@{location}/android" executable="ndk-build">
+                <arg value="-j4"/>
+            </exec>
+			<exec osfamily="windows" dir="@{location}/android" executable="cmd">
+				<arg value="/c"/>
+				<arg value="ndk-build -j4"/>
+			</exec> 
+	    </sequential>
+	</macrodef>
+    
     <target name="-pre-build">
-        <mkdir dir="src"/>
+		<build-native location="../../../gameplay"/>
+    	<build-native location=".."/>
+        <mkdir dir="../src/org/gameplay3d"/>
+	    <copy todir="../src/org/gameplay3d">
+            <fileset dir="../../../gameplay/src/org/gameplay3d"/>
+	    </copy>
+    </target>
+	
+    <target name="-post-compile">
         <copy file="../res/editor.form" tofile="assets/res/editor.form"/>
         <copy file="../res/editor.png" tofile="assets/res/editor.png"/>
         <copy file="../res/editor.theme" tofile="assets/res/editor.theme"/>
@@ -28,9 +58,6 @@
             <fileset dir="../../../gameplay/res/ui"/>
         </copy>
     </target>
-	
-    <target name="-post-compile">
-    </target>
 
     <!-- version-tag: 1 -->
     <import file="${sdk.dir}/tools/ant/build.xml" />

+ 7 - 8
samples/particles/android/jni/Android.mk

@@ -9,12 +9,12 @@ OGG_PATH := $(call my-dir)/../../../../external-deps/ogg/lib/android/arm
 VORBIS_PATH := $(call my-dir)/../../../../external-deps/vorbis/lib/android/arm
 OPENAL_PATH := $(call my-dir)/../../../../external-deps/openal/lib/android/arm
 
-# gameplay
-LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/obj/local/armeabi-v7a
+# libgameplay
+LOCAL_PATH := $(call my-dir)/../../../../gameplay/android/libs/armeabi-v7a
 include $(CLEAR_VARS)
 LOCAL_MODULE    := libgameplay
-LOCAL_SRC_FILES := libgameplay.a
-include $(PREBUILT_STATIC_LIBRARY)
+LOCAL_SRC_FILES := libgameplay.so
+include $(PREBUILT_SHARED_LIBRARY)
 
 # libpng
 LOCAL_PATH := $(PNG_PATH)
@@ -82,15 +82,14 @@ include $(PREBUILT_STATIC_LIBRARY)
 # sample-particles
 LOCAL_PATH := $(SAMPLE_PATH)
 include $(CLEAR_VARS)
-
 LOCAL_MODULE    := sample-particles
 LOCAL_SRC_FILES := ../../../gameplay/src/gameplay-main-android.cpp ParticlesGame.cpp
-
 LOCAL_CPPFLAGS += -std=c++11 -Wno-switch-enum -Wno-switch
 LOCAL_ARM_MODE := arm
 LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv2 -lOpenSLES
 LOCAL_CFLAGS    := -D__ANDROID__ -I"../../../external-deps/lua/include" -I"../../../external-deps/bullet/include" -I"../../../external-deps/png/include" -I"../../../external-deps/ogg/include" -I"../../../external-deps/vorbis/include" -I"../../../external-deps/openal/include" -I"../../../gameplay/src"
-LOCAL_STATIC_LIBRARIES := android_native_app_glue libgameplay libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
-
+LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng libz liblua libBulletDynamics libBulletCollision libLinearMath libvorbis libogg libOpenAL
+LOCAL_SHARED_LIBRARIES := gameplay
 include $(BUILD_SHARED_LIBRARY)
+
 $(call import-module,android/native_app_glue)

+ 1 - 1
samples/particles/android/jni/Application.mk

@@ -2,5 +2,5 @@ NDK_TOOLCHAIN_VERSION := 4.8
 APP_CPPFLAGS += -std=c++11
 APP_STL      := gnustl_static
 APP_ABI      := armeabi-v7a
-APP_PLATFORM := android-14
+APP_PLATFORM := android-16
 

+ 2 - 1
samples/particles/android/project.properties

@@ -1,2 +1,3 @@
-target=android-20
+target=android-16
 android.library=false
+source.dir=../src

+ 0 - 93
samples/particles/bar-descriptor.xml

@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
-
-<!-- BlackBerry OS application descriptor file.
-    Specifies parameters for identifying, installing, and launching native applications on BlackBerry OS.
--->
-
-    <!-- A universally unique application identifier. Must be unique across all BlackBerry OS applications.
-         Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
-    <id>org.gameplay3d.sample_particles</id>
-
-    <!-- The name that is displayed in the BlackBerry OS application installer. 
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <name>Particles</name>
-
-    <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. 
-         Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
-         An updated version of application must have a versionNumber value higher than the previous version. Required. -->
-    <versionNumber>1.0.0</versionNumber>
-
-    <!-- Fourth digit segment of the package version. First three segments are taken from the 
-         <versionNumber> element. Must be an integer from 0 to 2^16-1 -->
-    <buildId>1</buildId>
-
-    <!-- Description, displayed in the BlackBerry OS application installer.
-         May have multiple values for each language. See samples or xsd schema file. Optional. -->
-    <description>Particles</description>
-
-    <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
-    <author>RIM Canada</author>
-
-    <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
-    <!-- <authorId>gYAAgLDcDLxX077jVWRVnDpywiU</authorId> -->
-
-    <initialWindow>
-        <aspectRatio>landscape</aspectRatio>
-        <autoOrients>false</autoOrients>
-        <systemChrome>none</systemChrome>
-    </initialWindow>
-
-    <category>core.games</category>
-
-    <asset path="icon.png">icon.png</asset>
-    <asset path="res/editor.form">res/editor.form</asset>
-    <asset path="res/editor.png">res/editor.png</asset>
-    <asset path="res/editor.theme">res/editor.theme</asset>
-    <asset path="res/explosion.particle">res/explosion.particle</asset>
-    <asset path="res/explosion.png">res/explosion.png</asset>
-    <asset path="res/fire.particle">res/fire.particle</asset>
-    <asset path="res/fire.png">res/fire.png</asset>
-    <asset path="res/grid.material">res/grid.material</asset>
-    <asset path="res/smoke.particle">res/smoke.particle</asset>
-    <asset path="res/smoke.png">res/smoke.png</asset>
-    <asset path="../../gameplay/res/logo_powered_white.png">res/logo_powered_white.png</asset>
-    <asset path="../../gameplay/res/shaders">res/shaders</asset>
-    <asset path="../../gameplay/res/ui">res/ui</asset>
-
-    <configuration name="Device-Debug">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Debug/sample-particles" entry="true" type="Qnx/Elf">sample-particles</asset>
-    </configuration>
-    <configuration name="Device-Release">
-       <platformArchitecture>armle-v7</platformArchitecture>
-       <asset path="Device-Release/sample-particles" entry="true" type="Qnx/Elf">sample-particles</asset>
-    </configuration>
-    <configuration name="Simulator">
-        <platformArchitecture>x86</platformArchitecture>
-       <asset path="Simulator/sample-particles" entry="true" type="Qnx/Elf">sample-particles</asset>
-    </configuration>
-
-    <!-- The icon for the application, which should be 114x114. -->
-    <icon>
-        <image>icon.png</image>
-    </icon>
-
-    <!-- The splash screen that will appear when your application is launching, which should be 1280x720. -->
-    <!-- <splashscreen></splashscreen> -->
-
-    <!-- The permissions requested by your application. -->
-    <!--  <action>access_shared</action> -->
-    <!--  <action>record_audio</action> -->
-    <!--  <action>read_geolocation</action> -->
-    <!--  <action>use_camera</action> -->
-    <!--  <action>access_internet</action> -->
-    <!--  <action>play_audio</action> -->
-    <!--  <action>post_notification</action> -->
-    <!--  <action>set_audio_volume</action> -->
-    <!--  <action>read_device_identifying_information</action> -->
-
-    <!-- Ensure that shared libraries in the package are found at run-time. -->
-    <env var="LD_LIBRARY_PATH" value="app/native/lib"/>
-
-</qnx>

+ 4 - 4
samples/particles/sample-particles.xcodeproj/project.pbxproj

@@ -493,7 +493,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				USER_HEADER_SEARCH_PATHS = "";
 				VALID_ARCHS = x86_64;
 				WRAPPER_EXTENSION = app;
@@ -527,7 +527,7 @@
 					"../../external-deps/vorbis/lib/macosx/x64",
 					"~/Library/Developer/Xcode/DerivedData/gameplay-exiunaubxxjndaapmcqkaoeboiob/Build/Products/Debug",
 				);
-				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				USER_HEADER_SEARCH_PATHS = "";
 				VALID_ARCHS = x86_64;
 				WRAPPER_EXTENSION = app;
@@ -552,7 +552,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-particles-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",
@@ -589,7 +589,7 @@
 					"../../external-deps/vorbis/include",
 				);
 				INFOPLIST_FILE = "sample-particles-ios.plist";
-				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 7.1;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"../../external-deps/bullet/lib/ios/$(CURRENT_ARCH)",

+ 3 - 3
samples/racer/android/AndroidManifest.xml

@@ -4,14 +4,14 @@
         android:versionCode="1"
         android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="15" />
+    <uses-sdk android:minSdkVersion="16"/>
 	<uses-feature android:glEsVersion="0x00020000"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="true">
-        <activity android:name="android.app.NativeActivity"
+        <activity android:name="org.gameplay3d.GameNativeActivity"
                   android:label="@string/app_name"
-                  android:configChanges="screenSize|orientation|keyboardHidden"
+                  android:configChanges="orientation|keyboardHidden"
 				  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
 				  android:screenOrientation="landscape">
             <meta-data android:name="android.app.lib_name"

+ 31 - 6
samples/racer/android/build.xml

@@ -6,19 +6,44 @@
     
     <loadproperties srcFile="project.properties" />
     
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project'" unless="sdk.dir" />
-
+    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project -t 1 -p . -s'" unless="sdk.dir" />
+	<fail message="OS not supported. Supported platforms: Windows, MacOS X or Linux.">
+	    <condition>
+	      <not>
+	        <or>
+	          <os family="unix"/>
+	          <os family="windows"/>
+	        </or>
+	      </not>
+	    </condition>
+	</fail>
+	<macrodef name="build-native">
+		<attribute name="location"/>
+	     <sequential>
+            <exec osfamily="unix" dir="@{location}/android" executable="ndk-build">
+                <arg value="-j4"/>
+            </exec>
+			<exec osfamily="windows" dir="@{location}/android" executable="cmd">
+				<arg value="/c"/>
+				<arg value="ndk-build -j4"/>
+			</exec> 
+	    </sequential>
+	</macrodef>
+    
     <target name="-pre-build">
-	    <mkdir dir="src"/>
+		<build-native location="../../../gameplay"/>
+    	<build-native location=".."/>
+        <mkdir dir="../src/org/gameplay3d"/>
+	    <copy todir="../src/org/gameplay3d">
+            <fileset dir="../../../gameplay/src/org/gameplay3d"/>
+	    </copy>
     </target>
 	
     <target name="-post-compile">
-	    <copy file="../game.png.config" tofile="assets/game.config"/>
-		
+  	    <copy file="../game.png.config" tofile="assets/game.config"/>
         <copy todir="assets/res/common">
             <fileset dir="../res/common"/>
         </copy>
-		
         <copy todir="assets/res/png">
             <fileset dir="../res/png"/>
         </copy>

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است