Forráskód Böngészése

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

Conflicts:
	gameplay/src/ImageControl.cpp
SAUVAGEOT Paul-Arthur 12 éve
szülő
commit
dbf237cc8d
100 módosított fájl, 5484 hozzáadás és 1017 törlés
  1. 0 25
      .gitignore
  2. 10 0
      CHANGES.md
  3. 2 1
      CMakeLists.txt
  4. 4 3
      README.md
  5. 0 23
      gameplay.sln
  6. 0 3
      gameplay.xcworkspace/contents.xcworkspacedata
  7. 3 1
      gameplay/.cproject
  8. 17 1
      gameplay/CMakeLists.txt
  9. 1 1
      gameplay/android/AndroidManifest.xml
  10. 33 0
      gameplay/android/java/.project
  11. 9 0
      gameplay/android/java/AndroidManifest.xml
  12. 19 31
      gameplay/android/java/build.xml
  13. 190 0
      gameplay/android/java/src/org/gameplay3d/lib/BaseGameActivity.java
  14. 1149 0
      gameplay/android/java/src/org/gameplay3d/lib/GameHelper.java
  15. 118 0
      gameplay/android/java/src/org/gameplay3d/lib/GoogleGamesSocial.java
  16. 12 0
      gameplay/android/java/src/org/gameplay3d/lib/TestClass.java
  17. 8 1
      gameplay/android/jni/Android.mk
  18. 32 13
      gameplay/gameplay.vcxproj
  19. 42 3
      gameplay/gameplay.vcxproj.filters
  20. 132 42
      gameplay/gameplay.xcodeproj/project.pbxproj
  21. 0 7
      gameplay/gameplay.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  22. BIN
      gameplay/gameplay.xcodeproj/project.xcworkspace/xcuserdata/mozeal.xcuserdatad/UserInterfaceState.xcuserstate
  23. 1 1
      gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-ios.xcscheme
  24. 1 1
      gameplay/gameplay.xcodeproj/xcshareddata/xcschemes/gameplay-macosx.xcscheme
  25. 0 0
      gameplay/res/arial.ttf
  26. 14 1
      gameplay/res/shaders/font.frag
  27. 0 1
      gameplay/res/shaders/font.vert
  28. 14 10
      gameplay/src/Base.h
  29. 38 7
      gameplay/src/Bundle.cpp
  30. 16 1
      gameplay/src/Bundle.h
  31. 13 3
      gameplay/src/CheckBox.cpp
  32. 110 10
      gameplay/src/Container.cpp
  33. 1 0
      gameplay/src/Container.h
  34. 287 121
      gameplay/src/Control.cpp
  35. 193 67
      gameplay/src/Control.h
  36. 20 3
      gameplay/src/FlowLayout.cpp
  37. 32 0
      gameplay/src/FlowLayout.h
  38. 22 4
      gameplay/src/Font.cpp
  39. 19 2
      gameplay/src/Font.h
  40. 118 242
      gameplay/src/Form.cpp
  41. 20 49
      gameplay/src/Form.h
  42. 13 1
      gameplay/src/Game.cpp
  43. 12 0
      gameplay/src/Game.h
  44. 5 0
      gameplay/src/Game.inl
  45. 18 0
      gameplay/src/ImageControl.cpp
  46. 5 0
      gameplay/src/ImageControl.h
  47. 12 1
      gameplay/src/Label.cpp
  48. 15 28
      gameplay/src/Layout.cpp
  49. 1 1
      gameplay/src/ParticleEmitter.cpp
  50. 2 0
      gameplay/src/Platform.cpp
  51. 1 2
      gameplay/src/Platform.h
  52. 1 1
      gameplay/src/PlatformAndroid.cpp
  53. 14 1
      gameplay/src/PlatformBlackBerry.cpp
  54. 1 3
      gameplay/src/PlatformLinux.cpp
  55. 1 3
      gameplay/src/PlatformMacOSX.mm
  56. 40 59
      gameplay/src/PlatformWindows.cpp
  57. 6 1
      gameplay/src/PlatformiOS.mm
  58. 14 18
      gameplay/src/Properties.cpp
  59. 8 5
      gameplay/src/Properties.h
  60. 13 3
      gameplay/src/RadioButton.cpp
  61. 10 10
      gameplay/src/RenderState.cpp
  62. 17 5
      gameplay/src/ScriptController.cpp
  63. 14 2
      gameplay/src/Slider.cpp
  64. 9 2
      gameplay/src/SocialAchievement.h
  65. 16 0
      gameplay/src/SocialChallenge.cpp
  66. 86 0
      gameplay/src/SocialChallenge.h
  67. 51 5
      gameplay/src/SocialController.cpp
  68. 20 4
      gameplay/src/SocialController.h
  69. 2 0
      gameplay/src/SocialPlayer.h
  70. 3 1
      gameplay/src/SocialScore.h
  71. 26 3
      gameplay/src/SocialSession.h
  72. 40 0
      gameplay/src/SocialSessionListener.cpp
  73. 25 0
      gameplay/src/SocialSessionListener.h
  74. 1 1
      gameplay/src/SpriteBatch.cpp
  75. 11 9
      gameplay/src/Theme.cpp
  76. 12 2
      gameplay/src/VerticalLayout.cpp
  77. 19 0
      gameplay/src/VerticalLayout.h
  78. 72 0
      gameplay/src/lua/lua_Bundle.cpp
  79. 2 0
      gameplay/src/lua/lua_Bundle.h
  80. 367 24
      gameplay/src/lua/lua_Button.cpp
  81. 6 0
      gameplay/src/lua/lua_Button.h
  82. 367 24
      gameplay/src/lua/lua_CheckBox.cpp
  83. 6 0
      gameplay/src/lua/lua_CheckBox.h
  84. 369 26
      gameplay/src/lua/lua_Container.cpp
  85. 6 0
      gameplay/src/lua/lua_Container.h
  86. 367 24
      gameplay/src/lua/lua_Control.cpp
  87. 6 0
      gameplay/src/lua/lua_Control.h
  88. 36 0
      gameplay/src/lua/lua_ControlAutoSize.cpp
  89. 15 0
      gameplay/src/lua/lua_ControlAutoSize.h
  90. 1 0
      gameplay/src/lua/lua_ControlListener.cpp
  91. 113 0
      gameplay/src/lua/lua_FlowLayout.cpp
  92. 3 0
      gameplay/src/lua/lua_FlowLayout.h
  93. 37 0
      gameplay/src/lua/lua_Font.cpp
  94. 1 0
      gameplay/src/lua/lua_Font.h
  95. 31 0
      gameplay/src/lua/lua_FontFormat.cpp
  96. 15 0
      gameplay/src/lua/lua_FontFormat.h
  97. 1 0
      gameplay/src/lua/lua_FontText.cpp
  98. 369 26
      gameplay/src/lua/lua_Form.cpp
  99. 6 0
      gameplay/src/lua/lua_Form.h
  100. 44 44
      gameplay/src/lua/lua_Game.cpp

+ 0 - 25
.gitignore

@@ -115,31 +115,6 @@ Thumbs.db
 /samples/character/res/gamepad.xcf
 /samples/character/res/gamepad.xcf
 /samples/character/sample-character.xcodeproj/xcuserdata
 /samples/character/sample-character.xcodeproj/xcuserdata
 
 
-/samples/longboard/Debug
-/samples/longboard/DebugMem
-/samples/longboard/Release
-/samples/longboard/Simulator
-/samples/longboard/Simulator-Coverage
-/samples/longboard/Simulator-Profile
-/samples/longboard/Device-Debug
-/samples/longboard/Device-Coverage
-/samples/longboard/Device-Profile
-/samples/longboard/Device-Release
-/samples/longboard/res/shaders
-/samples/longboard/res/logo_powered_white.png
-/samples/longboard/NUL
-/samples/longboard/android/NUL
-/samples/longboard/android/src
-/samples/longboard/android/assets
-/samples/longboard/android/bin
-/samples/longboard/android/gen
-/samples/longboard/android/libs
-/samples/longboard/android/obj
-/samples/longboard/android/proguard.cfg
-/samples/longboard/android/project.properties
-/samples/longboard/android/local.properties
-/samples/longboard/sample-longboard.xcodeproj/xcuserdata
-
 /samples/lua/Debug
 /samples/lua/Debug
 /samples/lua/DebugMem
 /samples/lua/DebugMem
 /samples/lua/Release
 /samples/lua/Release

+ 10 - 0
CHANGES.md

@@ -1,3 +1,13 @@
+## v2.0.0
+
+- Adds support for Visual Studio 2012
+- Adds support for iOS 7, MacOS 10.8 and XCode 5.
+- Adds support for BlackBerry NDK 10.2.
+- Adds support for social achievements, leaderboard and challenges.
+- Adds password mode on textbox controls.
+- Adds collision object group mask filtering.
+- Fixes Mesh Collision shapes.
+
 ## v1.7.0
 ## v1.7.0
 
 
 - Adds -m parameter to encoder to support exporting Material from FBX scenes.
 - Adds -m parameter to encoder to support exporting Material from FBX scenes.

+ 2 - 1
CMakeLists.txt

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.6)
 
 
 project(GamePlay)
 project(GamePlay)
 
 
-set(GAMEPLAY_VERSION 1.7.0)
+set(GAMEPLAY_VERSION 2.0.0)
 set(CMAKE_C_COMPILER_INIT g++)
 set(CMAKE_C_COMPILER_INIT g++)
 
 
 # debug
 # debug
@@ -27,4 +27,5 @@ add_subdirectory(samples)
 # gameplay encoder
 # gameplay encoder
 # A pre-compiled executable can be found in 'gameplay/bin'
 # A pre-compiled executable can be found in 'gameplay/bin'
 # Uncomment out this line if you want to build the encoder instead of using the pre-compiled gameplay-encoder.
 # Uncomment out this line if you want to build the encoder instead of using the pre-compiled gameplay-encoder.
+
 #add_subdirectory(tools/encoder)
 #add_subdirectory(tools/encoder)

+ 4 - 3
README.md

@@ -1,4 +1,4 @@
-## gameplay v1.8.0
+## GamePlay v2.0.0
 
 
 GamePlay3D is an open-source, cross-platform 3D native C++ game framework making it easy to learn and write mobile and desktop games. 
 GamePlay3D is an open-source, cross-platform 3D native C++ game framework making it easy to learn and write mobile and desktop games. 
 
 
@@ -7,7 +7,7 @@ GamePlay3D is an open-source, cross-platform 3D native C++ game framework making
 - [Website](http://www.gameplay3d.org/)
 - [Website](http://www.gameplay3d.org/)
 - [Forums](http://www.gameplay3d.org/forums/)
 - [Forums](http://www.gameplay3d.org/forums/)
 - [Wiki](https://github.com/blackberry/GamePlay/wiki)
 - [Wiki](https://github.com/blackberry/GamePlay/wiki)
-- [API Reference](http://www.gameplay3d.org/api.php)
+- [API Reference](http://blackberry.github.io/GamePlay/api/index.html)
 - [Development Guide](https://github.com/blackberry/GamePlay/wiki#wiki-Development_Guide)
 - [Development Guide](https://github.com/blackberry/GamePlay/wiki#wiki-Development_Guide)
 
 
 ## Supported Platforms
 ## Supported Platforms
@@ -19,7 +19,8 @@ GamePlay3D is an open-source, cross-platform 3D native C++ game framework making
 - [Google Android](https://github.com/blackberry/GamePlay/wiki/Android-NDK-Setup) (using Google Android NDK)
 - [Google Android](https://github.com/blackberry/GamePlay/wiki/Android-NDK-Setup) (using Google Android NDK)
 
 
 ## Roadmap for 'next' branch
 ## Roadmap for 'next' branch
-- [backlog](https://github.com/blackberry/GamePlay/issues?milestone=7)
+- [2.0.0](https://github.com/blackberry/GamePlay/issues?milestone=6&page=1&state=open)
+- [backlog](https://github.com/blackberry/GamePlay/issues?milestone=5&page=1&state=open)
 
 
 ## License
 ## License
 The project is open sourced under the [Apache 2.0 license](http://www.tldrlegal.com/license/apache-license-2.0-%28apache-2.0%29).
 The project is open sourced under the [Apache 2.0 license](http://www.tldrlegal.com/license/apache-license-2.0-%28apache-2.0%29).

+ 0 - 23
gameplay.sln

@@ -18,11 +18,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample-lua", "samples\lua\s
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 	EndProjectSection
 	EndProjectSection
 EndProject
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample-longboard", "samples\longboard\sample-longboard.vcxproj", "{9A515C8B-3320-4C5C-9754-211E91206C9D}"
-	ProjectSection(ProjectDependencies) = postProject
-		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample-spaceship", "samples\spaceship\sample-spaceship.vcxproj", "{CC37B8E9-6402-4841-8D6A-5D908A5909B3}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample-spaceship", "samples\spaceship\sample-spaceship.vcxproj", "{CC37B8E9-6402-4841-8D6A-5D908A5909B3}"
 	ProjectSection(ProjectDependencies) = postProject
 	ProjectSection(ProjectDependencies) = postProject
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A} = {1032BA4B-57EB-4348-9E03-29DD63E80E4A}
@@ -131,24 +126,6 @@ Global
 		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|Win32.Build.0 = Release|Win32
 		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|Win32.Build.0 = Release|Win32
 		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|x64.ActiveCfg = Release|x64
 		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|x64.ActiveCfg = Release|x64
 		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|x64.Build.0 = Release|x64
 		{04EAF3E5-0F9E-AF4D-53F9-269CE114211F}.Release|x64.Build.0 = Release|x64
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.ActiveCfg = Debug|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerrySimulator.ActiveCfg = Debug|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.Build.0 = Debug|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|x64.ActiveCfg = Debug|x64
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|x64.Build.0 = Debug|x64
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.ActiveCfg = DebugMem|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.Build.0 = DebugMem|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|x64.ActiveCfg = DebugMem|x64
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|x64.Build.0 = DebugMem|x64
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.ActiveCfg = Release|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerrySimulator.ActiveCfg = Release|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.ActiveCfg = Release|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.Build.0 = Release|Win32
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|x64.ActiveCfg = Release|x64
-		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|x64.Build.0 = Release|x64
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.ActiveCfg = Debug|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.ActiveCfg = Debug|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.ActiveCfg = Debug|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.ActiveCfg = Debug|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.ActiveCfg = Debug|Win32

+ 0 - 3
gameplay.xcworkspace/contents.xcworkspacedata

@@ -10,9 +10,6 @@
    <FileRef
    <FileRef
       location = "group:samples/character/sample-character.xcodeproj">
       location = "group:samples/character/sample-character.xcodeproj">
    </FileRef>
    </FileRef>
-   <FileRef
-      location = "group:samples/longboard/sample-longboard.xcodeproj">
-   </FileRef>
    <FileRef
    <FileRef
       location = "group:samples/lua/sample-lua.xcodeproj">
       location = "group:samples/lua/sample-lua.xcodeproj">
    </FileRef>  
    </FileRef>  

+ 3 - 1
gameplay/.cproject

@@ -25,6 +25,7 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 									<listOptionValue builtIn="false" value="GP_USE_SOCIAL"/>
 									<listOptionValue builtIn="false" value="GP_USE_SOCIAL"/>
+									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.2133604142" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 								<option id="com.qnx.qcc.option.compiler.includePath.2133604142" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/lua/include&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/lua/include&quot;"/>
@@ -89,6 +90,7 @@
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 									<listOptionValue builtIn="false" value="GP_USE_SOCIAL"/>
 									<listOptionValue builtIn="false" value="GP_USE_SOCIAL"/>
+									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.1670164593" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 								<option id="com.qnx.qcc.option.compiler.includePath.1670164593" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
@@ -147,8 +149,8 @@
 								<option id="com.qnx.qcc.option.compiler.security.1671403331" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.security.1671403331" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="false" valueType="boolean"/>
 								<option id="com.qnx.qcc.option.compiler.defines.1863269886" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 								<option id="com.qnx.qcc.option.compiler.defines.1863269886" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
 									<listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/>
-									<listOptionValue builtIn="false" value="BT_USE_NEON"/>
 									<listOptionValue builtIn="false" value="GP_USE_SOCIAL"/>
 									<listOptionValue builtIn="false" value="GP_USE_SOCIAL"/>
+									<listOptionValue builtIn="false" value="GP_USE_GAMEPAD"/>
 								</option>
 								</option>
 								<option id="com.qnx.qcc.option.compiler.includePath.847642559" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 								<option id="com.qnx.qcc.option.compiler.includePath.847642559" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;../../external-deps/bullet/include&quot;"/>

+ 17 - 1
gameplay/CMakeLists.txt

@@ -194,6 +194,16 @@ set(GAMEPLAY_SRC
     src/ScriptTarget.h
     src/ScriptTarget.h
     src/Slider.cpp
     src/Slider.cpp
     src/Slider.h
     src/Slider.h
+    src/SocialAchievement.cpp
+    src/SocialAchievement.h
+    src/SocialChallenge.cpp
+    src/SocialChallenge.h
+    src/SocialController.cpp
+    src/SocialController.h
+    src/SocialPlayer.cpp
+    src/SocialPlayer.h
+    src/SocialSessionListener.cpp
+    src/SocialSessionListener.h
     src/SpriteBatch.cpp
     src/SpriteBatch.cpp
     src/SpriteBatch.h
     src/SpriteBatch.h
     src/Technique.cpp
     src/Technique.cpp
@@ -299,6 +309,8 @@ set(GAMEPLAY_LUA
     src/lua/lua_Control.h
     src/lua/lua_Control.h
     src/lua/lua_ControlAlignment.cpp
     src/lua/lua_ControlAlignment.cpp
     src/lua/lua_ControlAlignment.h
     src/lua/lua_ControlAlignment.h
+    src/lua/lua_ControlAutoSize.cpp
+    src/lua/lua_ControlAutoSize.h
     src/lua/lua_ControlListener.cpp
     src/lua/lua_ControlListener.cpp
     src/lua/lua_ControlListener.h
     src/lua/lua_ControlListener.h
     src/lua/lua_ControlListenerEventType.cpp
     src/lua/lua_ControlListenerEventType.cpp
@@ -321,6 +333,8 @@ set(GAMEPLAY_LUA
     src/lua/lua_FlowLayout.h
     src/lua/lua_FlowLayout.h
     src/lua/lua_Font.cpp
     src/lua/lua_Font.cpp
     src/lua/lua_Font.h
     src/lua/lua_Font.h
+    src/lua/lua_FontFormat.cpp
+    src/lua/lua_FontFormat.h
     src/lua/lua_FontJustify.cpp
     src/lua/lua_FontJustify.cpp
     src/lua/lua_FontJustify.h
     src/lua/lua_FontJustify.h
     src/lua/lua_FontStyle.cpp
     src/lua/lua_FontStyle.cpp
@@ -498,6 +512,8 @@ set(GAMEPLAY_LUA
     src/lua/lua_RenderStateCullFaceSide.cpp
     src/lua/lua_RenderStateCullFaceSide.cpp
     src/lua/lua_RenderStateDepthFunction.cpp
     src/lua/lua_RenderStateDepthFunction.cpp
     src/lua/lua_RenderStateDepthFunction.h
     src/lua/lua_RenderStateDepthFunction.h
+    src/lua/lua_RenderStateFrontFace.cpp
+    src/lua/lua_RenderStateFrontFace.h
     src/lua/lua_RenderStateStateBlock.cpp
     src/lua/lua_RenderStateStateBlock.cpp
     src/lua/lua_RenderStateStateBlock.h
     src/lua/lua_RenderStateStateBlock.h
     src/lua/lua_RenderStateStencilFunction.cpp
     src/lua/lua_RenderStateStencilFunction.cpp
@@ -618,7 +634,7 @@ include_directories(
     src
     src
     ../external-deps/lua/include
     ../external-deps/lua/include
     ../external-deps/bullet/include
     ../external-deps/bullet/include
-    ../external-deps/libpng/include
+    ../external-deps/png/include
     ../external-deps/zlib/include
     ../external-deps/zlib/include
     ../external-deps/oggvorbis/include
     ../external-deps/oggvorbis/include
     ../external-deps/openal/include
     ../external-deps/openal/include

+ 1 - 1
gameplay/android/AndroidManifest.xml

@@ -2,7 +2,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.gameplay3d.gameplay"
     package="org.gameplay3d.gameplay"
     android:versionCode="1"
     android:versionCode="1"
-    android:versionName="1.0" >
+    android:versionName="2.0" >
 
 
     <uses-sdk android:minSdkVersion="9" />
     <uses-sdk android:minSdkVersion="9" />
 
 

+ 33 - 0
gameplay/android/java/.project

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>libgameplay3d</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

+ 9 - 0
gameplay/android/java/AndroidManifest.xml

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

+ 19 - 31
samples/longboard/android/build.xml → gameplay/android/java/build.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<project name="sample-longboard" default="help">
+<project name="gameplay3dandroid" default="help">
 
 
     <!-- The local.properties file is created and updated by the 'android' tool.
     <!-- The local.properties file is created and updated by the 'android' tool.
          It contains the path to the SDK. It should *NOT* be checked into
          It contains the path to the SDK. It should *NOT* be checked into
@@ -40,36 +40,24 @@
     <loadproperties srcFile="project.properties" />
     <loadproperties srcFile="project.properties" />
 
 
     <!-- quick check on sdk.dir -->
     <!-- quick check on sdk.dir -->
-    <fail message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
-          unless="sdk.dir" />
-
-
-<!-- extension targets. Uncomment the ones where you want to do custom work
-     in between standard targets -->
-    <target name="-pre-build">
-		<mkdir dir="src"/>
-    </target>
-	 
-<!--
-    <target name="-pre-compile">
-    </target>
-
-    /* This is typically used for code obfuscation.
-       Compiled code location: ${out.classes.absolute.dir}
-       If this is not done in place, override ${out.dex.input.absolute.dir} */
-       -->
-    <target name="-post-compile">
-        <copy file="../res/asphalt.png" tofile="assets/res/asphalt.png"/>
-		<copy file="../res/longboard.png" tofile="assets/res/longboard.png"/>
-        <copy file="../res/longboard.wav" tofile="assets/res/longboard.wav"/>
-        <copy file="../res/longboard_wheels.png" tofile="assets/res/longboard_wheels.png"/>
-        <copy file="../res/overlay_gradient.png" tofile="assets/res/overlay_gradient.png"/>
-        <copy file="../../../gameplay/res/logo_powered_white.png" tofile="assets/res/logo_powered_white.png"/>
-        <copy todir="assets/res/shaders">
-            <fileset dir="../../../gameplay/res/shaders"/>
-        </copy>
-    </target>
-
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
 
 
     <!-- Import the actual build file.
     <!-- Import the actual build file.
 
 

+ 190 - 0
gameplay/android/java/src/org/gameplay3d/lib/BaseGameActivity.java

@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.gameplay3d.sample_spaceship.basegameutils;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.google.android.gms.appstate.AppStateClient;
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.games.GamesClient;
+import com.google.android.gms.plus.PlusClient;
+
+/**
+ * Example base class for games. This implementation takes care of setting up
+ * the GamesClient object and managing its lifecycle. Subclasses only need to
+ * override the @link{#onSignInSucceeded} and @link{#onSignInFailed} abstract
+ * methods. To initiate the sign-in flow when the user clicks the sign-in
+ * button, subclasses should call @link{#beginUserInitiatedSignIn}. By default,
+ * this class only instantiates the GamesClient object. If the PlusClient or
+ * AppStateClient objects are also wanted, call the BaseGameActivity(int)
+ * constructor and specify the requested clients. For example, to request
+ * PlusClient and GamesClient, use BaseGameActivity(CLIENT_GAMES | CLIENT_PLUS).
+ * To request all available clients, use BaseGameActivity(CLIENT_ALL).
+ * Alternatively, you can also specify the requested clients via
+ * @link{#setRequestedClients}, but you must do so before @link{#onCreate}
+ * gets called, otherwise the call will have no effect.
+ *
+ * @author Bruno Oliveira (Google)
+ */
+public abstract class BaseGameActivity extends FragmentActivity implements
+        GameHelper.GameHelperListener {
+
+    // The game helper object. This class is mainly a wrapper around this object.
+    protected GameHelper mHelper;
+
+    // We expose these constants here because we don't want users of this class
+    // to have to know about GameHelper at all.
+    public static final int CLIENT_GAMES = GameHelper.CLIENT_GAMES;
+    public static final int CLIENT_APPSTATE = GameHelper.CLIENT_APPSTATE;
+    public static final int CLIENT_PLUS = GameHelper.CLIENT_PLUS;
+    public static final int CLIENT_ALL = GameHelper.CLIENT_ALL;
+
+    // Requested clients. By default, that's just the games client.
+    protected int mRequestedClients = CLIENT_GAMES;
+
+    // stores any additional scopes.
+    private String[] mAdditionalScopes;
+
+    protected String mDebugTag = "BaseGameActivity";
+    protected boolean mDebugLog = false;
+
+    /** Constructs a BaseGameActivity with default client (GamesClient). */
+    protected BaseGameActivity() {
+        super();
+        mHelper = new GameHelper(this);
+    }
+
+    /**
+     * Constructs a BaseGameActivity with the requested clients.
+     * @param requestedClients The requested clients (a combination of CLIENT_GAMES,
+     *         CLIENT_PLUS and CLIENT_APPSTATE).
+     */
+    protected BaseGameActivity(int requestedClients) {
+        super();
+        setRequestedClients(requestedClients);
+    }
+
+    /**
+     * Sets the requested clients. The preferred way to set the requested clients is
+     * via the constructor, but this method is available if for some reason your code
+     * cannot do this in the constructor. This must be called before onCreate in order to
+     * have any effect. If called after onCreate, this method is a no-op.
+     *
+     * @param requestedClients A combination of the flags CLIENT_GAMES, CLIENT_PLUS
+     *         and CLIENT_APPSTATE, or CLIENT_ALL to request all available clients.
+     * @param additionalScopes.  Scopes that should also be requested when the auth
+     *         request is made.
+     */
+    protected void setRequestedClients(int requestedClients, String ... additionalScopes) {
+        mRequestedClients = requestedClients;
+        mAdditionalScopes = additionalScopes;
+    }
+
+    @Override
+    protected void onCreate(Bundle b) {
+        super.onCreate(b);
+        mHelper = new GameHelper(this);
+        if (mDebugLog) {
+            mHelper.enableDebugLog(mDebugLog, mDebugTag);
+        }
+        mHelper.setup(this, mRequestedClients, mAdditionalScopes);
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mHelper.onStart(this);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mHelper.onStop();
+    }
+
+    @Override
+    protected void onActivityResult(int request, int response, Intent data) {
+        super.onActivityResult(request, response, data);
+        mHelper.onActivityResult(request, response, data);
+    }
+
+    protected GamesClient getGamesClient() {
+        return mHelper.getGamesClient();
+    }
+
+    protected AppStateClient getAppStateClient() {
+        return mHelper.getAppStateClient();
+    }
+
+    protected PlusClient getPlusClient() {
+        return mHelper.getPlusClient();
+    }
+
+    protected boolean isSignedIn() {
+        return mHelper.isSignedIn();
+    }
+
+    protected void beginUserInitiatedSignIn() {
+        mHelper.beginUserInitiatedSignIn();
+    }
+
+    protected void signOut() {
+        mHelper.signOut();
+    }
+
+    protected void showAlert(String title, String message) {
+        mHelper.showAlert(title, message);
+    }
+
+    protected void showAlert(String message) {
+        mHelper.showAlert(message);
+    }
+
+    protected void enableDebugLog(boolean enabled, String tag) {
+        mDebugLog = true;
+        mDebugTag = tag;
+        if (mHelper != null) {
+            mHelper.enableDebugLog(enabled, tag);
+        }
+    }
+
+    protected String getInvitationId() {
+        return mHelper.getInvitationId();
+    }
+
+    protected void reconnectClients(int whichClients) {
+        mHelper.reconnectClients(whichClients);
+    }
+
+    protected String getScopes() {
+        return mHelper.getScopes();
+    }
+
+    protected String[] getScopesArray() {
+        return mHelper.getScopesArray();
+    }
+
+    protected boolean hasSignInError() {
+        return mHelper.hasSignInError();
+    }
+
+    protected GameHelper.SignInFailureReason getSignInError() {
+        return mHelper.getSignInError();
+    }
+}

+ 1149 - 0
gameplay/android/java/src/org/gameplay3d/lib/GameHelper.java

@@ -0,0 +1,1149 @@
+/*
+ * Copyright (C) 2013 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.gameplay3d.sample_spaceship.basegameutils;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Vector;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentSender.SendIntentException;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Gravity;
+
+import com.google.android.gms.appstate.AppStateClient;
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.GooglePlayServicesClient;
+import com.google.android.gms.common.GooglePlayServicesUtil;
+import com.google.android.gms.common.Scopes;
+import com.google.android.gms.games.GamesActivityResultCodes;
+import com.google.android.gms.games.GamesClient;
+import com.google.android.gms.games.multiplayer.Invitation;
+import com.google.android.gms.plus.PlusClient;
+
+public class GameHelper implements GooglePlayServicesClient.ConnectionCallbacks,
+        GooglePlayServicesClient.OnConnectionFailedListener {
+
+    /** Listener for sign-in success or failure events. */
+    public interface GameHelperListener {
+        /**
+         * Called when sign-in fails. As a result, a "Sign-In" button can be
+         * shown to the user; when that button is clicked, call
+         * @link{GamesHelper#beginUserInitiatedSignIn}. Note that not all calls to this
+         * method mean an error; it may be a result of the fact that automatic
+         * sign-in could not proceed because user interaction was required
+         * (consent dialogs). So implementations of this method should NOT
+         * display an error message unless a call to @link{GamesHelper#hasSignInError}
+         * indicates that an error indeed occurred.
+         */
+        void onSignInFailed();
+
+        /** Called when sign-in succeeds. */
+        void onSignInSucceeded();
+    }
+
+    // States we can be in
+    public static final int STATE_UNCONFIGURED = 0;
+    public static final int STATE_DISCONNECTED = 1;
+    public static final int STATE_CONNECTING = 2;
+    public static final int STATE_CONNECTED = 3;
+
+    // State names (for debug logging, etc)
+    public static final String[] STATE_NAMES = {
+            "UNCONFIGURED", "DISCONNECTED", "CONNECTING", "CONNECTED"
+    };
+
+    // State we are in right now
+    int mState = STATE_UNCONFIGURED;
+
+    // Are we expecting the result of a resolution flow?
+    boolean mExpectingResolution = false;
+
+    /**
+     * The Activity we are bound to. We need to keep a reference to the Activity
+     * because some games methods require an Activity (a Context won't do). We
+     * are careful not to leak these references: we release them on onStop().
+     */
+    Activity mActivity = null;
+
+    // OAuth scopes required for the clients. Initialized in setup().
+    String mScopes[];
+
+    // Request code we use when invoking other Activities to complete the
+    // sign-in flow.
+    final static int RC_RESOLVE = 9001;
+
+    // Request code when invoking Activities whose result we don't care about.
+    final static int RC_UNUSED = 9002;
+
+    // Client objects we manage. If a given client is not enabled, it is null.
+    GamesClient mGamesClient = null;
+    PlusClient mPlusClient = null;
+    AppStateClient mAppStateClient = null;
+
+    // What clients we manage (OR-able values, can be combined as flags)
+    public final static int CLIENT_NONE = 0x00;
+    public final static int CLIENT_GAMES = 0x01;
+    public final static int CLIENT_PLUS = 0x02;
+    public final static int CLIENT_APPSTATE = 0x04;
+    public final static int CLIENT_ALL = CLIENT_GAMES | CLIENT_PLUS | CLIENT_APPSTATE;
+
+    // What clients were requested? (bit flags)
+    int mRequestedClients = CLIENT_NONE;
+
+    // What clients are currently connected? (bit flags)
+    int mConnectedClients = CLIENT_NONE;
+
+    // What client are we currently connecting?
+    int mClientCurrentlyConnecting = CLIENT_NONE;
+
+    // Whether to automatically try to sign in on onStart().
+    boolean mAutoSignIn = true;
+
+    /*
+     * Whether user has specifically requested that the sign-in process begin.
+     * If mUserInitiatedSignIn is false, we're in the automatic sign-in attempt
+     * that we try once the Activity is started -- if true, then the user has
+     * already clicked a "Sign-In" button or something similar
+     */
+    boolean mUserInitiatedSignIn = false;
+
+    // The connection result we got from our last attempt to sign-in.
+    ConnectionResult mConnectionResult = null;
+
+    // The error that happened during sign-in.
+    SignInFailureReason mSignInFailureReason = null;
+
+    // Print debug logs?
+    boolean mDebugLog = false;
+    String mDebugTag = "GameHelper";
+
+    /*
+     * If we got an invitation id when we connected to the games client, it's
+     * here. Otherwise, it's null.
+     */
+    String mInvitationId;
+
+    // Listener
+    GameHelperListener mListener = null;
+
+    /**
+     * Construct a GameHelper object, initially tied to the given Activity.
+     * After constructing this object, call @link{setup} from the onCreate()
+     * method of your Activity.
+     */
+    public GameHelper(Activity activity) {
+        mActivity = activity;
+    }
+
+    static private final int TYPE_DEVELOPER_ERROR = 1001;
+    static private final int TYPE_GAMEHELPER_BUG = 1002;
+    boolean checkState(int type, String operation, String warning, int... expectedStates) {
+        for (int expectedState : expectedStates) {
+            if (mState == expectedState) {
+                return true;
+            }
+        }
+        StringBuilder sb = new StringBuilder();
+        if (type == TYPE_DEVELOPER_ERROR) {
+            sb.append("GameHelper: you attempted an operation at an invalid. ");
+        } else {
+            sb.append("GameHelper: bug detected. Please report it at our bug tracker ");
+            sb.append("https://github.com/playgameservices/android-samples/issues. ");
+            sb.append("Please include the last couple hundred lines of logcat output ");
+            sb.append("and describe the operation that caused this. ");
+        }
+        sb.append("Explanation: ").append(warning);
+        sb.append("Operation: ").append(operation).append(". ");
+        sb.append("State: ").append(STATE_NAMES[mState]).append(". ");
+        if (expectedStates.length == 1) {
+            sb.append("Expected state: ").append(STATE_NAMES[expectedStates[0]]).append(".");
+        } else {
+            sb.append("Expected states:");
+            for (int expectedState : expectedStates) {
+                sb.append(" " ).append(STATE_NAMES[expectedState]);
+            }
+            sb.append(".");
+        }
+
+        logWarn(sb.toString());
+        return false;
+    }
+
+    void assertConfigured(String operation) {
+        if (mState == STATE_UNCONFIGURED) {
+            String error = "GameHelper error: Operation attempted without setup: " + operation +
+                    ". The setup() method must be called before attempting any other operation.";
+            logError(error);
+            throw new IllegalStateException(error);
+        }
+    }
+
+    /**
+     * Same as calling @link{setup(GameHelperListener, int)} requesting only the
+     * CLIENT_GAMES client.
+     */
+    public void setup(GameHelperListener listener) {
+        setup(listener, CLIENT_GAMES);
+    }
+
+    /**
+     * Performs setup on this GameHelper object. Call this from the onCreate()
+     * method of your Activity. This will create the clients and do a few other
+     * initialization tasks. Next, call @link{#onStart} from the onStart()
+     * method of your Activity.
+     *
+     * @param listener The listener to be notified of sign-in events.
+     * @param clientsToUse The clients to use. Use a combination of
+     *            CLIENT_GAMES, CLIENT_PLUS and CLIENT_APPSTATE, or CLIENT_ALL
+     *            to request all clients.
+     * @param additionalScopes Any scopes to be used that are outside of the ones defined
+     *            in the Scopes class.
+     *            I.E. for YouTube uploads one would add
+     *            "https://www.googleapis.com/auth/youtube.upload"
+     */
+    public void setup(GameHelperListener listener, int clientsToUse, String ... additionalScopes) {
+        if (mState != STATE_UNCONFIGURED) {
+            String error = "GameHelper: you called GameHelper.setup() twice. You can only call " +
+                    "it once.";
+            logError(error);
+            throw new IllegalStateException(error);
+        }
+        mListener = listener;
+        mRequestedClients = clientsToUse;
+
+        debugLog("Setup: requested clients: " + mRequestedClients);
+
+        Vector<String> scopesVector = new Vector<String>();
+        if (0 != (clientsToUse & CLIENT_GAMES)) {
+            scopesVector.add(Scopes.GAMES);
+        }
+        if (0 != (clientsToUse & CLIENT_PLUS)) {
+            scopesVector.add(Scopes.PLUS_LOGIN);
+        }
+        if (0 != (clientsToUse & CLIENT_APPSTATE)) {
+            scopesVector.add(Scopes.APP_STATE);
+        }
+
+        if (null != additionalScopes) {
+            for (String scope : additionalScopes) {
+                scopesVector.add(scope);
+            }
+        }
+
+        mScopes = new String[scopesVector.size()];
+        scopesVector.copyInto(mScopes);
+
+        debugLog("setup: scopes:");
+        for (String scope : mScopes) {
+            debugLog("  - " + scope);
+        }
+
+        if (0 != (clientsToUse & CLIENT_GAMES)) {
+            debugLog("setup: creating GamesClient");
+            mGamesClient = new GamesClient.Builder(getContext(), this, this)
+                    .setGravityForPopups(Gravity.TOP | Gravity.CENTER_HORIZONTAL)
+                    .setScopes(mScopes)
+                    .create();
+        }
+
+        if (0 != (clientsToUse & CLIENT_PLUS)) {
+            debugLog("setup: creating GamesPlusClient");
+            mPlusClient = new PlusClient.Builder(getContext(), this, this)
+                    .setScopes(mScopes)
+                    .build();
+        }
+
+        if (0 != (clientsToUse & CLIENT_APPSTATE)) {
+            debugLog("setup: creating AppStateClient");
+            mAppStateClient = new AppStateClient.Builder(getContext(), this, this)
+                    .setScopes(mScopes)
+                    .create();
+        }
+        setState(STATE_DISCONNECTED);
+    }
+
+    void setState(int newState) {
+        String oldStateName = STATE_NAMES[mState];
+        String newStateName = STATE_NAMES[newState];
+        mState = newState;
+        debugLog("State change " + oldStateName + " -> " + newStateName);
+    }
+
+    /**
+     * Returns the GamesClient object. In order to call this method, you must have
+     * called @link{setup} with a set of clients that includes CLIENT_GAMES.
+     */
+    public GamesClient getGamesClient() {
+        if (mGamesClient == null) {
+            throw new IllegalStateException("No GamesClient. Did you request it at setup?");
+        }
+        return mGamesClient;
+    }
+
+    /**
+     * Returns the AppStateClient object. In order to call this method, you must have
+     * called @link{#setup} with a set of clients that includes CLIENT_APPSTATE.
+     */
+    public AppStateClient getAppStateClient() {
+        if (mAppStateClient == null) {
+            throw new IllegalStateException("No AppStateClient. Did you request it at setup?");
+        }
+        return mAppStateClient;
+    }
+
+    /**
+     * Returns the PlusClient object. In order to call this method, you must have
+     * called @link{#setup} with a set of clients that includes CLIENT_PLUS.
+     */
+    public PlusClient getPlusClient() {
+        if (mPlusClient == null) {
+            throw new IllegalStateException("No PlusClient. Did you request it at setup?");
+        }
+        return mPlusClient;
+    }
+
+    /** Returns whether or not the user is signed in. */
+    public boolean isSignedIn() {
+        return mState == STATE_CONNECTED;
+    }
+
+    /**
+     * Returns whether or not there was a (non-recoverable) error during the
+     * sign-in process.
+     */
+    public boolean hasSignInError() {
+        return mSignInFailureReason != null;
+    }
+
+    /**
+     * Returns the error that happened during the sign-in process, null if no
+     * error occurred.
+     */
+    public SignInFailureReason getSignInError() {
+        return mSignInFailureReason;
+    }
+
+    /** Call this method from your Activity's onStart(). */
+    public void onStart(Activity act) {
+        mActivity = act;
+
+        debugLog("onStart, state = " + STATE_NAMES[mState]);
+        assertConfigured("onStart");
+
+        switch (mState) {
+            case STATE_DISCONNECTED:
+                // we are not connected, so attempt to connect
+                if (mAutoSignIn) {
+                    debugLog("onStart: Now connecting clients.");
+                    startConnections();
+                } else {
+                    debugLog("onStart: Not connecting (user specifically signed out).");
+                }
+                break;
+            case STATE_CONNECTING:
+                // connection process is in progress; no action required
+                debugLog("onStart: connection process in progress, no action taken.");
+                break;
+            case STATE_CONNECTED:
+                // already connected (for some strange reason). No complaints :-)
+                debugLog("onStart: already connected (unusual, but ok).");
+                break;
+            default:
+                String msg =  "onStart: BUG: unexpected state " + STATE_NAMES[mState];
+                logError(msg);
+                throw new IllegalStateException(msg);
+        }
+    }
+
+    /** Call this method from your Activity's onStop(). */
+    public void onStop() {
+        debugLog("onStop, state = " + STATE_NAMES[mState]);
+        assertConfigured("onStop");
+        switch (mState) {
+            case STATE_CONNECTED:
+            case STATE_CONNECTING:
+                // kill connections
+                debugLog("onStop: Killing connections");
+                killConnections();
+                break;
+            case STATE_DISCONNECTED:
+                debugLog("onStop: not connected, so no action taken.");
+                break;
+            default:
+                String msg =  "onStop: BUG: unexpected state " + STATE_NAMES[mState];
+                logError(msg);
+                throw new IllegalStateException(msg);
+        }
+
+        // let go of the Activity reference
+        mActivity = null;
+    }
+
+    /** Convenience method to show an alert dialog. */
+    public void showAlert(String title, String message) {
+        (new AlertDialog.Builder(getContext())).setTitle(title).setMessage(message)
+                .setNeutralButton(android.R.string.ok, null).create().show();
+    }
+
+    /** Convenience method to show an alert dialog. */
+    public void showAlert(String message) {
+        (new AlertDialog.Builder(getContext())).setMessage(message)
+                .setNeutralButton(android.R.string.ok, null).create().show();
+    }
+
+    /**
+     * Returns the invitation ID received through an invitation notification.
+     * This should be called from your GameHelperListener's
+     *
+     * @link{GameHelperListener#onSignInSucceeded} method, to check if there's an
+     * invitation available. In that case, accept the invitation.
+     * @return The id of the invitation, or null if none was received.
+     */
+    public String getInvitationId() {
+        if (!checkState(TYPE_DEVELOPER_ERROR, "getInvitationId",
+                "Invitation ID is only available when connected " +
+                "(after getting the onSignInSucceeded callback).", STATE_CONNECTED)) {
+            return null;
+        }
+        return mInvitationId;
+    }
+
+    /** Enables debug logging */
+    public void enableDebugLog(boolean enabled, String tag) {
+        mDebugLog = enabled;
+        mDebugTag = tag;
+        if (enabled) {
+            debugLog("Debug log enabled, tag: " + tag);
+        }
+    }
+
+    /**
+     * Returns the current requested scopes. This is not valid until setup() has
+     * been called.
+     *
+     * @return the requested scopes, including the oauth2: prefix
+     */
+    public String getScopes() {
+        StringBuilder scopeStringBuilder = new StringBuilder();
+        if (null != mScopes) {
+            for (String scope: mScopes) {
+                addToScope(scopeStringBuilder, scope);
+            }
+        }
+        return scopeStringBuilder.toString();
+    }
+
+    /**
+     * Returns an array of the current requested scopes. This is not valid until
+     * setup() has been called
+     *
+     * @return the requested scopes, including the oauth2: prefix
+     */
+    public String[] getScopesArray() {
+        return mScopes;
+    }
+
+    /** Sign out and disconnect from the APIs. */
+    public void signOut() {
+        if (mState == STATE_DISCONNECTED) {
+            // nothing to do
+            debugLog("signOut: state was already DISCONNECTED, ignoring.");
+            return;
+        }
+
+        // for the PlusClient, "signing out" means clearing the default account and
+        // then disconnecting
+        if (mPlusClient != null && mPlusClient.isConnected()) {
+            debugLog("Clearing default account on PlusClient.");
+            mPlusClient.clearDefaultAccount();
+        }
+
+        // For the games client, signing out means calling signOut and disconnecting
+        if (mGamesClient != null && mGamesClient.isConnected()) {
+            debugLog("Signing out from GamesClient.");
+            mGamesClient.signOut();
+        }
+
+        // Ready to disconnect
+        debugLog("Proceeding with disconnection.");
+        killConnections();
+    }
+
+    void killConnections() {
+        if (!checkState(TYPE_GAMEHELPER_BUG, "killConnections", "killConnections() should only " +
+                "get called while connected or connecting.", STATE_CONNECTED, STATE_CONNECTING)) {
+            return;
+        }
+        debugLog("killConnections: killing connections.");
+
+        mConnectionResult = null;
+        mSignInFailureReason = null;
+
+        if (mGamesClient != null && mGamesClient.isConnected()) {
+            debugLog("Disconnecting GamesClient.");
+            mGamesClient.disconnect();
+        }
+        if (mPlusClient != null && mPlusClient.isConnected()) {
+            debugLog("Disconnecting PlusClient.");
+            mPlusClient.disconnect();
+        }
+        if (mAppStateClient != null && mAppStateClient.isConnected()) {
+            debugLog("Disconnecting AppStateClient.");
+            mAppStateClient.disconnect();
+        }
+        mConnectedClients = CLIENT_NONE;
+        debugLog("killConnections: all clients disconnected.");
+        setState(STATE_DISCONNECTED);
+    }
+
+    static String activityResponseCodeToString(int respCode) {
+        switch (respCode) {
+            case Activity.RESULT_OK:
+                return "RESULT_OK";
+            case Activity.RESULT_CANCELED:
+                return "RESULT_CANCELED";
+            case GamesActivityResultCodes.RESULT_APP_MISCONFIGURED:
+                return "RESULT_APP_MISCONFIGURED";
+            case GamesActivityResultCodes.RESULT_LEFT_ROOM:
+                return "RESULT_LEFT_ROOM";
+            case GamesActivityResultCodes.RESULT_LICENSE_FAILED:
+                return "RESULT_LICENSE_FAILED";
+            case GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED:
+                return "RESULT_RECONNECT_REQUIRED";
+            case GamesActivityResultCodes.RESULT_SIGN_IN_FAILED:
+                return "SIGN_IN_FAILED";
+            default:
+                return String.valueOf(respCode);
+        }
+    }
+
+    /**
+     * Handle activity result. Call this method from your Activity's
+     * onActivityResult callback. If the activity result pertains to the sign-in
+     * process, processes it appropriately.
+     */
+    public void onActivityResult(int requestCode, int responseCode, Intent intent) {
+        debugLog("onActivityResult: req=" + (requestCode == RC_RESOLVE ? "RC_RESOLVE" :
+                String.valueOf(requestCode)) + ", resp=" +
+                activityResponseCodeToString(responseCode));
+        if (requestCode != RC_RESOLVE) {
+            debugLog("onActivityResult: request code not meant for us. Ignoring.");
+            return;
+        }
+
+        // no longer expecting a resolution
+        mExpectingResolution = false;
+
+        if (mState != STATE_CONNECTING) {
+            debugLog("onActivityResult: ignoring because state isn't STATE_CONNECTING (" +
+                    "it's " + STATE_NAMES[mState] + ")");
+            return;
+        }
+
+        // We're coming back from an activity that was launched to resolve a
+        // connection problem. For example, the sign-in UI.
+        if (responseCode == Activity.RESULT_OK) {
+            // Ready to try to connect again.
+            debugLog("onAR: Resolution was RESULT_OK, so connecting current client again.");
+            connectCurrentClient();
+        } else if (responseCode == GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED) {
+            debugLog("onAR: Resolution was RECONNECT_REQUIRED, so reconnecting.");
+            connectCurrentClient();
+        } else if (responseCode == Activity.RESULT_CANCELED) {
+            // User cancelled.
+            debugLog("onAR: Got a cancellation result, so disconnecting.");
+            mAutoSignIn = false;
+            mUserInitiatedSignIn = false;
+            mSignInFailureReason = null; // cancelling is not a failure!
+            killConnections();
+            notifyListener(false);
+        } else {
+            // Whatever the problem we were trying to solve, it was not
+            // solved. So give up and show an error message.
+            debugLog("onAR: responseCode="  + activityResponseCodeToString(responseCode) +
+                        ", so giving up.");
+            giveUp(new SignInFailureReason(mConnectionResult.getErrorCode(), responseCode));
+        }
+    }
+
+    void notifyListener(boolean success) {
+        debugLog("Notifying LISTENER of sign-in " + (success ? "SUCCESS" :
+                mSignInFailureReason != null ? "FAILURE (error)" : "FAILURE (no error)"));
+        if (mListener != null) {
+            if (success) {
+                mListener.onSignInSucceeded();
+            } else {
+                mListener.onSignInFailed();
+            }
+        }
+    }
+
+    /**
+     * Starts a user-initiated sign-in flow. This should be called when the user
+     * clicks on a "Sign In" button. As a result, authentication/consent dialogs
+     * may show up. At the end of the process, the GameHelperListener's
+     * onSignInSucceeded() or onSignInFailed() methods will be called.
+     */
+    public void beginUserInitiatedSignIn() {
+        if (mState == STATE_CONNECTED) {
+            // nothing to do
+            logWarn("beginUserInitiatedSignIn() called when already connected. " +
+                    "Calling listener directly to notify of success.");
+            notifyListener(true);
+            return;
+        } else if (mState == STATE_CONNECTING) {
+            logWarn("beginUserInitiatedSignIn() called when already connecting. " +
+                    "Be patient! You can only call this method after you get an " +
+                    "onSignInSucceeded() or onSignInFailed() callback. Suggestion: disable " +
+                    "the sign-in button on startup and also when it's clicked, and re-enable " +
+                    "when you get the callback.");
+            // ignore call (listener will get a callback when the connection process finishes)
+            return;
+        }
+
+        debugLog("Starting USER-INITIATED sign-in flow.");
+
+        // sign in automatically on onStart()
+        mAutoSignIn = true;
+
+        // Is Google Play services available?
+        int result = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getContext());
+        debugLog("isGooglePlayServicesAvailable returned " + result);
+        if (result != ConnectionResult.SUCCESS) {
+            // Google Play services is not available.
+            debugLog("Google Play services not available. Show error dialog.");
+            mSignInFailureReason = new SignInFailureReason(result, 0);
+            showFailureDialog();
+            notifyListener(false);
+            return;
+        }
+
+        // indicate that user is actively trying to sign in (so we know to resolve
+        // connection problems by showing dialogs)
+        mUserInitiatedSignIn = true;
+
+        if (mConnectionResult != null) {
+            // We have a pending connection result from a previous failure, so
+            // start with that.
+            debugLog("beginUserInitiatedSignIn: continuing pending sign-in flow.");
+            setState(STATE_CONNECTING);
+            resolveConnectionResult();
+        } else {
+            // We don't have a pending connection result, so start anew.
+            debugLog("beginUserInitiatedSignIn: starting new sign-in flow.");
+            startConnections();
+        }
+    }
+
+    Context getContext() {
+        return mActivity;
+    }
+
+    void addToScope(StringBuilder scopeStringBuilder, String scope) {
+        if (scopeStringBuilder.length() == 0) {
+            scopeStringBuilder.append("oauth2:");
+        } else {
+            scopeStringBuilder.append(" ");
+        }
+        scopeStringBuilder.append(scope);
+    }
+
+    void startConnections() {
+        if (!checkState(TYPE_GAMEHELPER_BUG, "startConnections", "startConnections should " +
+                "only get called when disconnected.", STATE_DISCONNECTED)) {
+            return;
+        }
+        debugLog("Starting connections.");
+        setState(STATE_CONNECTING);
+        mInvitationId = null;
+        connectNextClient();
+    }
+
+    void connectNextClient() {
+        // do we already have all the clients we need?
+        debugLog("connectNextClient: requested clients: " + mRequestedClients +
+                    ", connected clients: " + mConnectedClients);
+
+        // failsafe, in case we somehow lost track of what clients are connected or not.
+        if (mGamesClient != null && mGamesClient.isConnected() &&
+                (0 == (mConnectedClients & CLIENT_GAMES))) {
+            logWarn("GamesClient was already connected. Fixing.");
+            mConnectedClients |= CLIENT_GAMES;
+        }
+        if (mPlusClient != null && mPlusClient.isConnected() &&
+                (0 == (mConnectedClients & CLIENT_PLUS))) {
+            logWarn("PlusClient was already connected. Fixing.");
+            mConnectedClients |= CLIENT_PLUS;
+        }
+        if (mAppStateClient != null && mAppStateClient.isConnected() &&
+                (0 == (mConnectedClients & CLIENT_APPSTATE))) {
+            logWarn("AppStateClient was already connected. Fixing");
+            mConnectedClients |= CLIENT_APPSTATE;
+        }
+
+        int pendingClients = mRequestedClients & ~mConnectedClients;
+        debugLog("Pending clients: " + pendingClients);
+
+        if (pendingClients == 0) {
+            debugLog("All clients now connected. Sign-in successful!");
+            succeedSignIn();
+            return;
+        }
+
+        // which client should be the next one to connect?
+        if (mGamesClient != null && (0 != (pendingClients & CLIENT_GAMES))) {
+            debugLog("Connecting GamesClient.");
+            mClientCurrentlyConnecting = CLIENT_GAMES;
+        } else if (mPlusClient != null && (0 != (pendingClients & CLIENT_PLUS))) {
+            debugLog("Connecting PlusClient.");
+            mClientCurrentlyConnecting = CLIENT_PLUS;
+        } else if (mAppStateClient != null && (0 != (pendingClients & CLIENT_APPSTATE))) {
+            debugLog("Connecting AppStateClient.");
+            mClientCurrentlyConnecting = CLIENT_APPSTATE;
+        } else {
+            // hmmm, getting here would be a bug.
+            throw new AssertionError("Not all clients connected, yet no one is next. R="
+                    + mRequestedClients + ", C=" + mConnectedClients);
+        }
+
+        connectCurrentClient();
+    }
+
+    void connectCurrentClient() {
+        if (mState == STATE_DISCONNECTED) {
+            // we got disconnected during the connection process, so abort
+            logWarn("GameHelper got disconnected during connection process. Aborting.");
+            return;
+        }
+        if (!checkState(TYPE_GAMEHELPER_BUG, "connectCurrentClient", "connectCurrentClient " +
+                "should only get called when connecting.", STATE_CONNECTING)) {
+            return;
+        }
+
+        switch (mClientCurrentlyConnecting) {
+            case CLIENT_GAMES:
+                mGamesClient.connect();
+                break;
+            case CLIENT_APPSTATE:
+                mAppStateClient.connect();
+                break;
+            case CLIENT_PLUS:
+                mPlusClient.connect();
+                break;
+        }
+    }
+
+    /**
+     * Disconnects the indicated clients, then connects them again.
+     * @param whatClients Indicates which clients to reconnect.
+     */
+    public void reconnectClients(int whatClients) {
+        checkState(TYPE_DEVELOPER_ERROR, "reconnectClients", "reconnectClients should " +
+                "only be called when connected. Proceeding anyway.", STATE_CONNECTED);
+        boolean actuallyReconnecting = false;
+
+        if ((whatClients & CLIENT_GAMES) != 0 && mGamesClient != null
+                && mGamesClient.isConnected()) {
+            debugLog("Reconnecting GamesClient.");
+            actuallyReconnecting = true;
+            mConnectedClients &= ~CLIENT_GAMES;
+            mGamesClient.reconnect();
+        }
+        if ((whatClients & CLIENT_APPSTATE) != 0 && mAppStateClient != null
+                && mAppStateClient.isConnected()) {
+            debugLog("Reconnecting AppStateClient.");
+            actuallyReconnecting = true;
+            mConnectedClients &= ~CLIENT_APPSTATE;
+            mAppStateClient.reconnect();
+        }
+        if ((whatClients & CLIENT_PLUS) != 0 && mPlusClient != null
+                && mPlusClient.isConnected()) {
+            // PlusClient doesn't need reconnections.
+            logWarn("GameHelper is ignoring your request to reconnect " +
+                    "PlusClient because this is unnecessary.");
+        }
+
+        if (actuallyReconnecting) {
+            setState(STATE_CONNECTING);
+        } else {
+            // No reconnections are to take place, so for consistency we call the listener
+            // as if sign in had just succeeded.
+            debugLog("No reconnections needed, so behaving as if sign in just succeeded");
+            notifyListener(true);
+        }
+    }
+
+    /** Called when we successfully obtain a connection to a client. */
+    @Override
+    public void onConnected(Bundle connectionHint) {
+        debugLog("onConnected: connected! client=" + mClientCurrentlyConnecting);
+
+        // Mark the current client as connected
+        mConnectedClients |= mClientCurrentlyConnecting;
+        debugLog("Connected clients updated to: " + mConnectedClients);
+
+        // If this was the games client and it came with an invite, store it for
+        // later retrieval.
+        if (mClientCurrentlyConnecting == CLIENT_GAMES && connectionHint != null) {
+            debugLog("onConnected: connection hint provided. Checking for invite.");
+            Invitation inv = connectionHint.getParcelable(GamesClient.EXTRA_INVITATION);
+            if (inv != null && inv.getInvitationId() != null) {
+                // accept invitation
+                debugLog("onConnected: connection hint has a room invite!");
+                mInvitationId = inv.getInvitationId();
+                debugLog("Invitation ID: " + mInvitationId);
+            }
+        }
+
+        // connect the next client in line, if any.
+        connectNextClient();
+    }
+
+    void succeedSignIn() {
+        checkState(TYPE_GAMEHELPER_BUG, "succeedSignIn", "succeedSignIn should only " +
+                "get called in the connecting or connected state. Proceeding anyway.",
+                STATE_CONNECTING, STATE_CONNECTED);
+        debugLog("All requested clients connected. Sign-in succeeded!");
+        setState(STATE_CONNECTED);
+        mSignInFailureReason = null;
+        mAutoSignIn = true;
+        mUserInitiatedSignIn = false;
+        notifyListener(true);
+    }
+
+    /** Handles a connection failure reported by a client. */
+    @Override
+    public void onConnectionFailed(ConnectionResult result) {
+        // save connection result for later reference
+        debugLog("onConnectionFailed");
+
+        mConnectionResult = result;
+        debugLog("Connection failure:");
+        debugLog("   - code: " +  errorCodeToString(mConnectionResult.getErrorCode()));
+        debugLog("   - resolvable: " + mConnectionResult.hasResolution());
+        debugLog("   - details: " + mConnectionResult.toString());
+
+        if (!mUserInitiatedSignIn) {
+            // If the user didn't initiate the sign-in, we don't try to resolve
+            // the connection problem automatically -- instead, we fail and wait
+            // for the user to want to sign in. That way, they won't get an
+            // authentication (or other) popup unless they are actively trying
+            // to
+            // sign in.
+            debugLog("onConnectionFailed: since user didn't initiate sign-in, failing now.");
+            mConnectionResult = result;
+            setState(STATE_DISCONNECTED);
+            notifyListener(false);
+            return;
+        }
+
+        debugLog("onConnectionFailed: since user initiated sign-in, resolving problem.");
+
+        // Resolve the connection result. This usually means showing a dialog or
+        // starting an Activity that will allow the user to give the appropriate
+        // consents so that sign-in can be successful.
+        resolveConnectionResult();
+    }
+
+    /**
+     * Attempts to resolve a connection failure. This will usually involve
+     * starting a UI flow that lets the user give the appropriate consents
+     * necessary for sign-in to work.
+     */
+    void resolveConnectionResult() {
+        // Try to resolve the problem
+        checkState(TYPE_GAMEHELPER_BUG, "resolveConnectionResult",
+                "resolveConnectionResult should only be called when connecting. Proceeding anyway.",
+                STATE_CONNECTING);
+
+        if (mExpectingResolution) {
+            debugLog("We're already expecting the result of a previous resolution.");
+            return;
+        }
+
+        debugLog("resolveConnectionResult: trying to resolve result: " + mConnectionResult);
+        if (mConnectionResult.hasResolution()) {
+            // This problem can be fixed. So let's try to fix it.
+            debugLog("Result has resolution. Starting it.");
+            try {
+                // launch appropriate UI flow (which might, for example, be the
+                // sign-in flow)
+                mExpectingResolution = true;
+                mConnectionResult.startResolutionForResult(mActivity, RC_RESOLVE);
+            } catch (SendIntentException e) {
+                // Try connecting again
+                debugLog("SendIntentException, so connecting again.");
+                connectCurrentClient();
+            }
+        } else {
+            // It's not a problem what we can solve, so give up and show an
+            // error.
+            debugLog("resolveConnectionResult: result has no resolution. Giving up.");
+            giveUp(new SignInFailureReason(mConnectionResult.getErrorCode()));
+        }
+    }
+
+    /**
+     * Give up on signing in due to an error. Shows the appropriate error
+     * message to the user, using a standard error dialog as appropriate to the
+     * cause of the error. That dialog will indicate to the user how the problem
+     * can be solved (for example, re-enable Google Play Services, upgrade to a
+     * new version, etc).
+     */
+    void giveUp(SignInFailureReason reason) {
+        checkState(TYPE_GAMEHELPER_BUG, "giveUp", "giveUp should only be called when " +
+                "connecting. Proceeding anyway.", STATE_CONNECTING);
+        mAutoSignIn = false;
+        killConnections();
+        mSignInFailureReason = reason;
+        showFailureDialog();
+        notifyListener(false);
+    }
+
+    /** Called when we are disconnected from a client. */
+    @Override
+    public void onDisconnected() {
+        debugLog("onDisconnected.");
+        if (mState == STATE_DISCONNECTED) {
+            // This is expected.
+            debugLog("onDisconnected is expected, so no action taken.");
+            return;
+        }
+
+        // Unexpected disconnect (rare!)
+        logWarn("Unexpectedly disconnected. Severing remaining connections.");
+
+        // kill the other connections too, and revert to DISCONNECTED state.
+        killConnections();
+        mSignInFailureReason = null;
+
+        // call the sign in failure callback
+        debugLog("Making extraordinary call to onSignInFailed callback");
+        notifyListener(false);
+    }
+
+    /** Shows an error dialog that's appropriate for the failure reason. */
+    void showFailureDialog() {
+        Context ctx = getContext();
+        if (ctx == null) {
+            debugLog("*** No context. Can't show failure dialog.");
+            return;
+        }
+        debugLog("Making error dialog for failure: " + mSignInFailureReason);
+        Dialog errorDialog = null;
+        int errorCode = mSignInFailureReason.getServiceErrorCode();
+        int actResp = mSignInFailureReason.getActivityResultCode();
+
+        switch (actResp) {
+            case GamesActivityResultCodes.RESULT_APP_MISCONFIGURED:
+                errorDialog = makeSimpleDialog(ctx.getString(
+                        R.string.gamehelper_app_misconfigured));
+                printMisconfiguredDebugInfo();
+                break;
+            case GamesActivityResultCodes.RESULT_SIGN_IN_FAILED:
+                errorDialog = makeSimpleDialog(ctx.getString(
+                        R.string.gamehelper_sign_in_failed));
+                break;
+            case GamesActivityResultCodes.RESULT_LICENSE_FAILED:
+                errorDialog = makeSimpleDialog(ctx.getString(
+                        R.string.gamehelper_license_failed));
+                break;
+            default:
+                // No meaningful Activity response code, so generate default Google
+                // Play services dialog
+                errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode, mActivity,
+                        RC_UNUSED, null);
+                if (errorDialog == null) {
+                    // get fallback dialog
+                    debugLog("No standard error dialog available. Making fallback dialog.");
+                    errorDialog = makeSimpleDialog(ctx.getString(R.string.gamehelper_unknown_error)
+                            + " " + errorCodeToString(errorCode));
+                }
+        }
+
+        debugLog("Showing error dialog.");
+        errorDialog.show();
+    }
+
+    Dialog makeSimpleDialog(String text) {
+        return (new AlertDialog.Builder(getContext())).setMessage(text)
+                .setNeutralButton(android.R.string.ok, null).create();
+    }
+
+    void debugLog(String message) {
+        if (mDebugLog) {
+            Log.d(mDebugTag, "GameHelper: " + message);
+        }
+    }
+
+    void logWarn(String message) {
+        Log.w(mDebugTag, "!!! GameHelper WARNING: " + message);
+    }
+
+    void logError(String message) {
+        Log.e(mDebugTag, "*** GameHelper ERROR: " + message);
+    }
+
+    static String errorCodeToString(int errorCode) {
+        switch (errorCode) {
+            case ConnectionResult.DEVELOPER_ERROR:
+                return "DEVELOPER_ERROR(" + errorCode + ")";
+            case ConnectionResult.INTERNAL_ERROR:
+                return "INTERNAL_ERROR(" + errorCode + ")";
+            case ConnectionResult.INVALID_ACCOUNT:
+                return "INVALID_ACCOUNT(" + errorCode + ")";
+            case ConnectionResult.LICENSE_CHECK_FAILED:
+                return "LICENSE_CHECK_FAILED(" + errorCode + ")";
+            case ConnectionResult.NETWORK_ERROR:
+                return "NETWORK_ERROR(" + errorCode + ")";
+            case ConnectionResult.RESOLUTION_REQUIRED:
+                return "RESOLUTION_REQUIRED(" + errorCode + ")";
+            case ConnectionResult.SERVICE_DISABLED:
+                return "SERVICE_DISABLED(" + errorCode + ")";
+            case ConnectionResult.SERVICE_INVALID:
+                return "SERVICE_INVALID(" + errorCode + ")";
+            case ConnectionResult.SERVICE_MISSING:
+                return "SERVICE_MISSING(" + errorCode + ")";
+            case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
+                return "SERVICE_VERSION_UPDATE_REQUIRED(" + errorCode + ")";
+            case ConnectionResult.SIGN_IN_REQUIRED:
+                return "SIGN_IN_REQUIRED(" + errorCode + ")";
+            case ConnectionResult.SUCCESS:
+                return "SUCCESS(" + errorCode + ")";
+            default:
+                return "Unknown error code " + errorCode;
+        }
+    }
+
+    // Represents the reason for a sign-in failure
+    public static class SignInFailureReason {
+        public static final int NO_ACTIVITY_RESULT_CODE = -100;
+        int mServiceErrorCode = 0;
+        int mActivityResultCode = NO_ACTIVITY_RESULT_CODE;
+        public int getServiceErrorCode() {
+            return mServiceErrorCode;
+        }
+        public int getActivityResultCode() {
+            return mActivityResultCode;
+        }
+        public SignInFailureReason(int serviceErrorCode, int activityResultCode) {
+            mServiceErrorCode = serviceErrorCode;
+            mActivityResultCode = activityResultCode;
+        }
+        public SignInFailureReason(int serviceErrorCode) {
+            this(serviceErrorCode, NO_ACTIVITY_RESULT_CODE);
+        }
+        @Override
+        public String toString() {
+            return "SignInFailureReason(serviceErrorCode:" +
+                    errorCodeToString(mServiceErrorCode) +
+                    ((mActivityResultCode == NO_ACTIVITY_RESULT_CODE) ? ")" :
+                    (",activityResultCode:" +
+                    activityResponseCodeToString(mActivityResultCode) + ")"));
+        }
+    }
+
+    void printMisconfiguredDebugInfo() {
+        debugLog("****");
+        debugLog("****");
+        debugLog("**** APP NOT CORRECTLY CONFIGURED TO USE GOOGLE PLAY GAME SERVICES");
+        debugLog("**** This is usually caused by one of these reasons:");
+        debugLog("**** (1) Your package name and certificate fingerprint do not match");
+        debugLog("****     the client ID you registered in Developer Console.");
+        debugLog("**** (2) Your App ID was incorrectly entered.");
+        debugLog("**** (3) Your game settings have not been published and you are ");
+        debugLog("****     trying to log in with an account that is not listed as");
+        debugLog("****     a test account.");
+        debugLog("****");
+        Context ctx = getContext();
+        if (ctx == null) {
+            debugLog("*** (no Context, so can't print more debug info)");
+            return;
+        }
+
+        debugLog("**** To help you debug, here is the information about this app");
+        debugLog("**** Package name         : " + getContext().getPackageName());
+        debugLog("**** Cert SHA1 fingerprint: " + getSHA1CertFingerprint());
+        debugLog("**** App ID from          : " + getAppIdFromResource());
+        debugLog("****");
+        debugLog("**** Check that the above information matches your setup in ");
+        debugLog("**** Developer Console. Also, check that you're logging in with the");
+        debugLog("**** right account (it should be listed in the Testers section if");
+        debugLog("**** your project is not yet published).");
+        debugLog("****");
+        debugLog("**** For more information, refer to the troubleshooting guide:");
+        debugLog("****   http://developers.google.com/games/services/android/troubleshooting");
+    }
+
+    String getAppIdFromResource() {
+        try {
+            Resources res = getContext().getResources();
+            String pkgName = getContext().getPackageName();
+            int res_id = res.getIdentifier("app_id", "string", pkgName);
+            return res.getString(res_id);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            return "??? (failed to retrieve APP ID)";
+        }
+    }
+
+    String getSHA1CertFingerprint() {
+        try {
+            Signature[] sigs = getContext().getPackageManager().getPackageInfo(
+                    getContext().getPackageName(), PackageManager.GET_SIGNATURES).signatures;
+            if (sigs.length == 0) {
+                return "ERROR: NO SIGNATURE.";
+            } else if (sigs.length > 1) {
+                return "ERROR: MULTIPLE SIGNATURES";
+            }
+            byte[] digest = MessageDigest.getInstance("SHA1").digest(sigs[0].toByteArray());
+            StringBuilder hexString = new StringBuilder();
+            for (int i = 0; i < digest.length; ++i) {
+                if (i > 0) {
+                    hexString.append(":");
+                }
+                byteToString(hexString, digest[i]);
+            }
+            return hexString.toString();
+
+        } catch (PackageManager.NameNotFoundException ex) {
+            ex.printStackTrace();
+            return "(ERROR: package not found)";
+        } catch (NoSuchAlgorithmException ex) {
+            ex.printStackTrace();
+            return "(ERROR: SHA1 algorithm not found)";
+        }
+    }
+
+    void byteToString(StringBuilder sb, byte b) {
+        int unsigned_byte = b < 0 ? b + 256 : b;
+        int hi = unsigned_byte / 16;
+        int lo = unsigned_byte % 16;
+        sb.append("0123456789ABCDEF".substring(hi, hi + 1));
+        sb.append("0123456789ABCDEF".substring(lo, lo + 1));
+    }
+
+}

+ 118 - 0
gameplay/android/java/src/org/gameplay3d/lib/GoogleGamesSocial.java

@@ -0,0 +1,118 @@
+    
+package org.gameplay3d.lib;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.google.android.gms.games.Player;
+import com.google.example.games.basegameutils.BaseGameActivity;
+
+public class GoogleGamesSocial extends BaseGameActivity {
+	
+	private static List<Player> mFriends = new ArrayList<Player>();
+    private static final int FRIENDS_PER_PAGE = 10;
+	
+	public static void gameServicesSignIn() 
+	{
+        ((appname)mContext).runOnUiThread(new Runnable() 
+		{
+            public void run() {
+                ((appname)mContext).beginUserInitiatedSignIn();
+            }
+        });
+    }
+
+    public static void updateTopScoreLeaderboard(int score) 
+	{
+		if (mContext.isSignedIn())
+			mContext.getGamesClient().submitScore("leaderboardid", score);
+    }
+
+	public static void submitAchievement(String achievementId)
+	{
+        if (mContext.isSignedIn())
+		{
+            mContext.getGamesClient().unlockAchievement(achievementId);
+        }
+    }
+	
+	public static void incrementAchievement(String achievementId, int percentage)
+	{
+        if (mContext.isSignedIn())
+		{
+            mContext.getGamesClient().incrementAchievement(achievementId, percentage);
+        }
+    }
+
+    public static void displayLeaderboards() 
+	{
+		if (mContext.isSignedIn())
+		{
+			((appname)mContext).runOnUiThread(new Runnable() 
+			{
+				public void run() {
+					((appname)mContext).startActivityForResult(((appname)mContext).getGamesClient().getLeaderboardIntent("leaderboardidfromgoogleplay"), 5001);
+				}
+			});
+		}
+		else
+		{
+			gameServicesSignIn();
+		}
+    }
+
+    public static void displayAchievements() 
+	{
+		if (mContext.isSignedIn())
+		{
+			((appname)mContext).runOnUiThread(new Runnable() 
+			{
+				public void run() {
+					((appname)mContext).startActivityForResult(((appname)mContext).getGamesClient().getAchievementsIntent(), 5001);
+				}
+			});
+		}
+		else
+		{
+			gameServicesSignIn();
+		}
+    }
+
+    public static void loadFriends() 
+	{
+        if (mFriends.size() > 0) {
+            mFriends.clear();
+        }
+
+        ((appname)mContext).runOnUiThread(new Runnable() 
+		{
+                public void run() 
+				{        
+            ((appname)mContext).getGamesClient().loadInvitablePlayers(new OnPlayersLoadedListener() {
+
+                @Override
+                public void onPlayersLoaded(int statusCode, PlayerBuffer playerBuffer) {
+
+                    if (statusCode == GamesClient.STATUS_OK) {
+                        for (Player player : playerBuffer) {
+                            mFriends.add(player);
+                        }
+
+                        if (playerBuffer.getCount() == FRIENDS_PER_PAGE) {
+                            ((appname)mContext).getGamesClient().loadMoreInvitablePlayers(this, FRIENDS_PER_PAGE);
+                        } else {
+                            // call out and return all the friends <more code to call into C++>
+
+                            for (Player friend : mFriends) {
+                                Log.i(TAG, String.format("Found player with id [%s] and display name [%s]", friend.getPlayerId(), friend.getDisplayName()));
+                            }
+                        }
+                    }
+                }
+            }, FRIENDS_PER_PAGE, false);
+        });
+    }
+}

+ 12 - 0
gameplay/android/java/src/org/gameplay3d/lib/TestClass.java

@@ -0,0 +1,12 @@
+
+package org.gameplay3d.lib;
+
+public class TestClass
+{
+   public TestClass() { }
+ 
+   public int ComputeMult(float a, float b)
+   {
+      return (int)(a * b);
+   }
+}

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

@@ -91,6 +91,12 @@ LOCAL_SRC_FILES := \
     ScriptController.cpp \
     ScriptController.cpp \
     ScriptTarget.cpp \
     ScriptTarget.cpp \
     Slider.cpp \
     Slider.cpp \
+	SocialAchievement.cpp \
+	SocialChallenge.cpp \
+	SocialController.cpp \
+	SocialPlayer.cpp \
+	SocialScore.cpp \
+	SocialSessionListener.cpp \
     SpriteBatch.cpp \
     SpriteBatch.cpp \
     Technique.cpp \
     Technique.cpp \
     Terrain.cpp \
     Terrain.cpp \
@@ -106,6 +112,7 @@ LOCAL_SRC_FILES := \
     VertexAttributeBinding.cpp \
     VertexAttributeBinding.cpp \
     VertexFormat.cpp \
     VertexFormat.cpp \
     VerticalLayout.cpp \
     VerticalLayout.cpp \
+	social/GoogleGamesSocialSession.cpp \
     lua/lua_AbsoluteLayout.cpp \
     lua/lua_AbsoluteLayout.cpp \
     lua/lua_AIAgent.cpp \
     lua/lua_AIAgent.cpp \
     lua/lua_AIAgentListener.cpp \
     lua/lua_AIAgentListener.cpp \
@@ -281,7 +288,7 @@ LOCAL_SRC_FILES := \
     lua/lua_VerticalLayout.cpp
     lua/lua_VerticalLayout.cpp
 
 
     
     
-LOCAL_CFLAGS := -D__ANDROID__ -I"../../external-deps/lua/include" -I"../../external-deps/bullet/include" -I"../../external-deps/libpng/include" -I"../../external-deps/oggvorbis/include" -I"../../external-deps/openal/include"
+LOCAL_CFLAGS := -D__ANDROID__ -DGP_USE_SOCIAL -I"../../external-deps/lua/include" -I"../../external-deps/bullet/include" -I"../../external-deps/png/include" -I"../../external-deps/oggvorbis/include" -I"../../external-deps/openal/include"
 LOCAL_STATIC_LIBRARIES := android_native_app_glue
 LOCAL_STATIC_LIBRARIES := android_native_app_glue
 
 
 include $(BUILD_STATIC_LIBRARY)
 include $(BUILD_STATIC_LIBRARY)

+ 32 - 13
gameplay/gameplay.vcxproj

@@ -131,6 +131,7 @@
     <ClCompile Include="src\lua\lua_ContainerScroll.cpp" />
     <ClCompile Include="src\lua\lua_ContainerScroll.cpp" />
     <ClCompile Include="src\lua\lua_Control.cpp" />
     <ClCompile Include="src\lua\lua_Control.cpp" />
     <ClCompile Include="src\lua\lua_ControlAlignment.cpp" />
     <ClCompile Include="src\lua\lua_ControlAlignment.cpp" />
+    <ClCompile Include="src\lua\lua_ControlAutoSize.cpp" />
     <ClCompile Include="src\lua\lua_ControlListener.cpp" />
     <ClCompile Include="src\lua\lua_ControlListener.cpp" />
     <ClCompile Include="src\lua\lua_ControlListenerEventType.cpp" />
     <ClCompile Include="src\lua\lua_ControlListenerEventType.cpp" />
     <ClCompile Include="src\lua\lua_ControlState.cpp" />
     <ClCompile Include="src\lua\lua_ControlState.cpp" />
@@ -142,6 +143,7 @@
     <ClCompile Include="src\lua\lua_FileSystem.cpp" />
     <ClCompile Include="src\lua\lua_FileSystem.cpp" />
     <ClCompile Include="src\lua\lua_FlowLayout.cpp" />
     <ClCompile Include="src\lua\lua_FlowLayout.cpp" />
     <ClCompile Include="src\lua\lua_Font.cpp" />
     <ClCompile Include="src\lua\lua_Font.cpp" />
+    <ClCompile Include="src\lua\lua_FontFormat.cpp" />
     <ClCompile Include="src\lua\lua_FontJustify.cpp" />
     <ClCompile Include="src\lua\lua_FontJustify.cpp" />
     <ClCompile Include="src\lua\lua_FontStyle.cpp" />
     <ClCompile Include="src\lua\lua_FontStyle.cpp" />
     <ClCompile Include="src\lua\lua_FontText.cpp" />
     <ClCompile Include="src\lua\lua_FontText.cpp" />
@@ -231,6 +233,7 @@
     <ClCompile Include="src\lua\lua_RenderStateBlend.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateBlend.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateCullFaceSide.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateCullFaceSide.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateDepthFunction.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateDepthFunction.cpp" />
+    <ClCompile Include="src\lua\lua_RenderStateFrontFace.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateStateBlock.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateStateBlock.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateStencilFunction.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateStencilFunction.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateStencilOperation.cpp" />
     <ClCompile Include="src\lua\lua_RenderStateStencilOperation.cpp" />
@@ -318,7 +321,13 @@
     <ClCompile Include="src\ScriptController.cpp" />
     <ClCompile Include="src\ScriptController.cpp" />
     <ClCompile Include="src\ScriptTarget.cpp" />
     <ClCompile Include="src\ScriptTarget.cpp" />
     <ClCompile Include="src\Slider.cpp" />
     <ClCompile Include="src\Slider.cpp" />
+    <ClCompile Include="src\SocialAchievement.cpp" />
+    <ClCompile Include="src\SocialChallenge.cpp" />
     <ClCompile Include="src\SocialController.cpp" />
     <ClCompile Include="src\SocialController.cpp" />
+    <ClCompile Include="src\SocialPlayer.cpp" />
+    <ClCompile Include="src\SocialScore.cpp" />
+    <ClCompile Include="src\SocialSessionListener.cpp" />
+    <ClCompile Include="src\social\GoogleGamesSocialSession.cpp" />
     <ClCompile Include="src\social\ScoreloopSocialSession.cpp" />
     <ClCompile Include="src\social\ScoreloopSocialSession.cpp" />
     <ClCompile Include="src\SpriteBatch.cpp" />
     <ClCompile Include="src\SpriteBatch.cpp" />
     <ClCompile Include="src\Technique.cpp" />
     <ClCompile Include="src\Technique.cpp" />
@@ -417,6 +426,7 @@
     <ClInclude Include="src\lua\lua_ContainerScroll.h" />
     <ClInclude Include="src\lua\lua_ContainerScroll.h" />
     <ClInclude Include="src\lua\lua_Control.h" />
     <ClInclude Include="src\lua\lua_Control.h" />
     <ClInclude Include="src\lua\lua_ControlAlignment.h" />
     <ClInclude Include="src\lua\lua_ControlAlignment.h" />
+    <ClInclude Include="src\lua\lua_ControlAutoSize.h" />
     <ClInclude Include="src\lua\lua_ControlListener.h" />
     <ClInclude Include="src\lua\lua_ControlListener.h" />
     <ClInclude Include="src\lua\lua_ControlListenerEventType.h" />
     <ClInclude Include="src\lua\lua_ControlListenerEventType.h" />
     <ClInclude Include="src\lua\lua_ControlState.h" />
     <ClInclude Include="src\lua\lua_ControlState.h" />
@@ -428,6 +438,7 @@
     <ClInclude Include="src\lua\lua_FileSystem.h" />
     <ClInclude Include="src\lua\lua_FileSystem.h" />
     <ClInclude Include="src\lua\lua_FlowLayout.h" />
     <ClInclude Include="src\lua\lua_FlowLayout.h" />
     <ClInclude Include="src\lua\lua_Font.h" />
     <ClInclude Include="src\lua\lua_Font.h" />
+    <ClInclude Include="src\lua\lua_FontFormat.h" />
     <ClInclude Include="src\lua\lua_FontJustify.h" />
     <ClInclude Include="src\lua\lua_FontJustify.h" />
     <ClInclude Include="src\lua\lua_FontStyle.h" />
     <ClInclude Include="src\lua\lua_FontStyle.h" />
     <ClInclude Include="src\lua\lua_FontText.h" />
     <ClInclude Include="src\lua\lua_FontText.h" />
@@ -517,6 +528,7 @@
     <ClInclude Include="src\lua\lua_RenderStateBlend.h" />
     <ClInclude Include="src\lua\lua_RenderStateBlend.h" />
     <ClInclude Include="src\lua\lua_RenderStateCullFaceSide.h" />
     <ClInclude Include="src\lua\lua_RenderStateCullFaceSide.h" />
     <ClInclude Include="src\lua\lua_RenderStateDepthFunction.h" />
     <ClInclude Include="src\lua\lua_RenderStateDepthFunction.h" />
+    <ClInclude Include="src\lua\lua_RenderStateFrontFace.h" />
     <ClInclude Include="src\lua\lua_RenderStateStateBlock.h" />
     <ClInclude Include="src\lua\lua_RenderStateStateBlock.h" />
     <ClInclude Include="src\lua\lua_RenderStateStencilFunction.h" />
     <ClInclude Include="src\lua\lua_RenderStateStencilFunction.h" />
     <ClInclude Include="src\lua\lua_RenderStateStencilOperation.h" />
     <ClInclude Include="src\lua\lua_RenderStateStencilOperation.h" />
@@ -602,12 +614,13 @@
     <ClInclude Include="src\ScriptTarget.h" />
     <ClInclude Include="src\ScriptTarget.h" />
     <ClInclude Include="src\Slider.h" />
     <ClInclude Include="src\Slider.h" />
     <ClInclude Include="src\SocialAchievement.h" />
     <ClInclude Include="src\SocialAchievement.h" />
+    <ClInclude Include="src\SocialChallenge.h" />
     <ClInclude Include="src\SocialController.h" />
     <ClInclude Include="src\SocialController.h" />
-    <ClInclude Include="src\SocialLeaderboard.h" />
     <ClInclude Include="src\SocialPlayer.h" />
     <ClInclude Include="src\SocialPlayer.h" />
     <ClInclude Include="src\SocialScore.h" />
     <ClInclude Include="src\SocialScore.h" />
     <ClInclude Include="src\SocialSession.h" />
     <ClInclude Include="src\SocialSession.h" />
     <ClInclude Include="src\SocialSessionListener.h" />
     <ClInclude Include="src\SocialSessionListener.h" />
+    <ClInclude Include="src\social\GoogleGamesSocialSession.h" />
     <ClInclude Include="src\social\ScoreloopSocialSession.h" />
     <ClInclude Include="src\social\ScoreloopSocialSession.h" />
     <ClInclude Include="src\SpriteBatch.h" />
     <ClInclude Include="src\SpriteBatch.h" />
     <ClInclude Include="src\Stream.h" />
     <ClInclude Include="src\Stream.h" />
@@ -885,10 +898,12 @@
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>
       <RuntimeTypeInfo>
       </RuntimeTypeInfo>
       </RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <DisableSpecificWarnings>
+      </DisableSpecificWarnings>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
       <SubSystem>Windows</SubSystem>
       <SubSystem>Windows</SubSystem>
@@ -905,7 +920,7 @@
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>
       <RuntimeTypeInfo>
       </RuntimeTypeInfo>
       </RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -925,7 +940,7 @@
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_SOCIAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_SOCIAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>
       <RuntimeTypeInfo>
       </RuntimeTypeInfo>
       </RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -943,7 +958,7 @@
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>
       <RuntimeTypeInfo>
       </RuntimeTypeInfo>
       </RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
@@ -960,9 +975,11 @@
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <DisableSpecificWarnings>
+      </DisableSpecificWarnings>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
       <SubSystem>Windows</SubSystem>
       <SubSystem>Windows</SubSystem>
@@ -984,7 +1001,7 @@
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
     </ClCompile>
     </ClCompile>
@@ -1004,7 +1021,7 @@
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_MEM_LEAK_DETECTION;GP_USE_SOCIAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_MEM_LEAK_DETECTION;GP_USE_SOCIAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
@@ -1025,7 +1042,7 @@
       <WarningLevel>Level3</WarningLevel>
       <WarningLevel>Level3</WarningLevel>
       <Optimization>Disabled</Optimization>
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GP_USE_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeTypeInfo>true</RuntimeTypeInfo>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
     </ClCompile>
     </ClCompile>
@@ -1047,9 +1064,11 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DebugInformationFormat>
       <DebugInformationFormat>
       </DebugInformationFormat>
       </DebugInformationFormat>
+      <DisableSpecificWarnings>
+      </DisableSpecificWarnings>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
       <SubSystem>Windows</SubSystem>
       <SubSystem>Windows</SubSystem>
@@ -1067,7 +1086,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DebugInformationFormat>
       <DebugInformationFormat>
       </DebugInformationFormat>
       </DebugInformationFormat>
     </ClCompile>
     </ClCompile>
@@ -1087,7 +1106,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;GP_USE_SOCIAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;GP_USE_SOCIAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
       <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
@@ -1106,7 +1125,7 @@
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <FunctionLevelLinking>true</FunctionLevelLinking>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;GP_USE_SOCIAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;GP_USE_SOCIAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\png\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
       <SubSystem>Windows</SubSystem>
       <SubSystem>Windows</SubSystem>

+ 42 - 3
gameplay/gameplay.vcxproj.filters

@@ -870,6 +870,33 @@
     <ClCompile Include="src\social\ScoreloopSocialSession.cpp">
     <ClCompile Include="src\social\ScoreloopSocialSession.cpp">
       <Filter>src\social</Filter>
       <Filter>src\social</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="src\social\GoogleGamesSocialSession.cpp">
+      <Filter>src\social</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SocialAchievement.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SocialPlayer.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SocialScore.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SocialChallenge.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\SocialSessionListener.cpp">
+      <Filter>src</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_ControlAutoSize.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_FontFormat.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
+    <ClCompile Include="src\lua\lua_RenderStateFrontFace.cpp">
+      <Filter>src\lua</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\Animation.h">
     <ClInclude Include="src\Animation.h">
@@ -1727,9 +1754,6 @@
     <ClInclude Include="src\SocialAchievement.h">
     <ClInclude Include="src\SocialAchievement.h">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="src\SocialLeaderboard.h">
-      <Filter>src</Filter>
-    </ClInclude>
     <ClInclude Include="src\SocialPlayer.h">
     <ClInclude Include="src\SocialPlayer.h">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClInclude>
     </ClInclude>
@@ -1742,6 +1766,21 @@
     <ClInclude Include="src\social\ScoreloopSocialSession.h">
     <ClInclude Include="src\social\ScoreloopSocialSession.h">
       <Filter>src\social</Filter>
       <Filter>src\social</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="src\social\GoogleGamesSocialSession.h">
+      <Filter>src\social</Filter>
+    </ClInclude>
+    <ClInclude Include="src\SocialChallenge.h">
+      <Filter>src</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_ControlAutoSize.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_FontFormat.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
+    <ClInclude Include="src\lua\lua_RenderStateFrontFace.h">
+      <Filter>src\lua</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <None Include="src\Game.inl">
     <None Include="src\Game.inl">

+ 132 - 42
gameplay/gameplay.xcodeproj/project.pbxproj

@@ -54,6 +54,32 @@
 		42554EA2152BC35C000ED910 /* PhysicsCollisionShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42554E9F152BC35C000ED910 /* PhysicsCollisionShape.cpp */; };
 		42554EA2152BC35C000ED910 /* PhysicsCollisionShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42554E9F152BC35C000ED910 /* PhysicsCollisionShape.cpp */; };
 		42554EA3152BC35C000ED910 /* PhysicsCollisionShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 42554EA0152BC35C000ED910 /* PhysicsCollisionShape.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		42554EA3152BC35C000ED910 /* PhysicsCollisionShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 42554EA0152BC35C000ED910 /* PhysicsCollisionShape.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		42554EA4152BC35C000ED910 /* PhysicsCollisionShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 42554EA0152BC35C000ED910 /* PhysicsCollisionShape.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		42554EA4152BC35C000ED910 /* PhysicsCollisionShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 42554EA0152BC35C000ED910 /* PhysicsCollisionShape.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		425EDA5D17FB260500AABF95 /* SocialAchievement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5017FB260500AABF95 /* SocialAchievement.cpp */; };
+		425EDA5E17FB260500AABF95 /* SocialAchievement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5017FB260500AABF95 /* SocialAchievement.cpp */; };
+		425EDA5F17FB260500AABF95 /* SocialAchievement.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5117FB260500AABF95 /* SocialAchievement.h */; };
+		425EDA6017FB260500AABF95 /* SocialAchievement.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5117FB260500AABF95 /* SocialAchievement.h */; };
+		425EDA6117FB260500AABF95 /* SocialChallenge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5217FB260500AABF95 /* SocialChallenge.cpp */; };
+		425EDA6217FB260500AABF95 /* SocialChallenge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5217FB260500AABF95 /* SocialChallenge.cpp */; };
+		425EDA6317FB260500AABF95 /* SocialChallenge.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5317FB260500AABF95 /* SocialChallenge.h */; };
+		425EDA6417FB260500AABF95 /* SocialChallenge.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5317FB260500AABF95 /* SocialChallenge.h */; };
+		425EDA6517FB260500AABF95 /* SocialController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5417FB260500AABF95 /* SocialController.cpp */; };
+		425EDA6617FB260500AABF95 /* SocialController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5417FB260500AABF95 /* SocialController.cpp */; };
+		425EDA6717FB260500AABF95 /* SocialController.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5517FB260500AABF95 /* SocialController.h */; };
+		425EDA6817FB260500AABF95 /* SocialController.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5517FB260500AABF95 /* SocialController.h */; };
+		425EDA6917FB260500AABF95 /* SocialPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5617FB260500AABF95 /* SocialPlayer.cpp */; };
+		425EDA6A17FB260500AABF95 /* SocialPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5617FB260500AABF95 /* SocialPlayer.cpp */; };
+		425EDA6B17FB260500AABF95 /* SocialPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5717FB260500AABF95 /* SocialPlayer.h */; };
+		425EDA6C17FB260500AABF95 /* SocialPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5717FB260500AABF95 /* SocialPlayer.h */; };
+		425EDA6D17FB260500AABF95 /* SocialScore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5817FB260500AABF95 /* SocialScore.cpp */; };
+		425EDA6E17FB260500AABF95 /* SocialScore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5817FB260500AABF95 /* SocialScore.cpp */; };
+		425EDA6F17FB260500AABF95 /* SocialScore.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5917FB260500AABF95 /* SocialScore.h */; };
+		425EDA7017FB260500AABF95 /* SocialScore.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5917FB260500AABF95 /* SocialScore.h */; };
+		425EDA7117FB260500AABF95 /* SocialSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5A17FB260500AABF95 /* SocialSession.h */; };
+		425EDA7217FB260500AABF95 /* SocialSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5A17FB260500AABF95 /* SocialSession.h */; };
+		425EDA7317FB260500AABF95 /* SocialSessionListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5B17FB260500AABF95 /* SocialSessionListener.cpp */; };
+		425EDA7417FB260500AABF95 /* SocialSessionListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425EDA5B17FB260500AABF95 /* SocialSessionListener.cpp */; };
+		425EDA7517FB260500AABF95 /* SocialSessionListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5C17FB260500AABF95 /* SocialSessionListener.h */; };
+		425EDA7617FB260500AABF95 /* SocialSessionListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 425EDA5C17FB260500AABF95 /* SocialSessionListener.h */; };
 		426878AC153F4BB300844500 /* FlowLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 426878AA153F4BB300844500 /* FlowLayout.cpp */; };
 		426878AC153F4BB300844500 /* FlowLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 426878AA153F4BB300844500 /* FlowLayout.cpp */; };
 		426878AD153F4BB300844500 /* FlowLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 426878AA153F4BB300844500 /* FlowLayout.cpp */; };
 		426878AD153F4BB300844500 /* FlowLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 426878AA153F4BB300844500 /* FlowLayout.cpp */; };
 		426878AE153F4BB300844500 /* FlowLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 426878AB153F4BB300844500 /* FlowLayout.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		426878AE153F4BB300844500 /* FlowLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 426878AB153F4BB300844500 /* FlowLayout.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1215,6 +1241,19 @@
 		4251B130152D049B002F6199 /* ThemeStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThemeStyle.h; path = src/ThemeStyle.h; sourceTree = SOURCE_ROOT; };
 		4251B130152D049B002F6199 /* ThemeStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThemeStyle.h; path = src/ThemeStyle.h; sourceTree = SOURCE_ROOT; };
 		42554E9F152BC35C000ED910 /* PhysicsCollisionShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsCollisionShape.cpp; path = src/PhysicsCollisionShape.cpp; sourceTree = SOURCE_ROOT; };
 		42554E9F152BC35C000ED910 /* PhysicsCollisionShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PhysicsCollisionShape.cpp; path = src/PhysicsCollisionShape.cpp; sourceTree = SOURCE_ROOT; };
 		42554EA0152BC35C000ED910 /* PhysicsCollisionShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsCollisionShape.h; path = src/PhysicsCollisionShape.h; sourceTree = SOURCE_ROOT; };
 		42554EA0152BC35C000ED910 /* PhysicsCollisionShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PhysicsCollisionShape.h; path = src/PhysicsCollisionShape.h; sourceTree = SOURCE_ROOT; };
+		425EDA5017FB260500AABF95 /* SocialAchievement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocialAchievement.cpp; path = src/SocialAchievement.cpp; sourceTree = SOURCE_ROOT; };
+		425EDA5117FB260500AABF95 /* SocialAchievement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SocialAchievement.h; path = src/SocialAchievement.h; sourceTree = SOURCE_ROOT; };
+		425EDA5217FB260500AABF95 /* SocialChallenge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocialChallenge.cpp; path = src/SocialChallenge.cpp; sourceTree = SOURCE_ROOT; };
+		425EDA5317FB260500AABF95 /* SocialChallenge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SocialChallenge.h; path = src/SocialChallenge.h; sourceTree = SOURCE_ROOT; };
+		425EDA5417FB260500AABF95 /* SocialController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocialController.cpp; path = src/SocialController.cpp; sourceTree = SOURCE_ROOT; };
+		425EDA5517FB260500AABF95 /* SocialController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SocialController.h; path = src/SocialController.h; sourceTree = SOURCE_ROOT; };
+		425EDA5617FB260500AABF95 /* SocialPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocialPlayer.cpp; path = src/SocialPlayer.cpp; sourceTree = SOURCE_ROOT; };
+		425EDA5717FB260500AABF95 /* SocialPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SocialPlayer.h; path = src/SocialPlayer.h; sourceTree = SOURCE_ROOT; };
+		425EDA5817FB260500AABF95 /* SocialScore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocialScore.cpp; path = src/SocialScore.cpp; sourceTree = SOURCE_ROOT; };
+		425EDA5917FB260500AABF95 /* SocialScore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SocialScore.h; path = src/SocialScore.h; sourceTree = SOURCE_ROOT; };
+		425EDA5A17FB260500AABF95 /* SocialSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SocialSession.h; path = src/SocialSession.h; sourceTree = SOURCE_ROOT; };
+		425EDA5B17FB260500AABF95 /* SocialSessionListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SocialSessionListener.cpp; path = src/SocialSessionListener.cpp; sourceTree = SOURCE_ROOT; };
+		425EDA5C17FB260500AABF95 /* SocialSessionListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SocialSessionListener.h; path = src/SocialSessionListener.h; sourceTree = SOURCE_ROOT; };
 		426878AA153F4BB300844500 /* FlowLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FlowLayout.cpp; path = src/FlowLayout.cpp; sourceTree = SOURCE_ROOT; };
 		426878AA153F4BB300844500 /* FlowLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FlowLayout.cpp; path = src/FlowLayout.cpp; sourceTree = SOURCE_ROOT; };
 		426878AB153F4BB300844500 /* FlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FlowLayout.h; path = src/FlowLayout.h; sourceTree = SOURCE_ROOT; };
 		426878AB153F4BB300844500 /* FlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FlowLayout.h; path = src/FlowLayout.h; sourceTree = SOURCE_ROOT; };
 		4271C08D15337C8200B89DA7 /* Layout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Layout.cpp; path = src/Layout.cpp; sourceTree = SOURCE_ROOT; };
 		4271C08D15337C8200B89DA7 /* Layout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Layout.cpp; path = src/Layout.cpp; sourceTree = SOURCE_ROOT; };
@@ -1237,7 +1276,7 @@
 		42A5031B16E8F0B800F0246C /* lua_TerrainListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_TerrainListener.cpp; sourceTree = "<group>"; };
 		42A5031B16E8F0B800F0246C /* lua_TerrainListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_TerrainListener.cpp; sourceTree = "<group>"; };
 		42A5031C16E8F0B800F0246C /* lua_TerrainListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_TerrainListener.h; sourceTree = "<group>"; };
 		42A5031C16E8F0B800F0246C /* lua_TerrainListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_TerrainListener.h; sourceTree = "<group>"; };
 		42B701F615B08177002BB8C3 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "../external-deps/lua/lib/macosx/liblua.a"; sourceTree = "<group>"; };
 		42B701F615B08177002BB8C3 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "../external-deps/lua/lib/macosx/liblua.a"; sourceTree = "<group>"; };
-		42B701F815B081B6002BB8C3 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "../external-deps/lua/lib/ios/armv7/liblua.a"; sourceTree = "<group>"; };
+		42B701F815B081B6002BB8C3 /* liblua.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua.a; path = "../external-deps/lua/lib/ios/armv7s/liblua.a"; sourceTree = "<group>"; };
 		42B7FADD15B08049002BB8C3 /* ScreenDisplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScreenDisplayer.cpp; path = src/ScreenDisplayer.cpp; sourceTree = SOURCE_ROOT; };
 		42B7FADD15B08049002BB8C3 /* ScreenDisplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScreenDisplayer.cpp; path = src/ScreenDisplayer.cpp; sourceTree = SOURCE_ROOT; };
 		42B7FADE15B08049002BB8C3 /* ScriptController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptController.cpp; path = src/ScriptController.cpp; sourceTree = SOURCE_ROOT; };
 		42B7FADE15B08049002BB8C3 /* ScriptController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptController.cpp; path = src/ScriptController.cpp; sourceTree = SOURCE_ROOT; };
 		42B7FADF15B08049002BB8C3 /* ScriptController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptController.h; path = src/ScriptController.h; sourceTree = SOURCE_ROOT; };
 		42B7FADF15B08049002BB8C3 /* ScriptController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptController.h; path = src/ScriptController.h; sourceTree = SOURCE_ROOT; };
@@ -1556,12 +1595,10 @@
 		42BCD45715EFD0F300C0E076 /* lua_VerticalLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_VerticalLayout.cpp; sourceTree = "<group>"; };
 		42BCD45715EFD0F300C0E076 /* lua_VerticalLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_VerticalLayout.cpp; sourceTree = "<group>"; };
 		42BCD45815EFD0F300C0E076 /* lua_VerticalLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_VerticalLayout.h; sourceTree = "<group>"; };
 		42BCD45815EFD0F300C0E076 /* lua_VerticalLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_VerticalLayout.h; sourceTree = "<group>"; };
 		42C932AF14919FD10098216A /* Game.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Game.inl; path = src/Game.inl; sourceTree = SOURCE_ROOT; };
 		42C932AF14919FD10098216A /* Game.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Game.inl; path = src/Game.inl; sourceTree = SOURCE_ROOT; };
-		42CCD555146EC1EB00353661 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "../external-deps/libpng/lib/macosx/libpng.a"; sourceTree = "<group>"; };
+		42CCD555146EC1EB00353661 /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "../external-deps/png/lib/macosx/libpng.a"; sourceTree = "<group>"; };
 		42CD0DA6147D8EA80000361E /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "../external-deps/bullet/lib/macosx/libbullet.a"; sourceTree = "<group>"; };
 		42CD0DA6147D8EA80000361E /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "../external-deps/bullet/lib/macosx/libbullet.a"; sourceTree = "<group>"; };
 		42CD0DA7147D8EA80000361E /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "../external-deps/oggvorbis/lib/macosx/libogg.a"; sourceTree = "<group>"; };
 		42CD0DA7147D8EA80000361E /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "../external-deps/oggvorbis/lib/macosx/libogg.a"; sourceTree = "<group>"; };
 		42CD0DA8147D8EA80000361E /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "../external-deps/oggvorbis/lib/macosx/libvorbis.a"; sourceTree = "<group>"; };
 		42CD0DA8147D8EA80000361E /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "../external-deps/oggvorbis/lib/macosx/libvorbis.a"; sourceTree = "<group>"; };
-		42CD0DA9147D8EA80000361E /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "../external-deps/oggvorbis/lib/macosx/libvorbisenc.a"; sourceTree = "<group>"; };
-		42CD0DAA147D8EA80000361E /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "../external-deps/oggvorbis/lib/macosx/libvorbisfile.a"; sourceTree = "<group>"; };
 		42CD0DB1147D8FF50000361E /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Animation.cpp; path = src/Animation.cpp; sourceTree = SOURCE_ROOT; };
 		42CD0DB1147D8FF50000361E /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Animation.cpp; path = src/Animation.cpp; sourceTree = SOURCE_ROOT; };
 		42CD0DB2147D8FF50000361E /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animation.h; path = src/Animation.h; sourceTree = SOURCE_ROOT; };
 		42CD0DB2147D8FF50000361E /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Animation.h; path = src/Animation.h; sourceTree = SOURCE_ROOT; };
 		42CD0DB3147D8FF50000361E /* AnimationClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationClip.cpp; path = src/AnimationClip.cpp; sourceTree = SOURCE_ROOT; };
 		42CD0DB3147D8FF50000361E /* AnimationClip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnimationClip.cpp; path = src/AnimationClip.cpp; sourceTree = SOURCE_ROOT; };
@@ -1698,7 +1735,7 @@
 		42CD0E41147D8FF50000361E /* VertexAttributeBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexAttributeBinding.h; path = src/VertexAttributeBinding.h; sourceTree = SOURCE_ROOT; };
 		42CD0E41147D8FF50000361E /* VertexAttributeBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexAttributeBinding.h; path = src/VertexAttributeBinding.h; sourceTree = SOURCE_ROOT; };
 		42CD0E42147D8FF50000361E /* VertexFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VertexFormat.cpp; path = src/VertexFormat.cpp; sourceTree = SOURCE_ROOT; };
 		42CD0E42147D8FF50000361E /* VertexFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VertexFormat.cpp; path = src/VertexFormat.cpp; sourceTree = SOURCE_ROOT; };
 		42CD0E43147D8FF50000361E /* VertexFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexFormat.h; path = src/VertexFormat.h; sourceTree = SOURCE_ROOT; };
 		42CD0E43147D8FF50000361E /* VertexFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VertexFormat.h; path = src/VertexFormat.h; sourceTree = SOURCE_ROOT; };
-		42DFAB4F16AD8ECD0000F342 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
+		42DFAB4F16AD8ECD0000F342 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; };
 		42F4B7D515994CED00B5A78D /* Gamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gamepad.cpp; path = src/Gamepad.cpp; sourceTree = SOURCE_ROOT; };
 		42F4B7D515994CED00B5A78D /* Gamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gamepad.cpp; path = src/Gamepad.cpp; sourceTree = SOURCE_ROOT; };
 		42F4B7D615994CED00B5A78D /* Gamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Gamepad.h; path = src/Gamepad.h; sourceTree = SOURCE_ROOT; };
 		42F4B7D615994CED00B5A78D /* Gamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Gamepad.h; path = src/Gamepad.h; sourceTree = SOURCE_ROOT; };
 		5B04C5CA14BFCFE100EB0071 /* libgameplay.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgameplay.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		5B04C5CA14BFCFE100EB0071 /* libgameplay.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgameplay.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1708,12 +1745,10 @@
 		5B2BC75E1512514500D176CD /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		5B2BC75E1512514500D176CD /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
 		5B2BC7611512514D00D176CD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
 		5B2BC7611512514D00D176CD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
 		5B2BC7631512516B00D176CD /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
 		5B2BC7631512516B00D176CD /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
-		5B5DB92D14C25B7B007755DB /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "../external-deps/bullet/lib/ios/i386/libbullet.a"; sourceTree = "<group>"; };
-		5B5DB92F14C25B94007755DB /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "../external-deps/libpng/lib/ios/armv7/libpng.a"; sourceTree = "<group>"; };
-		5B5DB93114C25BA5007755DB /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "../external-deps/oggvorbis/lib/ios/armv7/libogg.a"; sourceTree = "<group>"; };
-		5B5DB93214C25BA5007755DB /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "../external-deps/oggvorbis/lib/ios/armv7/libvorbis.a"; sourceTree = "<group>"; };
-		5B5DB93314C25BA5007755DB /* libvorbisenc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisenc.a; path = "../external-deps/oggvorbis/lib/ios/armv7/libvorbisenc.a"; sourceTree = "<group>"; };
-		5B5DB93414C25BA5007755DB /* libvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbisfile.a; path = "../external-deps/oggvorbis/lib/ios/armv7/libvorbisfile.a"; sourceTree = "<group>"; };
+		5B5DB92D14C25B7B007755DB /* libbullet.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libbullet.a; path = "../external-deps/bullet/lib/ios/armv7s/libbullet.a"; sourceTree = "<group>"; };
+		5B5DB92F14C25B94007755DB /* libpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng.a; path = "../external-deps/png/lib/ios/armv7s/libpng.a"; sourceTree = "<group>"; };
+		5B5DB93114C25BA5007755DB /* libogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libogg.a; path = "../external-deps/oggvorbis/lib/ios/armv7s/libogg.a"; sourceTree = "<group>"; };
+		5B5DB93214C25BA5007755DB /* libvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvorbis.a; path = "../external-deps/oggvorbis/lib/ios/armv7s/libvorbis.a"; sourceTree = "<group>"; };
 		5BB0823C14C6FEC40019975F /* Mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mouse.h; path = src/Mouse.h; sourceTree = SOURCE_ROOT; };
 		5BB0823C14C6FEC40019975F /* Mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mouse.h; path = src/Mouse.h; sourceTree = SOURCE_ROOT; };
 		5BBAD0EF15F5251D004C9639 /* lua_Gesture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_Gesture.cpp; sourceTree = "<group>"; };
 		5BBAD0EF15F5251D004C9639 /* lua_Gesture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_Gesture.cpp; sourceTree = "<group>"; };
 		5BBAD0F015F5251D004C9639 /* lua_Gesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_Gesture.h; sourceTree = "<group>"; };
 		5BBAD0F015F5251D004C9639 /* lua_Gesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_Gesture.h; sourceTree = "<group>"; };
@@ -1776,12 +1811,12 @@
 		B67EC8EA161DFC8E000B4D12 /* lua_LoggerLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_LoggerLevel.h; sourceTree = "<group>"; };
 		B67EC8EA161DFC8E000B4D12 /* lua_LoggerLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_LoggerLevel.h; sourceTree = "<group>"; };
 		B67EC8F4161DFCA8000B4D12 /* Logger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Logger.cpp; path = src/Logger.cpp; sourceTree = SOURCE_ROOT; };
 		B67EC8F4161DFCA8000B4D12 /* Logger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Logger.cpp; path = src/Logger.cpp; sourceTree = SOURCE_ROOT; };
 		B67EC8F5161DFCA8000B4D12 /* Logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logger.h; path = src/Logger.h; sourceTree = SOURCE_ROOT; };
 		B67EC8F5161DFCA8000B4D12 /* Logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logger.h; path = src/Logger.h; sourceTree = SOURCE_ROOT; };
-		BD2636DF16CF5B7400CFE15F /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
-		BD2636E016CF5B7400CFE15F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
-		BD2636E116CF5B7400CFE15F /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
-		BD2636E216CF5B7400CFE15F /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
-		BD2636E316CF5B7400CFE15F /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
-		BD2636E416CF5B7400CFE15F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+		BD2636DF16CF5B7400CFE15F /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; };
+		BD2636E016CF5B7400CFE15F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
+		BD2636E116CF5B7400CFE15F /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/OpenAL.framework; sourceTree = DEVELOPER_DIR; };
+		BD2636E216CF5B7400CFE15F /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; };
+		BD2636E316CF5B7400CFE15F /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
+		BD2636E416CF5B7400CFE15F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
 		C01405111765345800B9FFB1 /* lua_RenderStateStencilFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_RenderStateStencilFunction.cpp; sourceTree = "<group>"; };
 		C01405111765345800B9FFB1 /* lua_RenderStateStencilFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_RenderStateStencilFunction.cpp; sourceTree = "<group>"; };
 		C01405121765345800B9FFB1 /* lua_RenderStateStencilFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_RenderStateStencilFunction.h; sourceTree = "<group>"; };
 		C01405121765345800B9FFB1 /* lua_RenderStateStencilFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua_RenderStateStencilFunction.h; sourceTree = "<group>"; };
 		C01405131765345800B9FFB1 /* lua_RenderStateStencilOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_RenderStateStencilOperation.cpp; sourceTree = "<group>"; };
 		C01405131765345800B9FFB1 /* lua_RenderStateStencilOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_RenderStateStencilOperation.cpp; sourceTree = "<group>"; };
@@ -1850,6 +1885,7 @@
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
 				42BCD31E15EFD0F300C0E076 /* lua */,
 				42BCD31E15EFD0F300C0E076 /* lua */,
+				425EDA4F17FB25D300AABF95 /* social */,
 				5BD52634150F822A004C9099 /* AbsoluteLayout.cpp */,
 				5BD52634150F822A004C9099 /* AbsoluteLayout.cpp */,
 				5BD52635150F822A004C9099 /* AbsoluteLayout.h */,
 				5BD52635150F822A004C9099 /* AbsoluteLayout.h */,
 				42789FC215B0E83700866F5B /* AIAgent.cpp */,
 				42789FC215B0E83700866F5B /* AIAgent.cpp */,
@@ -2050,6 +2086,19 @@
 				421A233315B600E8004F97C3 /* ScriptTarget.h */,
 				421A233315B600E8004F97C3 /* ScriptTarget.h */,
 				5BD52646150F822A004C9099 /* Slider.cpp */,
 				5BD52646150F822A004C9099 /* Slider.cpp */,
 				5BD52647150F822A004C9099 /* Slider.h */,
 				5BD52647150F822A004C9099 /* Slider.h */,
+				425EDA5017FB260500AABF95 /* SocialAchievement.cpp */,
+				425EDA5117FB260500AABF95 /* SocialAchievement.h */,
+				425EDA5217FB260500AABF95 /* SocialChallenge.cpp */,
+				425EDA5317FB260500AABF95 /* SocialChallenge.h */,
+				425EDA5417FB260500AABF95 /* SocialController.cpp */,
+				425EDA5517FB260500AABF95 /* SocialController.h */,
+				425EDA5617FB260500AABF95 /* SocialPlayer.cpp */,
+				425EDA5717FB260500AABF95 /* SocialPlayer.h */,
+				425EDA5817FB260500AABF95 /* SocialScore.cpp */,
+				425EDA5917FB260500AABF95 /* SocialScore.h */,
+				425EDA5A17FB260500AABF95 /* SocialSession.h */,
+				425EDA5B17FB260500AABF95 /* SocialSessionListener.cpp */,
+				425EDA5C17FB260500AABF95 /* SocialSessionListener.h */,
 				42CD0E2F147D8FF50000361E /* SpriteBatch.cpp */,
 				42CD0E2F147D8FF50000361E /* SpriteBatch.cpp */,
 				42CD0E30147D8FF50000361E /* SpriteBatch.h */,
 				42CD0E30147D8FF50000361E /* SpriteBatch.h */,
 				9FC6EE721665304F00F39955 /* Stream.h */,
 				9FC6EE721665304F00F39955 /* Stream.h */,
@@ -2091,6 +2140,13 @@
 			path = gameplay;
 			path = gameplay;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		425EDA4F17FB25D300AABF95 /* social */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			name = social;
+			sourceTree = "<group>";
+		};
 		427D4F42147DC8DE0076760E /* Libraries */ = {
 		427D4F42147DC8DE0076760E /* Libraries */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -2493,11 +2549,9 @@
 			children = (
 			children = (
 				5B5DB92D14C25B7B007755DB /* libbullet.a */,
 				5B5DB92D14C25B7B007755DB /* libbullet.a */,
 				42B701F815B081B6002BB8C3 /* liblua.a */,
 				42B701F815B081B6002BB8C3 /* liblua.a */,
+				5B5DB92F14C25B94007755DB /* libpng.a */,
 				5B5DB93114C25BA5007755DB /* libogg.a */,
 				5B5DB93114C25BA5007755DB /* libogg.a */,
 				5B5DB93214C25BA5007755DB /* libvorbis.a */,
 				5B5DB93214C25BA5007755DB /* libvorbis.a */,
-				5B5DB93314C25BA5007755DB /* libvorbisenc.a */,
-				5B5DB93414C25BA5007755DB /* libvorbisfile.a */,
-				5B5DB92F14C25B94007755DB /* libpng.a */,
 				42DFAB4F16AD8ECD0000F342 /* libz.dylib */,
 				42DFAB4F16AD8ECD0000F342 /* libz.dylib */,
 			);
 			);
 			name = iOS;
 			name = iOS;
@@ -2508,11 +2562,9 @@
 			children = (
 			children = (
 				42CD0DA6147D8EA80000361E /* libbullet.a */,
 				42CD0DA6147D8EA80000361E /* libbullet.a */,
 				42B701F615B08177002BB8C3 /* liblua.a */,
 				42B701F615B08177002BB8C3 /* liblua.a */,
+				42CCD555146EC1EB00353661 /* libpng.a */,
 				42CD0DA7147D8EA80000361E /* libogg.a */,
 				42CD0DA7147D8EA80000361E /* libogg.a */,
 				42CD0DA8147D8EA80000361E /* libvorbis.a */,
 				42CD0DA8147D8EA80000361E /* libvorbis.a */,
-				42CD0DA9147D8EA80000361E /* libvorbisenc.a */,
-				42CD0DAA147D8EA80000361E /* libvorbisfile.a */,
-				42CCD555146EC1EB00353661 /* libpng.a */,
 				5B2BC7631512516B00D176CD /* libz.dylib */,
 				5B2BC7631512516B00D176CD /* libz.dylib */,
 			);
 			);
 			name = MacOSX;
 			name = MacOSX;
@@ -2538,6 +2590,8 @@
 				42CD0E5A147D8FF60000361E /* BoundingBox.h in Headers */,
 				42CD0E5A147D8FF60000361E /* BoundingBox.h in Headers */,
 				42CD0E5C147D8FF60000361E /* BoundingSphere.h in Headers */,
 				42CD0E5C147D8FF60000361E /* BoundingSphere.h in Headers */,
 				42CD0E5E147D8FF60000361E /* Camera.h in Headers */,
 				42CD0E5E147D8FF60000361E /* Camera.h in Headers */,
+				425EDA5F17FB260500AABF95 /* SocialAchievement.h in Headers */,
+				425EDA6F17FB260500AABF95 /* SocialScore.h in Headers */,
 				42CD0E60147D8FF60000361E /* Curve.h in Headers */,
 				42CD0E60147D8FF60000361E /* Curve.h in Headers */,
 				42CD0E62147D8FF60000361E /* DebugNew.h in Headers */,
 				42CD0E62147D8FF60000361E /* DebugNew.h in Headers */,
 				42CD0E64147D8FF60000361E /* DepthStencilTarget.h in Headers */,
 				42CD0E64147D8FF60000361E /* DepthStencilTarget.h in Headers */,
@@ -2619,6 +2673,7 @@
 				4239DDF4157545C1005EA3F6 /* MathUtil.h in Headers */,
 				4239DDF4157545C1005EA3F6 /* MathUtil.h in Headers */,
 				42F4B7D915994CED00B5A78D /* Gamepad.h in Headers */,
 				42F4B7D915994CED00B5A78D /* Gamepad.h in Headers */,
 				42B7FAE715B08049002BB8C3 /* ScriptController.h in Headers */,
 				42B7FAE715B08049002BB8C3 /* ScriptController.h in Headers */,
+				425EDA6717FB260500AABF95 /* SocialController.h in Headers */,
 				42789FCE15B0E83700866F5B /* AIAgent.h in Headers */,
 				42789FCE15B0E83700866F5B /* AIAgent.h in Headers */,
 				42789FD215B0E83700866F5B /* AIController.h in Headers */,
 				42789FD215B0E83700866F5B /* AIController.h in Headers */,
 				42789FD615B0E83700866F5B /* AIMessage.h in Headers */,
 				42789FD615B0E83700866F5B /* AIMessage.h in Headers */,
@@ -2631,6 +2686,7 @@
 				42BCD46615EFD0F300C0E076 /* lua_AIAgentListener.h in Headers */,
 				42BCD46615EFD0F300C0E076 /* lua_AIAgentListener.h in Headers */,
 				42BCD46A15EFD0F300C0E076 /* lua_AIController.h in Headers */,
 				42BCD46A15EFD0F300C0E076 /* lua_AIController.h in Headers */,
 				42BCD46E15EFD0F300C0E076 /* lua_AIMessage.h in Headers */,
 				42BCD46E15EFD0F300C0E076 /* lua_AIMessage.h in Headers */,
+				425EDA6B17FB260500AABF95 /* SocialPlayer.h in Headers */,
 				42BCD47215EFD0F300C0E076 /* lua_AIMessageParameterType.h in Headers */,
 				42BCD47215EFD0F300C0E076 /* lua_AIMessageParameterType.h in Headers */,
 				42BCD47615EFD0F300C0E076 /* lua_AIState.h in Headers */,
 				42BCD47615EFD0F300C0E076 /* lua_AIState.h in Headers */,
 				42BCD47A15EFD0F300C0E076 /* lua_AIStateListener.h in Headers */,
 				42BCD47A15EFD0F300C0E076 /* lua_AIStateListener.h in Headers */,
@@ -2649,7 +2705,9 @@
 				42BCD4AE15EFD0F300C0E076 /* lua_AudioSource.h in Headers */,
 				42BCD4AE15EFD0F300C0E076 /* lua_AudioSource.h in Headers */,
 				42BCD4B215EFD0F300C0E076 /* lua_AudioSourceState.h in Headers */,
 				42BCD4B215EFD0F300C0E076 /* lua_AudioSourceState.h in Headers */,
 				42BCD4B615EFD0F300C0E076 /* lua_BoundingBox.h in Headers */,
 				42BCD4B615EFD0F300C0E076 /* lua_BoundingBox.h in Headers */,
+				425EDA7117FB260500AABF95 /* SocialSession.h in Headers */,
 				42BCD4BA15EFD0F300C0E076 /* lua_BoundingSphere.h in Headers */,
 				42BCD4BA15EFD0F300C0E076 /* lua_BoundingSphere.h in Headers */,
+				425EDA6317FB260500AABF95 /* SocialChallenge.h in Headers */,
 				42BCD4BE15EFD0F300C0E076 /* lua_Bundle.h in Headers */,
 				42BCD4BE15EFD0F300C0E076 /* lua_Bundle.h in Headers */,
 				42BCD4C215EFD0F300C0E076 /* lua_Button.h in Headers */,
 				42BCD4C215EFD0F300C0E076 /* lua_Button.h in Headers */,
 				42BCD4C615EFD0F300C0E076 /* lua_Camera.h in Headers */,
 				42BCD4C615EFD0F300C0E076 /* lua_Camera.h in Headers */,
@@ -2669,6 +2727,7 @@
 				42BCD4FE15EFD0F300C0E076 /* lua_Effect.h in Headers */,
 				42BCD4FE15EFD0F300C0E076 /* lua_Effect.h in Headers */,
 				42BCD50215EFD0F300C0E076 /* lua_FileSystem.h in Headers */,
 				42BCD50215EFD0F300C0E076 /* lua_FileSystem.h in Headers */,
 				42BCD50615EFD0F300C0E076 /* lua_FlowLayout.h in Headers */,
 				42BCD50615EFD0F300C0E076 /* lua_FlowLayout.h in Headers */,
+				425EDA7517FB260500AABF95 /* SocialSessionListener.h in Headers */,
 				42BCD50A15EFD0F300C0E076 /* lua_Font.h in Headers */,
 				42BCD50A15EFD0F300C0E076 /* lua_Font.h in Headers */,
 				42BCD50E15EFD0F300C0E076 /* lua_FontJustify.h in Headers */,
 				42BCD50E15EFD0F300C0E076 /* lua_FontJustify.h in Headers */,
 				42BCD51215EFD0F300C0E076 /* lua_FontStyle.h in Headers */,
 				42BCD51215EFD0F300C0E076 /* lua_FontStyle.h in Headers */,
@@ -2848,6 +2907,8 @@
 				5B04C58B14BFCFE100EB0071 /* BoundingBox.h in Headers */,
 				5B04C58B14BFCFE100EB0071 /* BoundingBox.h in Headers */,
 				5B04C58C14BFCFE100EB0071 /* BoundingSphere.h in Headers */,
 				5B04C58C14BFCFE100EB0071 /* BoundingSphere.h in Headers */,
 				5B04C58D14BFCFE100EB0071 /* Camera.h in Headers */,
 				5B04C58D14BFCFE100EB0071 /* Camera.h in Headers */,
+				425EDA6017FB260500AABF95 /* SocialAchievement.h in Headers */,
+				425EDA7017FB260500AABF95 /* SocialScore.h in Headers */,
 				5B04C58E14BFCFE100EB0071 /* Curve.h in Headers */,
 				5B04C58E14BFCFE100EB0071 /* Curve.h in Headers */,
 				5B04C58F14BFCFE100EB0071 /* DebugNew.h in Headers */,
 				5B04C58F14BFCFE100EB0071 /* DebugNew.h in Headers */,
 				5B04C59014BFCFE100EB0071 /* DepthStencilTarget.h in Headers */,
 				5B04C59014BFCFE100EB0071 /* DepthStencilTarget.h in Headers */,
@@ -2929,6 +2990,7 @@
 				42F4B7DA15994CED00B5A78D /* Gamepad.h in Headers */,
 				42F4B7DA15994CED00B5A78D /* Gamepad.h in Headers */,
 				42B7FAE815B08049002BB8C3 /* ScriptController.h in Headers */,
 				42B7FAE815B08049002BB8C3 /* ScriptController.h in Headers */,
 				42789FCF15B0E83700866F5B /* AIAgent.h in Headers */,
 				42789FCF15B0E83700866F5B /* AIAgent.h in Headers */,
+				425EDA6817FB260500AABF95 /* SocialController.h in Headers */,
 				42789FD315B0E83700866F5B /* AIController.h in Headers */,
 				42789FD315B0E83700866F5B /* AIController.h in Headers */,
 				42789FD715B0E83700866F5B /* AIMessage.h in Headers */,
 				42789FD715B0E83700866F5B /* AIMessage.h in Headers */,
 				42789FDB15B0E83700866F5B /* AIState.h in Headers */,
 				42789FDB15B0E83700866F5B /* AIState.h in Headers */,
@@ -2941,6 +3003,7 @@
 				42BCD46B15EFD0F300C0E076 /* lua_AIController.h in Headers */,
 				42BCD46B15EFD0F300C0E076 /* lua_AIController.h in Headers */,
 				42BCD46F15EFD0F300C0E076 /* lua_AIMessage.h in Headers */,
 				42BCD46F15EFD0F300C0E076 /* lua_AIMessage.h in Headers */,
 				42BCD47315EFD0F300C0E076 /* lua_AIMessageParameterType.h in Headers */,
 				42BCD47315EFD0F300C0E076 /* lua_AIMessageParameterType.h in Headers */,
+				425EDA6C17FB260500AABF95 /* SocialPlayer.h in Headers */,
 				42BCD47715EFD0F300C0E076 /* lua_AIState.h in Headers */,
 				42BCD47715EFD0F300C0E076 /* lua_AIState.h in Headers */,
 				42BCD47B15EFD0F300C0E076 /* lua_AIStateListener.h in Headers */,
 				42BCD47B15EFD0F300C0E076 /* lua_AIStateListener.h in Headers */,
 				42BCD47F15EFD0F300C0E076 /* lua_AIStateMachine.h in Headers */,
 				42BCD47F15EFD0F300C0E076 /* lua_AIStateMachine.h in Headers */,
@@ -2959,7 +3022,9 @@
 				42BCD4B315EFD0F300C0E076 /* lua_AudioSourceState.h in Headers */,
 				42BCD4B315EFD0F300C0E076 /* lua_AudioSourceState.h in Headers */,
 				42BCD4B715EFD0F300C0E076 /* lua_BoundingBox.h in Headers */,
 				42BCD4B715EFD0F300C0E076 /* lua_BoundingBox.h in Headers */,
 				42BCD4BB15EFD0F300C0E076 /* lua_BoundingSphere.h in Headers */,
 				42BCD4BB15EFD0F300C0E076 /* lua_BoundingSphere.h in Headers */,
+				425EDA7217FB260500AABF95 /* SocialSession.h in Headers */,
 				42BCD4BF15EFD0F300C0E076 /* lua_Bundle.h in Headers */,
 				42BCD4BF15EFD0F300C0E076 /* lua_Bundle.h in Headers */,
+				425EDA6417FB260500AABF95 /* SocialChallenge.h in Headers */,
 				42BCD4C315EFD0F300C0E076 /* lua_Button.h in Headers */,
 				42BCD4C315EFD0F300C0E076 /* lua_Button.h in Headers */,
 				42BCD4C715EFD0F300C0E076 /* lua_Camera.h in Headers */,
 				42BCD4C715EFD0F300C0E076 /* lua_Camera.h in Headers */,
 				42BCD4CB15EFD0F300C0E076 /* lua_CameraType.h in Headers */,
 				42BCD4CB15EFD0F300C0E076 /* lua_CameraType.h in Headers */,
@@ -2979,6 +3044,7 @@
 				42BCD50315EFD0F300C0E076 /* lua_FileSystem.h in Headers */,
 				42BCD50315EFD0F300C0E076 /* lua_FileSystem.h in Headers */,
 				42BCD50715EFD0F300C0E076 /* lua_FlowLayout.h in Headers */,
 				42BCD50715EFD0F300C0E076 /* lua_FlowLayout.h in Headers */,
 				42BCD50B15EFD0F300C0E076 /* lua_Font.h in Headers */,
 				42BCD50B15EFD0F300C0E076 /* lua_Font.h in Headers */,
+				425EDA7617FB260500AABF95 /* SocialSessionListener.h in Headers */,
 				42BCD50F15EFD0F300C0E076 /* lua_FontJustify.h in Headers */,
 				42BCD50F15EFD0F300C0E076 /* lua_FontJustify.h in Headers */,
 				42BCD51315EFD0F300C0E076 /* lua_FontStyle.h in Headers */,
 				42BCD51315EFD0F300C0E076 /* lua_FontStyle.h in Headers */,
 				42BCD51715EFD0F300C0E076 /* lua_FontText.h in Headers */,
 				42BCD51715EFD0F300C0E076 /* lua_FontText.h in Headers */,
@@ -3186,7 +3252,7 @@
 		4234D98C14686BB6003031B3 /* Project object */ = {
 		4234D98C14686BB6003031B3 /* Project object */ = {
 			isa = PBXProject;
 			isa = PBXProject;
 			attributes = {
 			attributes = {
-				LastUpgradeCheck = 0440;
+				LastUpgradeCheck = 0500;
 			};
 			};
 			buildConfigurationList = 4234D98F14686BB6003031B3 /* Build configuration list for PBXProject "gameplay" */;
 			buildConfigurationList = 4234D98F14686BB6003031B3 /* Build configuration list for PBXProject "gameplay" */;
 			compatibilityVersion = "Xcode 3.2";
 			compatibilityVersion = "Xcode 3.2";
@@ -3276,6 +3342,7 @@
 				42CD0E91147D8FF60000361E /* PhysicsConstraint.cpp in Sources */,
 				42CD0E91147D8FF60000361E /* PhysicsConstraint.cpp in Sources */,
 				42CD0E93147D8FF60000361E /* PhysicsController.cpp in Sources */,
 				42CD0E93147D8FF60000361E /* PhysicsController.cpp in Sources */,
 				42CD0E95147D8FF60000361E /* PhysicsFixedConstraint.cpp in Sources */,
 				42CD0E95147D8FF60000361E /* PhysicsFixedConstraint.cpp in Sources */,
+				425EDA5D17FB260500AABF95 /* SocialAchievement.cpp in Sources */,
 				42CD0E97147D8FF60000361E /* PhysicsGenericConstraint.cpp in Sources */,
 				42CD0E97147D8FF60000361E /* PhysicsGenericConstraint.cpp in Sources */,
 				42CD0E99147D8FF60000361E /* PhysicsHingeConstraint.cpp in Sources */,
 				42CD0E99147D8FF60000361E /* PhysicsHingeConstraint.cpp in Sources */,
 				42CD0E9D147D8FF60000361E /* PhysicsRigidBody.cpp in Sources */,
 				42CD0E9D147D8FF60000361E /* PhysicsRigidBody.cpp in Sources */,
@@ -3303,6 +3370,7 @@
 				428390991489D6E800E2B2F5 /* SceneLoader.cpp in Sources */,
 				428390991489D6E800E2B2F5 /* SceneLoader.cpp in Sources */,
 				4208DEE914A4079F00D3C511 /* Image.cpp in Sources */,
 				4208DEE914A4079F00D3C511 /* Image.cpp in Sources */,
 				4201819014A41B18008C3F56 /* MeshBatch.cpp in Sources */,
 				4201819014A41B18008C3F56 /* MeshBatch.cpp in Sources */,
+				425EDA6917FB260500AABF95 /* SocialPlayer.cpp in Sources */,
 				5BD5264F150F822A004C9099 /* AbsoluteLayout.cpp in Sources */,
 				5BD5264F150F822A004C9099 /* AbsoluteLayout.cpp in Sources */,
 				5BD52651150F822A004C9099 /* Button.cpp in Sources */,
 				5BD52651150F822A004C9099 /* Button.cpp in Sources */,
 				5BD52653150F822A004C9099 /* CheckBox.cpp in Sources */,
 				5BD52653150F822A004C9099 /* CheckBox.cpp in Sources */,
@@ -3357,6 +3425,7 @@
 				42BCD4B015EFD0F300C0E076 /* lua_AudioSourceState.cpp in Sources */,
 				42BCD4B015EFD0F300C0E076 /* lua_AudioSourceState.cpp in Sources */,
 				42BCD4B415EFD0F300C0E076 /* lua_BoundingBox.cpp in Sources */,
 				42BCD4B415EFD0F300C0E076 /* lua_BoundingBox.cpp in Sources */,
 				42BCD4B815EFD0F300C0E076 /* lua_BoundingSphere.cpp in Sources */,
 				42BCD4B815EFD0F300C0E076 /* lua_BoundingSphere.cpp in Sources */,
+				425EDA6D17FB260500AABF95 /* SocialScore.cpp in Sources */,
 				42BCD4BC15EFD0F300C0E076 /* lua_Bundle.cpp in Sources */,
 				42BCD4BC15EFD0F300C0E076 /* lua_Bundle.cpp in Sources */,
 				42BCD4C015EFD0F300C0E076 /* lua_Button.cpp in Sources */,
 				42BCD4C015EFD0F300C0E076 /* lua_Button.cpp in Sources */,
 				42BCD4C415EFD0F300C0E076 /* lua_Camera.cpp in Sources */,
 				42BCD4C415EFD0F300C0E076 /* lua_Camera.cpp in Sources */,
@@ -3387,6 +3456,7 @@
 				42BCD52815EFD0F300C0E076 /* lua_GameClearFlags.cpp in Sources */,
 				42BCD52815EFD0F300C0E076 /* lua_GameClearFlags.cpp in Sources */,
 				42BCD52C15EFD0F300C0E076 /* lua_Gamepad.cpp in Sources */,
 				42BCD52C15EFD0F300C0E076 /* lua_Gamepad.cpp in Sources */,
 				42BCD53415EFD0F300C0E076 /* lua_GamepadGamepadEvent.cpp in Sources */,
 				42BCD53415EFD0F300C0E076 /* lua_GamepadGamepadEvent.cpp in Sources */,
+				425EDA6517FB260500AABF95 /* SocialController.cpp in Sources */,
 				42BCD53815EFD0F300C0E076 /* lua_GameState.cpp in Sources */,
 				42BCD53815EFD0F300C0E076 /* lua_GameState.cpp in Sources */,
 				42BCD53C15EFD0F300C0E076 /* lua_Global.cpp in Sources */,
 				42BCD53C15EFD0F300C0E076 /* lua_Global.cpp in Sources */,
 				42BCD54015EFD0F300C0E076 /* lua_Image.cpp in Sources */,
 				42BCD54015EFD0F300C0E076 /* lua_Image.cpp in Sources */,
@@ -3483,6 +3553,7 @@
 				42BCD6AC15EFD0F300C0E076 /* lua_Uniform.cpp in Sources */,
 				42BCD6AC15EFD0F300C0E076 /* lua_Uniform.cpp in Sources */,
 				42BCD6B015EFD0F300C0E076 /* lua_Vector2.cpp in Sources */,
 				42BCD6B015EFD0F300C0E076 /* lua_Vector2.cpp in Sources */,
 				42BCD6B415EFD0F300C0E076 /* lua_Vector3.cpp in Sources */,
 				42BCD6B415EFD0F300C0E076 /* lua_Vector3.cpp in Sources */,
+				425EDA6117FB260500AABF95 /* SocialChallenge.cpp in Sources */,
 				42BCD6B815EFD0F300C0E076 /* lua_Vector4.cpp in Sources */,
 				42BCD6B815EFD0F300C0E076 /* lua_Vector4.cpp in Sources */,
 				42BCD6BC15EFD0F300C0E076 /* lua_VertexAttributeBinding.cpp in Sources */,
 				42BCD6BC15EFD0F300C0E076 /* lua_VertexAttributeBinding.cpp in Sources */,
 				42BCD6C015EFD0F300C0E076 /* lua_VertexFormat.cpp in Sources */,
 				42BCD6C015EFD0F300C0E076 /* lua_VertexFormat.cpp in Sources */,
@@ -3506,6 +3577,7 @@
 				B661731716A619D30083A307 /* lua_TerrainFlags.cpp in Sources */,
 				B661731716A619D30083A307 /* lua_TerrainFlags.cpp in Sources */,
 				B661731F16A619FB0083A307 /* Terrain.cpp in Sources */,
 				B661731F16A619FB0083A307 /* Terrain.cpp in Sources */,
 				B661732316A619FB0083A307 /* TerrainPatch.cpp in Sources */,
 				B661732316A619FB0083A307 /* TerrainPatch.cpp in Sources */,
+				425EDA7317FB260500AABF95 /* SocialSessionListener.cpp in Sources */,
 				B661732916A61A140083A307 /* HeightField.cpp in Sources */,
 				B661732916A61A140083A307 /* HeightField.cpp in Sources */,
 				B661732F16A61A4B0083A307 /* lua_RenderStateDepthFunction.cpp in Sources */,
 				B661732F16A61A4B0083A307 /* lua_RenderStateDepthFunction.cpp in Sources */,
 				B661733516A61B430083A307 /* lua_GamepadButtonMapping.cpp in Sources */,
 				B661733516A61B430083A307 /* lua_GamepadButtonMapping.cpp in Sources */,
@@ -3560,6 +3632,7 @@
 				5B04C55214BFCFE100EB0071 /* PhysicsConstraint.cpp in Sources */,
 				5B04C55214BFCFE100EB0071 /* PhysicsConstraint.cpp in Sources */,
 				5B04C55314BFCFE100EB0071 /* PhysicsController.cpp in Sources */,
 				5B04C55314BFCFE100EB0071 /* PhysicsController.cpp in Sources */,
 				5B04C55414BFCFE100EB0071 /* PhysicsFixedConstraint.cpp in Sources */,
 				5B04C55414BFCFE100EB0071 /* PhysicsFixedConstraint.cpp in Sources */,
+				425EDA5E17FB260500AABF95 /* SocialAchievement.cpp in Sources */,
 				5B04C55514BFCFE100EB0071 /* PhysicsGenericConstraint.cpp in Sources */,
 				5B04C55514BFCFE100EB0071 /* PhysicsGenericConstraint.cpp in Sources */,
 				5B04C55614BFCFE100EB0071 /* PhysicsHingeConstraint.cpp in Sources */,
 				5B04C55614BFCFE100EB0071 /* PhysicsHingeConstraint.cpp in Sources */,
 				5B04C55814BFCFE100EB0071 /* PhysicsRigidBody.cpp in Sources */,
 				5B04C55814BFCFE100EB0071 /* PhysicsRigidBody.cpp in Sources */,
@@ -3587,6 +3660,7 @@
 				5B04C57214BFCFE100EB0071 /* Image.cpp in Sources */,
 				5B04C57214BFCFE100EB0071 /* Image.cpp in Sources */,
 				5B04C57314BFCFE100EB0071 /* MeshBatch.cpp in Sources */,
 				5B04C57314BFCFE100EB0071 /* MeshBatch.cpp in Sources */,
 				5B04C5CE14BFD48500EB0071 /* PlatformiOS.mm in Sources */,
 				5B04C5CE14BFD48500EB0071 /* PlatformiOS.mm in Sources */,
+				425EDA6A17FB260500AABF95 /* SocialPlayer.cpp in Sources */,
 				5BD52670150F8258004C9099 /* PhysicsCharacter.cpp in Sources */,
 				5BD52670150F8258004C9099 /* PhysicsCharacter.cpp in Sources */,
 				5BD52674150F8258004C9099 /* PhysicsCollisionObject.cpp in Sources */,
 				5BD52674150F8258004C9099 /* PhysicsCollisionObject.cpp in Sources */,
 				5BC4E73F150F843D00CBE1C0 /* AbsoluteLayout.cpp in Sources */,
 				5BC4E73F150F843D00CBE1C0 /* AbsoluteLayout.cpp in Sources */,
@@ -3641,6 +3715,7 @@
 				42BCD4B115EFD0F300C0E076 /* lua_AudioSourceState.cpp in Sources */,
 				42BCD4B115EFD0F300C0E076 /* lua_AudioSourceState.cpp in Sources */,
 				42BCD4B515EFD0F300C0E076 /* lua_BoundingBox.cpp in Sources */,
 				42BCD4B515EFD0F300C0E076 /* lua_BoundingBox.cpp in Sources */,
 				42BCD4B915EFD0F300C0E076 /* lua_BoundingSphere.cpp in Sources */,
 				42BCD4B915EFD0F300C0E076 /* lua_BoundingSphere.cpp in Sources */,
+				425EDA6E17FB260500AABF95 /* SocialScore.cpp in Sources */,
 				42BCD4BD15EFD0F300C0E076 /* lua_Bundle.cpp in Sources */,
 				42BCD4BD15EFD0F300C0E076 /* lua_Bundle.cpp in Sources */,
 				42BCD4C115EFD0F300C0E076 /* lua_Button.cpp in Sources */,
 				42BCD4C115EFD0F300C0E076 /* lua_Button.cpp in Sources */,
 				42BCD4C515EFD0F300C0E076 /* lua_Camera.cpp in Sources */,
 				42BCD4C515EFD0F300C0E076 /* lua_Camera.cpp in Sources */,
@@ -3671,6 +3746,7 @@
 				42BCD52915EFD0F300C0E076 /* lua_GameClearFlags.cpp in Sources */,
 				42BCD52915EFD0F300C0E076 /* lua_GameClearFlags.cpp in Sources */,
 				42BCD52D15EFD0F300C0E076 /* lua_Gamepad.cpp in Sources */,
 				42BCD52D15EFD0F300C0E076 /* lua_Gamepad.cpp in Sources */,
 				42BCD53515EFD0F300C0E076 /* lua_GamepadGamepadEvent.cpp in Sources */,
 				42BCD53515EFD0F300C0E076 /* lua_GamepadGamepadEvent.cpp in Sources */,
+				425EDA6617FB260500AABF95 /* SocialController.cpp in Sources */,
 				42BCD53915EFD0F300C0E076 /* lua_GameState.cpp in Sources */,
 				42BCD53915EFD0F300C0E076 /* lua_GameState.cpp in Sources */,
 				42BCD53D15EFD0F300C0E076 /* lua_Global.cpp in Sources */,
 				42BCD53D15EFD0F300C0E076 /* lua_Global.cpp in Sources */,
 				42BCD54115EFD0F300C0E076 /* lua_Image.cpp in Sources */,
 				42BCD54115EFD0F300C0E076 /* lua_Image.cpp in Sources */,
@@ -3767,6 +3843,7 @@
 				42BCD6AD15EFD0F300C0E076 /* lua_Uniform.cpp in Sources */,
 				42BCD6AD15EFD0F300C0E076 /* lua_Uniform.cpp in Sources */,
 				42BCD6B115EFD0F300C0E076 /* lua_Vector2.cpp in Sources */,
 				42BCD6B115EFD0F300C0E076 /* lua_Vector2.cpp in Sources */,
 				42BCD6B515EFD0F300C0E076 /* lua_Vector3.cpp in Sources */,
 				42BCD6B515EFD0F300C0E076 /* lua_Vector3.cpp in Sources */,
+				425EDA6217FB260500AABF95 /* SocialChallenge.cpp in Sources */,
 				42BCD6B915EFD0F300C0E076 /* lua_Vector4.cpp in Sources */,
 				42BCD6B915EFD0F300C0E076 /* lua_Vector4.cpp in Sources */,
 				42BCD6BD15EFD0F300C0E076 /* lua_VertexAttributeBinding.cpp in Sources */,
 				42BCD6BD15EFD0F300C0E076 /* lua_VertexAttributeBinding.cpp in Sources */,
 				42BCD6C115EFD0F300C0E076 /* lua_VertexFormat.cpp in Sources */,
 				42BCD6C115EFD0F300C0E076 /* lua_VertexFormat.cpp in Sources */,
@@ -3790,6 +3867,7 @@
 				B661731816A619D30083A307 /* lua_TerrainFlags.cpp in Sources */,
 				B661731816A619D30083A307 /* lua_TerrainFlags.cpp in Sources */,
 				B661732016A619FB0083A307 /* Terrain.cpp in Sources */,
 				B661732016A619FB0083A307 /* Terrain.cpp in Sources */,
 				B661732416A619FB0083A307 /* TerrainPatch.cpp in Sources */,
 				B661732416A619FB0083A307 /* TerrainPatch.cpp in Sources */,
+				425EDA7417FB260500AABF95 /* SocialSessionListener.cpp in Sources */,
 				B661732A16A61A140083A307 /* HeightField.cpp in Sources */,
 				B661732A16A61A140083A307 /* HeightField.cpp in Sources */,
 				B661733016A61A4B0083A307 /* lua_RenderStateDepthFunction.cpp in Sources */,
 				B661733016A61A4B0083A307 /* lua_RenderStateDepthFunction.cpp in Sources */,
 				B661733616A61B430083A307 /* lua_GamepadButtonMapping.cpp in Sources */,
 				B661733616A61B430083A307 /* lua_GamepadButtonMapping.cpp in Sources */,
@@ -3813,7 +3891,7 @@
 				ONLY_ACTIVE_ARCH = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = macosx;
 				SDKROOT = macosx;
 				SUPPORTED_PLATFORMS = "iphonesimulator macosx iphoneos";
 				SUPPORTED_PLATFORMS = "iphonesimulator macosx iphoneos";
-				VALID_ARCHS = "armv7 armv7s i386 x86_64";
+				VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64";
 			};
 			};
 			name = Debug;
 			name = Debug;
 		};
 		};
@@ -3822,7 +3900,7 @@
 			buildSettings = {
 			buildSettings = {
 				SDKROOT = macosx;
 				SDKROOT = macosx;
 				SUPPORTED_PLATFORMS = "iphonesimulator macosx iphoneos";
 				SUPPORTED_PLATFORMS = "iphonesimulator macosx iphoneos";
-				VALID_ARCHS = "armv7 armv7s i386 x86_64";
+				VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64";
 			};
 			};
 			name = Release;
 			name = Release;
 		};
 		};
@@ -3831,6 +3909,8 @@
 			buildSettings = {
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
+				CLANG_CXX_LIBRARY = "libstdc++";
 				COMBINE_HIDPI_IMAGES = YES;
 				COMBINE_HIDPI_IMAGES = YES;
 				COPY_PHASE_STRIP = NO;
 				COPY_PHASE_STRIP = NO;
 				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
 				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
@@ -3848,6 +3928,7 @@
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
 				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
 				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
 				GCC_WARN_MISSING_PARENTHESES = NO;
 				GCC_WARN_MISSING_PARENTHESES = NO;
@@ -3855,12 +3936,11 @@
 				HEADER_SEARCH_PATHS = (
 				HEADER_SEARCH_PATHS = (
 					"../external-deps/bullet/include",
 					"../external-deps/bullet/include",
 					"../external-deps/lua/include",
 					"../external-deps/lua/include",
-					"../external-deps/libpng/include",
+					"../external-deps/png/include",
 					"../external-deps/oggvorbis/include",
 					"../external-deps/oggvorbis/include",
-					./gameplay,
 				);
 				);
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
-				MACOSX_DEPLOYMENT_TARGET = 10.7;
+				MACOSX_DEPLOYMENT_TARGET = 10.8;
 				ONLY_ACTIVE_ARCH = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRODUCT_NAME = gameplay;
 				PRODUCT_NAME = gameplay;
@@ -3877,6 +3957,8 @@
 			buildSettings = {
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
+				CLANG_CXX_LIBRARY = "libstdc++";
 				COMBINE_HIDPI_IMAGES = YES;
 				COMBINE_HIDPI_IMAGES = YES;
 				COPY_PHASE_STRIP = YES;
 				COPY_PHASE_STRIP = YES;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@@ -3888,6 +3970,7 @@
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
 				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
 				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
 				GCC_WARN_MISSING_PARENTHESES = NO;
 				GCC_WARN_MISSING_PARENTHESES = NO;
@@ -3895,12 +3978,11 @@
 				HEADER_SEARCH_PATHS = (
 				HEADER_SEARCH_PATHS = (
 					"../external-deps/bullet/include",
 					"../external-deps/bullet/include",
 					"../external-deps/lua/include",
 					"../external-deps/lua/include",
-					"../external-deps/libpng/include",
+					"../external-deps/png/include",
 					"../external-deps/oggvorbis/include",
 					"../external-deps/oggvorbis/include",
-					./gameplay,
 				);
 				);
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
-				MACOSX_DEPLOYMENT_TARGET = 10.7;
+				MACOSX_DEPLOYMENT_TARGET = 10.8;
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRODUCT_NAME = gameplay;
 				PRODUCT_NAME = gameplay;
 				PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)_include";
 				PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)_include";
@@ -3915,7 +3997,9 @@
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
+				CLANG_CXX_LIBRARY = "libstdc++";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				COPY_PHASE_STRIP = NO;
 				COPY_PHASE_STRIP = NO;
 				DEPLOYMENT_LOCATION = NO;
 				DEPLOYMENT_LOCATION = NO;
@@ -3931,6 +4015,7 @@
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
 				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
 				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
 				GCC_WARN_MISSING_PARENTHESES = NO;
 				GCC_WARN_MISSING_PARENTHESES = NO;
@@ -3938,23 +4023,24 @@
 				HEADER_SEARCH_PATHS = (
 				HEADER_SEARCH_PATHS = (
 					"../external-deps/bullet/include",
 					"../external-deps/bullet/include",
 					"../external-deps/lua/include",
 					"../external-deps/lua/include",
-					"../external-deps/libpng/include",
+					"../external-deps/png/include",
 					"../external-deps/oggvorbis/include",
 					"../external-deps/oggvorbis/include",
 				);
 				);
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
-				MACOSX_DEPLOYMENT_TARGET = 10.7;
+				MACOSX_DEPLOYMENT_TARGET = 10.8;
 				ONLY_ACTIVE_ARCH = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				OTHER_LDFLAGS = "-ObjC";
 				OTHER_LDFLAGS = "-ObjC";
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRODUCT_NAME = gameplay;
 				PRODUCT_NAME = gameplay;
 				PROVISIONING_PROFILE = "";
 				PROVISIONING_PROFILE = "";
-				PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)_include";
+				PUBLIC_HEADERS_FOLDER_PATH = include;
 				SDKROOT = iphoneos;
 				SDKROOT = iphoneos;
 				SHARED_PRECOMPS_DIR = "";
 				SHARED_PRECOMPS_DIR = "";
 				SKIP_INSTALL = YES;
 				SKIP_INSTALL = YES;
 				SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
 				SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
+				TARGETED_DEVICE_FAMILY = "1,2";
 				USER_HEADER_SEARCH_PATHS = "";
 				USER_HEADER_SEARCH_PATHS = "";
-				VALID_ARCHS = "armv7 armv7s i386";
+				VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64";
 			};
 			};
 			name = Debug;
 			name = Debug;
 		};
 		};
@@ -3962,7 +4048,9 @@
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++98";
+				CLANG_CXX_LIBRARY = "libstdc++";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				COPY_PHASE_STRIP = YES;
 				COPY_PHASE_STRIP = YES;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@@ -3976,6 +4064,7 @@
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
 				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
 				GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO;
+				GCC_WARN_ABOUT_POINTER_SIGNEDNESS = NO;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
 				GCC_WARN_CHECK_SWITCH_STATEMENTS = NO;
 				GCC_WARN_MISSING_PARENTHESES = NO;
 				GCC_WARN_MISSING_PARENTHESES = NO;
@@ -3983,22 +4072,23 @@
 				HEADER_SEARCH_PATHS = (
 				HEADER_SEARCH_PATHS = (
 					"../external-deps/bullet/include",
 					"../external-deps/bullet/include",
 					"../external-deps/lua/include",
 					"../external-deps/lua/include",
-					"../external-deps/libpng/include",
+					"../external-deps/png/include",
 					"../external-deps/oggvorbis/include",
 					"../external-deps/oggvorbis/include",
 				);
 				);
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
 				LIBRARY_SEARCH_PATHS = "$(inherited)";
-				MACOSX_DEPLOYMENT_TARGET = 10.7;
+				MACOSX_DEPLOYMENT_TARGET = 10.8;
 				OTHER_LDFLAGS = "-ObjC";
 				OTHER_LDFLAGS = "-ObjC";
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
 				PRODUCT_NAME = gameplay;
 				PRODUCT_NAME = gameplay;
 				PROVISIONING_PROFILE = "";
 				PROVISIONING_PROFILE = "";
-				PUBLIC_HEADERS_FOLDER_PATH = "$(PROJECT_NAME)_include";
+				PUBLIC_HEADERS_FOLDER_PATH = include;
 				SDKROOT = iphoneos;
 				SDKROOT = iphoneos;
 				SHARED_PRECOMPS_DIR = "";
 				SHARED_PRECOMPS_DIR = "";
 				SKIP_INSTALL = YES;
 				SKIP_INSTALL = YES;
 				SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
 				SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
+				TARGETED_DEVICE_FAMILY = "1,2";
 				USER_HEADER_SEARCH_PATHS = "";
 				USER_HEADER_SEARCH_PATHS = "";
-				VALID_ARCHS = "armv7 armv7s i386";
+				VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64";
 			};
 			};
 			name = Release;
 			name = Release;
 		};
 		};

+ 0 - 7
gameplay/gameplay.xcodeproj/project.xcworkspace/contents.xcworkspacedata

@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Workspace
-   version = "1.0">
-   <FileRef
-      location = "self:gameplay.xcodeproj">
-   </FileRef>
-</Workspace>

BIN
gameplay/gameplay.xcodeproj/project.xcworkspace/xcuserdata/mozeal.xcuserdatad/UserInterfaceState.xcuserstate


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

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

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

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

+ 0 - 0
samples/lua/res/arial.ttf → gameplay/res/arial.ttf


+ 14 - 1
gameplay/res/shaders/font.frag

@@ -1,9 +1,13 @@
 #ifdef OPENGL_ES
 #ifdef OPENGL_ES
 precision highp float;
 precision highp float;
+#extension GL_OES_standard_derivatives : enable
 #endif
 #endif
 
 
 // Uniforms
 // Uniforms
 uniform sampler2D u_texture;
 uniform sampler2D u_texture;
+#ifdef DISTANCE_FIELD
+uniform vec2 u_cutoff;
+#endif
 
 
 // Varyings
 // Varyings
 varying vec2 v_texCoord;
 varying vec2 v_texCoord;
@@ -11,7 +15,16 @@ varying vec4 v_color;
 
 
 
 
 void main()
 void main()
-{
+{ 
+#ifdef DISTANCE_FIELD
+    gl_FragColor = v_color;
+    float distance = texture2D(u_texture, v_texCoord).a;
+    float smoothing = fwidth(distance);
+    float alpha = smoothstep(0.5 - smoothing * u_cutoff.x, 0.5 + smoothing * u_cutoff.y, distance);
+    gl_FragColor.a = alpha * v_color.a;
+
+#else
     gl_FragColor = v_color;
     gl_FragColor = v_color;
     gl_FragColor.a = texture2D(u_texture, v_texCoord).a * v_color.a;
     gl_FragColor.a = texture2D(u_texture, v_texCoord).a * v_color.a;
+#endif
 }
 }

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

@@ -10,7 +10,6 @@ uniform mat4 u_projectionMatrix;
 varying vec2 v_texCoord;
 varying vec2 v_texCoord;
 varying vec4 v_color;
 varying vec4 v_color;
 
 
-
 void main()
 void main()
 {
 {
     gl_Position = u_projectionMatrix * vec4(a_position, 1);
     gl_Position = u_projectionMatrix * vec4(a_position, 1);

+ 14 - 10
gameplay/src/Base.h

@@ -97,6 +97,17 @@ extern void print(const char* format, ...);
         gameplay::Logger::log(gameplay::Logger::LEVEL_WARN, "\n"); \
         gameplay::Logger::log(gameplay::Logger::LEVEL_WARN, "\n"); \
     } while (0)
     } while (0)
 
 
+#if defined(WIN32)
+    #pragma warning( disable : 4005 )
+    #pragma warning( disable : 4172 )
+    #pragma warning( disable : 4244 )
+    #pragma warning( disable : 4267 )
+    #pragma warning( disable : 4311 )
+    #pragma warning( disable : 4390 )
+    #pragma warning( disable : 4800 )
+    #pragma warning( disable : 4996 )
+#endif
+
 // Bullet Physics
 // Bullet Physics
 #include <btBulletDynamicsCommon.h>
 #include <btBulletDynamicsCommon.h>
 #include <BulletCollision/CollisionDispatch/btGhostObject.h>
 #include <BulletCollision/CollisionDispatch/btGhostObject.h>
@@ -293,14 +304,17 @@ typedef GLuint RenderBufferHandle;
     typedef void* SocialPlayerHandle;
     typedef void* SocialPlayerHandle;
     typedef void* SocialAchievementHandle;
     typedef void* SocialAchievementHandle;
     typedef void* SocialScoreHandle;
     typedef void* SocialScoreHandle;
+    typedef void* SocialChallengeHandle;
 #elif defined(WIN32)
 #elif defined(WIN32)
     typedef unsigned long SocialPlayerHandle;
     typedef unsigned long SocialPlayerHandle;
     typedef unsigned long SocialAchievementHandle;
     typedef unsigned long SocialAchievementHandle;
     typedef unsigned long SocialScoreHandle;
     typedef unsigned long SocialScoreHandle;
+    typedef unsigned long SocialChallengeHandle;
 #else
 #else
     typedef unsigned int SocialPlayerHandle;
     typedef unsigned int SocialPlayerHandle;
     typedef unsigned int SocialAchievementHandle;
     typedef unsigned int SocialAchievementHandle;
     typedef unsigned int SocialScoreHandle;
     typedef unsigned int SocialScoreHandle;
+    typedef unsigned int SocialChallengeHandle;
 #endif
 #endif
 
 
 }
 }
@@ -355,14 +369,4 @@ extern ALenum __al_error_code;
  */
  */
 #define AL_LAST_ERROR() __al_error_code
 #define AL_LAST_ERROR() __al_error_code
 
 
-
-#if defined(WIN32)
-    #pragma warning( disable : 4172 )
-    #pragma warning( disable : 4244 )
-    #pragma warning( disable : 4311 )
-    #pragma warning( disable : 4390 )
-    #pragma warning( disable : 4800 )
-    #pragma warning( disable : 4996 )
-#endif
-
 #endif
 #endif

+ 38 - 7
gameplay/src/Bundle.cpp

@@ -5,8 +5,9 @@
 #include "Scene.h"
 #include "Scene.h"
 #include "Joint.h"
 #include "Joint.h"
 
 
-#define BUNDLE_VERSION_MAJOR            1
-#define BUNDLE_VERSION_MINOR            2
+// Minimum version numbers supported
+#define BUNDLE_VERSION_MAJOR_REQUIRED   1 
+#define BUNDLE_VERSION_MINOR_REQUIRED   2
 
 
 #define BUNDLE_TYPE_SCENE               1
 #define BUNDLE_TYPE_SCENE               1
 #define BUNDLE_TYPE_NODE                2
 #define BUNDLE_TYPE_NODE                2
@@ -26,6 +27,9 @@
 // For sanity checking string reads
 // For sanity checking string reads
 #define BUNDLE_MAX_STRING_LENGTH        5000
 #define BUNDLE_MAX_STRING_LENGTH        5000
 
 
+#define BUNDLE_VERSION_MAJOR_FONT_FORMAT  1
+#define BUNDLE_VERSION_MINOR_FONT_FORMAT  3
+
 namespace gameplay
 namespace gameplay
 {
 {
 
 
@@ -55,6 +59,16 @@ Bundle::~Bundle()
     }
     }
 }
 }
 
 
+unsigned int Bundle::getVersionMajor() const
+{
+    return (unsigned int)_version[0];
+}
+
+unsigned int Bundle::getVersionMinor() const
+{
+    return (unsigned int)_version[1];
+}
+
 template <class T>
 template <class T>
 bool Bundle::readArray(unsigned int* length, T** ptr)
 bool Bundle::readArray(unsigned int* length, T** ptr)
 {
 {
@@ -189,17 +203,18 @@ Bundle* Bundle::create(const char* path)
     }
     }
 
 
     // Read version.
     // Read version.
-    unsigned char ver[2];
-    if (stream->read(ver, 1, 2) != 2)
+    unsigned char version[2];
+    if (stream->read(version, 1, 2) != 2)
     {
     {
         SAFE_DELETE(stream);
         SAFE_DELETE(stream);
         GP_ERROR("Failed to read GPB version for bundle '%s'.", path);
         GP_ERROR("Failed to read GPB version for bundle '%s'.", path);
         return NULL;
         return NULL;
     }
     }
-    if (ver[0] != BUNDLE_VERSION_MAJOR || ver[1] != BUNDLE_VERSION_MINOR)
+    // Check for the minimal 
+    if (version[0] != BUNDLE_VERSION_MAJOR_REQUIRED || version[1] < BUNDLE_VERSION_MINOR_REQUIRED)
     {
     {
         SAFE_DELETE(stream);
         SAFE_DELETE(stream);
-        GP_ERROR("Unsupported version (%d.%d) for bundle '%s' (expected %d.%d).", (int)ver[0], (int)ver[1], path, BUNDLE_VERSION_MAJOR, BUNDLE_VERSION_MINOR);
+        GP_ERROR("Unsupported version (%d.%d) for bundle '%s' (expected %d.%d).", (int)version[0], (int)version[1], path, BUNDLE_VERSION_MAJOR_REQUIRED, BUNDLE_VERSION_MINOR_REQUIRED);
         return NULL;
         return NULL;
     }
     }
 
 
@@ -229,6 +244,8 @@ Bundle* Bundle::create(const char* path)
 
 
     // Keep file open for faster reading later.
     // Keep file open for faster reading later.
     Bundle* bundle = new Bundle(path);
     Bundle* bundle = new Bundle(path);
+    bundle->_version[0] = version[0];
+    bundle->_version[1] = version[1];
     bundle->_referenceCount = refCount;
     bundle->_referenceCount = refCount;
     bundle->_references = refs;
     bundle->_references = refs;
     bundle->_stream = stream;
     bundle->_stream = stream;
@@ -1704,6 +1721,20 @@ Font* Bundle::loadFont(const char* id)
         return NULL;
         return NULL;
     }
     }
 
 
+    unsigned int format = Font::BITMAP;
+    // After bundle version we add enum FontFormat to bundle format
+    if (getVersionMajor() >= BUNDLE_VERSION_MAJOR_FONT_FORMAT &&
+        getVersionMinor() >= BUNDLE_VERSION_MINOR_FONT_FORMAT)
+    {
+        if (_stream->read(&format, 4, 1) != 1)
+        {
+            GP_ERROR("Failed to font format'%u'.", format);
+            SAFE_DELETE_ARRAY(glyphs);
+            SAFE_DELETE_ARRAY(textureData);
+            return NULL;
+        }
+    }
+
     // Create the texture for the font.
     // Create the texture for the font.
     Texture* texture = Texture::create(Texture::ALPHA, width, height, textureData, true);
     Texture* texture = Texture::create(Texture::ALPHA, width, height, textureData, true);
 
 
@@ -1718,7 +1749,7 @@ Font* Bundle::loadFont(const char* id)
     }
     }
 
 
     // Create the font.
     // Create the font.
-    Font* font = Font::create(family.c_str(), Font::PLAIN, size, glyphs, glyphCount, texture);
+    Font* font = Font::create(family.c_str(), Font::PLAIN, size, glyphs, glyphCount, texture, (Font::Format)format);
 
 
     // Free the glyph array.
     // Free the glyph array.
     SAFE_DELETE_ARRAY(glyphs);
     SAFE_DELETE_ARRAY(glyphs);

+ 16 - 1
gameplay/src/Bundle.h

@@ -89,7 +89,7 @@ public:
     unsigned int getObjectCount() const;
     unsigned int getObjectCount() const;
 
 
     /**
     /**
-     * Returns the unique identifier of the top-level object at the specified index in this bundle.
+     * Gets the unique identifier of the top-level object at the specified index in this bundle.
      *
      *
      * @param index The index of the object.
      * @param index The index of the object.
      * 
      * 
@@ -97,6 +97,20 @@ public:
      */
      */
     const char* getObjectId(unsigned int index) const;
     const char* getObjectId(unsigned int index) const;
 
 
+    /**
+     * Gets the major version of the loaded bundle.
+     *
+     * @return The major version of the loaded bundle.
+     */
+    unsigned int getVersionMajor() const;
+
+    /**
+     * Gets the minor version of the loaded bundle.
+     *
+     * @return The minor version of the loaded bundle.
+     */
+    unsigned int getVersionMinor() const;
+
 private:
 private:
 
 
     class Reference
     class Reference
@@ -433,6 +447,7 @@ private:
      */
      */
     bool skipNode();
     bool skipNode();
 
 
+    unsigned char _version[2];
     std::string _path;
     std::string _path;
     std::string _materialPath;
     std::string _materialPath;
     unsigned int _referenceCount;
     unsigned int _referenceCount;

+ 13 - 3
gameplay/src/CheckBox.cpp

@@ -145,11 +145,21 @@ void CheckBox::update(const Control* container, const Vector2& offset)
     {
     {
         size.set(_imageSize);
         size.set(_imageSize);
     }
     }
-    float iconWidth = size.x;
+    
+    if (_autoWidth == Control::AUTO_SIZE_FIT)
+    {
+        // Text-only width was already measured in Label::update - append image
+        setWidth(size.x + _bounds.width + 5);
+    }
 
 
-    _textBounds.x += iconWidth + 5;
-    _textBounds.width -= iconWidth + 5;
+    if (_autoHeight == Control::AUTO_SIZE_FIT)
+    {
+        // Text-only width was already measured in Label::update - append image
+        setHeight(std::max(getHeight(), size.y));
+    }
 
 
+    _textBounds.x += size.x + 5;
+    
     if (_checked)
     if (_checked)
     {
     {
         _image = getImage("checked", _state);
         _image = getImage("checked", _state);

+ 110 - 10
gameplay/src/Container.cpp

@@ -61,7 +61,7 @@ Container::Container()
       _lastFrameTime(0), _focusChangeRepeat(false),
       _lastFrameTime(0), _focusChangeRepeat(false),
       _focusChangeStartTime(0), _focusChangeRepeatDelay(FOCUS_CHANGE_REPEAT_DELAY), _focusChangeCount(0),
       _focusChangeStartTime(0), _focusChangeRepeatDelay(FOCUS_CHANGE_REPEAT_DELAY), _focusChangeCount(0),
       _totalWidth(0), _totalHeight(0),
       _totalWidth(0), _totalHeight(0),
-      _initializedWithScroll(false), _scrollWheelRequiresFocus(false)
+      _initializedWithScroll(false), _scrollWheelRequiresFocus(false), _allowRelayout(true)
 {
 {
 	clearContacts();
 	clearContacts();
 }
 }
@@ -101,6 +101,9 @@ Container* Container::create(Layout::Type type)
     case Layout::LAYOUT_VERTICAL:
     case Layout::LAYOUT_VERTICAL:
         layout = VerticalLayout::create();
         layout = VerticalLayout::create();
         break;
         break;
+    default:
+        layout = AbsoluteLayout::create();
+        break;
     }
     }
 
 
     Container* container = new Container();
     Container* container = new Container();
@@ -113,8 +116,28 @@ Control* Container::create(Theme::Style* style, Properties* properties, Theme* t
 {
 {
     GP_ASSERT(properties);
     GP_ASSERT(properties);
 
 
-    const char* layoutString = properties->getString("layout");
-    Container* container = Container::create(getLayoutType(layoutString));
+    // Parse layout
+    Container* container;
+    Properties* layoutNS = properties->getNamespace("layout", true, false);
+    if (layoutNS)
+    {
+        Layout::Type layoutType = getLayoutType(layoutNS->getString("type"));
+        container = Container::create(layoutType);
+        switch (layoutType)
+        {
+        case Layout::LAYOUT_FLOW:
+            static_cast<FlowLayout*>(container->getLayout())->setSpacing(layoutNS->getInt("horizontalSpacing"), layoutNS->getInt("verticalSpacing"));
+            break;
+        case Layout::LAYOUT_VERTICAL:
+            static_cast<VerticalLayout*>(container->getLayout())->setSpacing(layoutNS->getInt("spacing"));
+            break;
+        }
+    }
+    else
+    {
+        container = Container::create(getLayoutType(properties->getString("layout")));
+    }
+
     container->initialize(style, properties);
     container->initialize(style, properties);
     container->_scroll = getScroll(properties->getString("scroll"));
     container->_scroll = getScroll(properties->getString("scroll"));
     container->_scrollBarsAutoHide = properties->getBool("scrollBarsAutoHide");
     container->_scrollBarsAutoHide = properties->getBool("scrollBarsAutoHide");
@@ -429,6 +452,7 @@ void Container::update(const Control* container, const Vector2& offset)
 
 
         GP_ASSERT(_scrollBarLeftCap && _scrollBarHorizontal && _scrollBarRightCap);
         GP_ASSERT(_scrollBarLeftCap && _scrollBarHorizontal && _scrollBarRightCap);
 
 
+        _viewportBounds.height -= _scrollBarHorizontal->getRegion().height;
         _viewportClipBounds.height -= _scrollBarHorizontal->getRegion().height;
         _viewportClipBounds.height -= _scrollBarHorizontal->getRegion().height;
     }
     }
 
 
@@ -439,7 +463,8 @@ void Container::update(const Control* container, const Vector2& offset)
         _scrollBarBottomCap = getImage("scrollBarBottomCap", _state);
         _scrollBarBottomCap = getImage("scrollBarBottomCap", _state);
 
 
         GP_ASSERT(_scrollBarTopCap && _scrollBarVertical && _scrollBarBottomCap);
         GP_ASSERT(_scrollBarTopCap && _scrollBarVertical && _scrollBarBottomCap);
-        
+
+        _viewportBounds.width -= _scrollBarVertical->getRegion().width;
         _viewportClipBounds.width -= _scrollBarVertical->getRegion().width;
         _viewportClipBounds.width -= _scrollBarVertical->getRegion().width;
     }
     }
 
 
@@ -452,6 +477,81 @@ void Container::update(const Control* container, const Vector2& offset)
     {
     {
         _layout->update(this, Vector2::zero());
         _layout->update(this, Vector2::zero());
     }
     }
+
+    // Handle automatically sizing based on our children
+    if (_autoWidth == Control::AUTO_SIZE_FIT || _autoHeight == Control::AUTO_SIZE_FIT)
+    {
+        Vector2 oldSize(_bounds.width, _bounds.height);
+        bool sizeChanged = false;
+        bool relayout = false;
+
+        if (_autoWidth == Control::AUTO_SIZE_FIT)
+        {
+            // Size ourself to tightly fit the width of our children
+            float width = 0;
+            for (std::vector<Control*>::const_iterator it = _controls.begin(); it < _controls.end(); ++it)
+            {
+                Control* ctrl = *it;
+                if (ctrl->isXPercentage() || ctrl->isWidthPercentage())
+                {
+                    // We (this control's parent) are resizing and our child's layout
+                    // depends on our size, so we need to dirty it
+                    ctrl->_dirty = true;
+                    relayout = _allowRelayout;
+                }
+                else
+                {
+                    float w = ctrl->getX() + ctrl->getWidth();
+                    if (width < w)
+                        width = w;
+                }
+            }
+            width += getBorder(_state).left + getBorder(_state).right + getPadding().left + getPadding().right;
+            if (width != oldSize.x)
+            {
+                setWidth(width);
+                sizeChanged = true;
+            }
+        }
+
+        if (_autoHeight == Control::AUTO_SIZE_FIT)
+        {
+            // Size ourself to tightly fit the height of our children
+            float height = 0;
+            for (std::vector<Control*>::const_iterator it = _controls.begin(); it < _controls.end(); ++it)
+            {
+                Control* ctrl = *it;
+                if (ctrl->isYPercentage() || ctrl->isHeightPercentage())
+                {
+                    // We (this control's parent) are resizing and our child's layout
+                    // depends on our size, so we need to dirty it
+                    ctrl->_dirty = true;
+                    relayout = _allowRelayout;
+                }
+                else
+                {
+                    float h = ctrl->getY() + ctrl->getHeight();
+                    if (height < h)
+                        height = h;
+                }
+            }
+            height += getBorder(_state).top + getBorder(_state).bottom + getPadding().top + getPadding().bottom;
+            if (height != oldSize.y)
+            {
+                setHeight(height);
+                sizeChanged = true;
+            }
+        }
+
+        if (sizeChanged && relayout)
+        {
+            // Our size changed and as a result we need to force another layout.
+            // Prevent infinitely recursive layouts by disabling relayout for the next call.
+            _allowRelayout = false;
+            update(container, offset);
+            _allowRelayout = true;
+        }
+    }
 }
 }
 
 
 void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight)
 void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight)
@@ -520,7 +620,7 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
 
 
             clipRegion.width += verticalRegion.width;
             clipRegion.width += verticalRegion.width;
 
 
-            Rectangle bounds(_viewportBounds.x + _viewportBounds.width - verticalRegion.width, _viewportBounds.y + _scrollBarBounds.y, topRegion.width, topRegion.height);
+            Rectangle bounds(_viewportBounds.x + _viewportBounds.width, _viewportBounds.y + _scrollBarBounds.y, topRegion.width, topRegion.height);
             spriteBatch->draw(bounds.x, bounds.y, bounds.width, bounds.height, topUVs.u1, topUVs.v1, topUVs.u2, topUVs.v2, topColor, clipRegion);
             spriteBatch->draw(bounds.x, bounds.y, bounds.width, bounds.height, topUVs.u1, topUVs.v1, topUVs.u2, topUVs.v2, topColor, clipRegion);
 
 
             bounds.y += topRegion.height;
             bounds.y += topRegion.height;
@@ -551,7 +651,7 @@ void Container::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needs
 
 
             clipRegion.height += horizontalRegion.height;
             clipRegion.height += horizontalRegion.height;
         
         
-            Rectangle bounds(_viewportBounds.x + _scrollBarBounds.x, _viewportBounds.y + _viewportBounds.height - horizontalRegion.height, leftRegion.width, leftRegion.height);
+            Rectangle bounds(_viewportBounds.x + _scrollBarBounds.x, _viewportBounds.y + _viewportBounds.height, leftRegion.width, leftRegion.height);
             spriteBatch->draw(bounds.x, bounds.y, bounds.width, bounds.height, leftUVs.u1, leftUVs.v1, leftUVs.u2, leftUVs.v2, leftColor, clipRegion);
             spriteBatch->draw(bounds.x, bounds.y, bounds.width, bounds.height, leftUVs.u1, leftUVs.v1, leftUVs.u2, leftUVs.v2, leftColor, clipRegion);
 
 
             bounds.x += leftRegion.width;
             bounds.x += leftRegion.width;
@@ -1297,8 +1397,8 @@ void Container::updateScroll()
 
 
     float vWidth = getImageRegion("verticalScrollBar", _state).width;
     float vWidth = getImageRegion("verticalScrollBar", _state).width;
     float hHeight = getImageRegion("horizontalScrollBar", _state).height;
     float hHeight = getImageRegion("horizontalScrollBar", _state).height;
-    float clipWidth = _bounds.width - containerBorder.left - containerBorder.right - containerPadding.left - containerPadding.right - vWidth;
-    float clipHeight = _bounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom - hHeight;
+    float clipWidth = _absoluteBounds.width - containerBorder.left - containerBorder.right - containerPadding.left - containerPadding.right - vWidth;
+    float clipHeight = _absoluteBounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom - hHeight;
 
 
     // Apply and dampen inertia.
     // Apply and dampen inertia.
     if (!_scrollingVelocity.isZero())
     if (!_scrollingVelocity.isZero())
@@ -1537,7 +1637,7 @@ bool Container::mouseEventScroll(Mouse::MouseEvent evt, int x, int y, int wheelD
             if (_scrollBarVertical)
             if (_scrollBarVertical)
             {
             {
                 float vWidth = _scrollBarVertical->getRegion().width;
                 float vWidth = _scrollBarVertical->getRegion().width;
-                Rectangle vBounds(_viewportBounds.x + _viewportBounds.width - vWidth,
+                Rectangle vBounds(_viewportBounds.x + _viewportBounds.width,
                                  _scrollBarBounds.y,
                                  _scrollBarBounds.y,
                                  vWidth, _scrollBarBounds.height);
                                  vWidth, _scrollBarBounds.height);
 
 
@@ -1565,7 +1665,7 @@ bool Container::mouseEventScroll(Mouse::MouseEvent evt, int x, int y, int wheelD
             {
             {
                 float hHeight = _scrollBarHorizontal->getRegion().height;
                 float hHeight = _scrollBarHorizontal->getRegion().height;
                 Rectangle hBounds(_scrollBarBounds.x,
                 Rectangle hBounds(_scrollBarBounds.x,
-                                  _viewportBounds.y + _viewportBounds.height - hHeight,
+                                  _viewportBounds.y + _viewportBounds.height,
                                   _scrollBarBounds.width, hHeight);
                                   _scrollBarBounds.width, hHeight);
             
             
                 if (y + _viewportBounds.y >= hBounds.y &&
                 if (y + _viewportBounds.y >= hBounds.y &&

+ 1 - 0
gameplay/src/Container.h

@@ -632,6 +632,7 @@ private:
     bool _contactIndices[MAX_CONTACT_INDICES];
     bool _contactIndices[MAX_CONTACT_INDICES];
     bool _initializedWithScroll;
     bool _initializedWithScroll;
     bool _scrollWheelRequiresFocus;
     bool _scrollWheelRequiresFocus;
+    bool _allowRelayout;
 };
 };
 
 
 }
 }

+ 287 - 121
gameplay/src/Control.cpp

@@ -2,12 +2,50 @@
 #include "Game.h"
 #include "Game.h"
 #include "Control.h"
 #include "Control.h"
 
 
+#define BOUNDS_X_PERCENTAGE_BIT 1
+#define BOUNDS_Y_PERCENTAGE_BIT 2
+#define BOUNDS_WIDTH_PERCENTAGE_BIT 4
+#define BOUNDS_HEIGHT_PERCENTAGE_BIT 8
+
 namespace gameplay
 namespace gameplay
 {
 {
 
 
+static std::string toString(float v)
+{
+    std::ostringstream s;
+    s << v;
+    return s.str();
+}
+
+static float parseCoord(const char* s, bool* isPercentage)
+{
+    const char* p;
+    if ((p = strchr(s, '%')) != NULL)
+    {
+        std::string value(s, (std::string::size_type)(p - s));
+        *isPercentage = true;
+        return (float)(atof(value.c_str()) * 0.01);
+    }
+    *isPercentage = false;
+    return (float)atof(s);
+}
+
+static bool parseCoordPair(const char* s, float* v1, float* v2, bool* v1Percentage, bool* v2Percentage)
+{
+    size_t len = strlen(s);
+    const char* s2 = strchr(s, ',');
+    if (s2 == NULL)
+        return false;
+    std::string v1Str(s, (std::string::size_type)(s2 - s));
+    std::string v2Str(s2 + 1);
+    *v1 = parseCoord(v1Str.c_str(), v1Percentage);
+    *v2 = parseCoord(v2Str.c_str(), v2Percentage);
+    return true;
+}
+
 Control::Control()
 Control::Control()
-    : _id(""), _state(Control::NORMAL), _bounds(Rectangle::empty()), _clipBounds(Rectangle::empty()), _viewportClipBounds(Rectangle::empty()),
-    _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(false), _alignment(ALIGN_TOP_LEFT), _isAlignmentSet(false), _autoWidth(false), _autoHeight(false), _listeners(NULL), _visible(true),
+    : _id(""), _state(Control::NORMAL), _boundsBits(0), _dirty(true), _consumeInputEvents(false),
+    _alignment(ALIGN_TOP_LEFT), _isAlignmentSet(false), _autoWidth(AUTO_SIZE_NONE), _autoHeight(AUTO_SIZE_NONE), _listeners(NULL), _visible(true),
     _zIndex(-1), _contactIndex(INVALID_CONTACT_INDEX), _focusIndex(-1), _parent(NULL), _styleOverridden(false), _skin(NULL), _previousState(NORMAL)
     _zIndex(-1), _contactIndex(INVALID_CONTACT_INDEX), _focusIndex(-1), _parent(NULL), _styleOverridden(false), _skin(NULL), _previousState(NORMAL)
 {
 {
     addScriptEvent("controlEvent", "<Control>[Control::Listener::EventType]");
     addScriptEvent("controlEvent", "<Control>[Control::Listener::EventType]");
@@ -31,6 +69,17 @@ Control::~Control()
     }
     }
 }
 }
 
 
+static Control::AutoSize parseAutoSize(const char* str)
+{
+    if (str == NULL)
+        return Control::AUTO_SIZE_NONE;
+    if (strcmp(str, "AUTO_SIZE_STRETCH") == 0 || strcmp(str, "true") == 0) // left for backwards compatibility
+        return Control::AUTO_SIZE_STRETCH;
+    if (strcmp(str, "AUTO_SIZE_FIT") == 0)
+        return Control::AUTO_SIZE_FIT;
+    return Control::AUTO_SIZE_NONE;
+}
+
 void Control::initialize(Theme::Style* style, Properties* properties)
 void Control::initialize(Theme::Style* style, Properties* properties)
 {
 {
     GP_ASSERT(properties);
     GP_ASSERT(properties);
@@ -41,8 +90,9 @@ void Control::initialize(Theme::Style* style, Properties* properties)
 
 
     _isAlignmentSet = alignmentString != NULL;
     _isAlignmentSet = alignmentString != NULL;
     _alignment = getAlignment(alignmentString);
     _alignment = getAlignment(alignmentString);
-    _autoWidth = properties->getBool("autoWidth");
-    _autoHeight = properties->getBool("autoHeight");
+
+    _autoWidth = parseAutoSize(properties->getString("autoWidth"));
+    _autoHeight = parseAutoSize(properties->getString("autoHeight"));
 
 
     _consumeInputEvents = properties->getBool("consumeInputEvents", false);
     _consumeInputEvents = properties->getBool("consumeInputEvents", false);
 
 
@@ -66,28 +116,31 @@ void Control::initialize(Theme::Style* style, Properties* properties)
         _focusIndex = -1;
         _focusIndex = -1;
     }
     }
 
 
-    Vector2 position;
-    Vector2 size;
+    float bounds[4];
+    bool boundsBits[4];
     if (properties->exists("position"))
     if (properties->exists("position"))
     {
     {
-        properties->getVector2("position", &position);
+        parseCoordPair(properties->getString("position", "0,0"), &bounds[0], &bounds[1], &boundsBits[0], &boundsBits[1]);
     }
     }
     else
     else
     {
     {
-        position.x = properties->getFloat("x");
-        position.y = properties->getFloat("y");
+        bounds[0] = parseCoord(properties->getString("x", "0"), &boundsBits[0]);
+        bounds[1] = parseCoord(properties->getString("y", "0"), &boundsBits[1]);
     }
     }
-        
+
     if (properties->exists("size"))
     if (properties->exists("size"))
     {
     {
-        properties->getVector2("size", &size);
+        parseCoordPair(properties->getString("size", "0,0"), &bounds[2], &bounds[3], &boundsBits[2], &boundsBits[3]);
     }
     }
     else
     else
     {
     {
-        size.x = properties->getFloat("width");
-        size.y = properties->getFloat("height");
+        bounds[2] = parseCoord(properties->getString("width", "0"), &boundsBits[2]);
+        bounds[3] = parseCoord(properties->getString("height", "0"), &boundsBits[3]);
     }
     }
-    setBounds(Rectangle(position.x, position.y, size.x, size.y));
+    setX(bounds[0], boundsBits[0]);
+    setY(bounds[1], boundsBits[1]);
+    setWidth(bounds[2], boundsBits[2]);
+    setHeight(bounds[3], boundsBits[3]);
 
 
     const char* id = properties->getId();
     const char* id = properties->getId();
     if (id)
     if (id)
@@ -98,6 +151,10 @@ void Control::initialize(Theme::Style* style, Properties* properties)
         setEnabled(properties->getBool("enabled"));
         setEnabled(properties->getBool("enabled"));
     }
     }
 
 
+    // Register script listeners for control events
+    if (properties->exists("listener"))
+        addScriptCallback("controlEvent", properties->getString("listener"));
+
     // Potentially override themed properties for all states.
     // Potentially override themed properties for all states.
     overrideThemedProperties(properties, STATE_ALL);
     overrideThemedProperties(properties, STATE_ALL);
 
 
@@ -147,81 +204,156 @@ const char* Control::getId() const
     return _id.c_str();
     return _id.c_str();
 }
 }
 
 
-void Control::setPosition(float x, float y)
+float Control::getX() const
 {
 {
-    if (x != _bounds.x || y != _bounds.y)
-    {
-        _bounds.x = x;
-        _bounds.y = y;
-        _dirty = true;
-    }
+    return _bounds.x;
 }
 }
 
 
-void Control::setSize(float width, float height)
+void Control::setX(float x, bool percentage)
 {
 {
-    if (width != _bounds.width || height != _bounds.height)
+    if (_relativeBounds.x != x || percentage != ((_boundsBits & BOUNDS_X_PERCENTAGE_BIT) != 0))
     {
     {
-        _bounds.width = width;
-        _bounds.height = height;
+        _relativeBounds.x = x;
+        if (percentage)
+        {
+            _boundsBits |= BOUNDS_X_PERCENTAGE_BIT;
+        }
+        else
+        {
+            _boundsBits &= ~BOUNDS_X_PERCENTAGE_BIT;
+            _bounds.x = x;
+        }
         _dirty = true;
         _dirty = true;
     }
     }
 }
 }
 
 
-void Control::setWidth(float width)
+bool Control::isXPercentage() const
 {
 {
-    if (width != _bounds.width)
+    return (_boundsBits & BOUNDS_X_PERCENTAGE_BIT) != 0;
+}
+
+float Control::getY() const
+{
+    return _bounds.y;
+}
+
+void Control::setY(float y, bool percentage)
+{
+    if (_relativeBounds.y != y || percentage != ((_boundsBits & BOUNDS_Y_PERCENTAGE_BIT) != 0))
     {
     {
-        _bounds.width = width;
+        _relativeBounds.y = y;
+        if (percentage)
+        {
+            _boundsBits |= BOUNDS_Y_PERCENTAGE_BIT;
+        }
+        else
+        {
+            _boundsBits &= ~BOUNDS_Y_PERCENTAGE_BIT;
+            _bounds.y = y;
+        }
         _dirty = true;
         _dirty = true;
     }
     }
 }
 }
 
 
-void Control::setHeight(float height)
+bool Control::isYPercentage() const
+{
+    return (_boundsBits & BOUNDS_Y_PERCENTAGE_BIT) != 0;
+}
+
+float Control::getWidth() const
+{
+    return _bounds.width;
+}
+
+void Control::setWidth(float width, bool percentage)
 {
 {
-    if (height != _bounds.height)
+    if (_relativeBounds.width != width || percentage != ((_boundsBits & BOUNDS_WIDTH_PERCENTAGE_BIT) != 0))
     {
     {
-        _bounds.height = height;
+        _relativeBounds.width = width;
+        if (percentage)
+        {
+            _boundsBits |= BOUNDS_WIDTH_PERCENTAGE_BIT;
+        }
+        else
+        {
+            _boundsBits &= ~BOUNDS_WIDTH_PERCENTAGE_BIT;
+            _bounds.width = width;
+        }
         _dirty = true;
         _dirty = true;
     }
     }
 }
 }
 
 
-void Control::setBounds(const Rectangle& bounds)
+bool Control::isWidthPercentage() const
 {
 {
-    if (bounds != _bounds)
+    return (_boundsBits & BOUNDS_WIDTH_PERCENTAGE_BIT) != 0;
+}
+
+float Control::getHeight() const
+{
+    return _bounds.height;
+}
+
+void Control::setHeight(float height, bool percentage)
+{
+    if (_relativeBounds.height != height || percentage != ((_boundsBits & BOUNDS_HEIGHT_PERCENTAGE_BIT) != 0))
     {
     {
-        _bounds.set(bounds);
+        _relativeBounds.height = height;
+        if (percentage)
+        {
+            _boundsBits |= BOUNDS_HEIGHT_PERCENTAGE_BIT;
+        }
+        else
+        {
+            _boundsBits &= ~BOUNDS_HEIGHT_PERCENTAGE_BIT;
+            _bounds.height = height;
+        }
         _dirty = true;
         _dirty = true;
     }
     }
 }
 }
 
 
-const Rectangle& Control::getBounds() const
+bool Control::isHeightPercentage() const
 {
 {
-    return _bounds;
+    return (_boundsBits & BOUNDS_HEIGHT_PERCENTAGE_BIT) != 0;
 }
 }
 
 
-const Rectangle& Control::getAbsoluteBounds() const
+void Control::setPosition(float x, float y)
 {
 {
-    return _absoluteBounds;
+    setX(x);
+    setY(y);
 }
 }
 
 
-float Control::getX() const
+void Control::setSize(float width, float height)
 {
 {
-    return _bounds.x;
+    setWidth(width);
+    setHeight(height);
 }
 }
 
 
-float Control::getY() const
+const Rectangle& Control::getBounds() const
 {
 {
-    return _bounds.y;
+    return _bounds;
 }
 }
 
 
-float Control::getWidth() const
+void Control::setBounds(const Rectangle& bounds)
 {
 {
-    return _bounds.width;
+    setX(bounds.x);
+    setY(bounds.y);
+    setWidth(bounds.width);
+    setHeight(bounds.height);
 }
 }
 
 
-float Control::getHeight() const
+const Rectangle& Control::getAbsoluteBounds() const
 {
 {
-    return _bounds.height;
+    return _absoluteBounds;
+}
+
+const Rectangle& Control::getClipBounds() const
+{
+    return _clipBounds;
+}
+
+const Rectangle& Control::getClip() const
+{
+    return _viewportClipBounds;
 }
 }
 
 
 void Control::setAlignment(Alignment alignment)
 void Control::setAlignment(Alignment alignment)
@@ -236,32 +368,42 @@ Control::Alignment Control::getAlignment() const
     return _alignment;
     return _alignment;
 }
 }
 
 
+Control::AutoSize Control::getAutoWidth() const
+{
+    return _autoWidth;
+}
+
 void Control::setAutoWidth(bool autoWidth)
 void Control::setAutoWidth(bool autoWidth)
 {
 {
-    if (_autoWidth != autoWidth)
+    setAutoWidth(autoWidth ? AUTO_SIZE_STRETCH : AUTO_SIZE_NONE);
+}
+
+void Control::setAutoWidth(AutoSize mode)
+{
+    if (_autoWidth != mode)
     {
     {
-        _autoWidth = autoWidth;
+        _autoWidth = mode;
         _dirty = true;
         _dirty = true;
     }
     }
 }
 }
 
 
-bool Control::getAutoWidth() const
+Control::AutoSize Control::getAutoHeight() const
 {
 {
-    return _autoWidth;
+    return _autoHeight;
 }
 }
 
 
 void Control::setAutoHeight(bool autoHeight)
 void Control::setAutoHeight(bool autoHeight)
 {
 {
-    if (_autoHeight != autoHeight)
-    {
-        _autoHeight = autoHeight;
-        _dirty = true;
-    }
+    setAutoHeight(autoHeight ? AUTO_SIZE_STRETCH : AUTO_SIZE_NONE);
 }
 }
 
 
-bool Control::getAutoHeight() const
+void Control::setAutoHeight(AutoSize mode)
 {
 {
-    return _autoHeight;
+    if (_autoHeight != mode)
+    {
+        _autoHeight = mode;
+        _dirty = true;
+    }
 }
 }
 
 
 void Control::setVisible(bool visible)
 void Control::setVisible(bool visible)
@@ -633,16 +775,6 @@ bool Control::getTextRightToLeft(State state) const
     return overlay->getTextRightToLeft();
     return overlay->getTextRightToLeft();
 }
 }
 
 
-const Rectangle& Control::getClipBounds() const
-{
-    return _clipBounds;
-}
-
-const Rectangle& Control::getClip() const
-{
-    return _viewportClipBounds;
-}
-
 void Control::setStyle(Theme::Style* style)
 void Control::setStyle(Theme::Style* style)
 {
 {
     if (style != _style)
     if (style != _style)
@@ -956,24 +1088,51 @@ void Control::notifyListeners(Control::Listener::EventType eventType)
 
 
 void Control::update(const Control* container, const Vector2& offset)
 void Control::update(const Control* container, const Vector2& offset)
 {
 {
-    const Rectangle& clip = container->getClip();
-    const Rectangle& absoluteViewport = container->_viewportBounds;
+    Game* game = Game::getInstance();
+    const Rectangle parentAbsoluteBounds = container ? container->_viewportBounds : Rectangle(0, 0, game->getViewport().width, game->getViewport().height);
+    const Rectangle parentAbsoluteClip = container ? container->getClip() : parentAbsoluteBounds;
 
 
+    // Store previous absolute clip bounds
     _clearBounds.set(_absoluteClipBounds);
     _clearBounds.set(_absoluteClipBounds);
 
 
-    // Calculate the clipped bounds.
-    float x = _bounds.x + offset.x;
-    float y = _bounds.y + offset.y;
-    float width = _bounds.width;
-    float height = _bounds.height;
-
-    float clipX2 = clip.x + clip.width;
-    float x2 = clip.x + x + width;
+    // Calculate local un-clipped bounds.
+    _bounds.set(_relativeBounds);
+    if (isXPercentage())
+        _bounds.x *= parentAbsoluteBounds.width;
+    if (isYPercentage())
+        _bounds.y *= parentAbsoluteBounds.height;
+    if (_autoWidth == AUTO_SIZE_STRETCH)
+        _bounds.width = parentAbsoluteBounds.width;
+    else if (isWidthPercentage())
+        _bounds.width *= parentAbsoluteBounds.width;
+    if (_autoHeight == AUTO_SIZE_STRETCH)
+        _bounds.height = parentAbsoluteBounds.height;
+    else if (isHeightPercentage())
+        _bounds.height *= parentAbsoluteBounds.height;
+
+    float x, y, width, height, clipX2, x2, clipY2, y2;
+
+    // Calculate the local clipped bounds
+    width = _bounds.width;
+    height = _bounds.height;
+    if (container)
+    {
+        x = _bounds.x + offset.x;
+        y = _bounds.y + offset.y;
+        x2 = parentAbsoluteClip.x + x + width;
+        y2 = parentAbsoluteClip.y + y + height;
+    }
+    else
+    {
+        x = 0;
+        y = 0;
+        x2 = width;
+        y2 = height;
+    }
+    clipX2 = parentAbsoluteClip.x + parentAbsoluteClip.width;
+    clipY2 = parentAbsoluteClip.y + parentAbsoluteClip.height;
     if (x2 > clipX2)
     if (x2 > clipX2)
         width -= x2 - clipX2;
         width -= x2 - clipX2;
-
-    float clipY2 = clip.y + clip.height;
-    float y2 = clip.y + y + height;
     if (y2 > clipY2)
     if (y2 > clipY2)
         height -= y2 - clipY2;
         height -= y2 - clipY2;
 
 
@@ -999,50 +1158,63 @@ void Control::update(const Control* container, const Vector2& offset)
 
 
     _clipBounds.set(x, y, width, height);
     _clipBounds.set(x, y, width, height);
 
 
-    // Calculate the absolute bounds.
-    x = _bounds.x + offset.x + absoluteViewport.x;
-    y = _bounds.y + offset.y + absoluteViewport.y;
+    // Calculate absolute bounds un-clipped bounds
+    if (container)
+    {
+        x = _bounds.x + offset.x + parentAbsoluteBounds.x;
+        y = _bounds.y + offset.y + parentAbsoluteBounds.y;
+    }
+    else
+    {
+        x = 0;
+        y = 0;
+    }
     _absoluteBounds.set(x, y, _bounds.width, _bounds.height);
     _absoluteBounds.set(x, y, _bounds.width, _bounds.height);
 
 
-    // Calculate the absolute viewport bounds.
+    // Calculate the absolute viewport bounds (content area, which does not include border and padding)
     // Absolute bounds minus border and padding.
     // Absolute bounds minus border and padding.
     const Theme::Border& border = getBorder(_state);
     const Theme::Border& border = getBorder(_state);
     const Theme::Padding& padding = getPadding();
     const Theme::Padding& padding = getPadding();
-
     x += border.left + padding.left;
     x += border.left + padding.left;
     y += border.top + padding.top;
     y += border.top + padding.top;
     width = _bounds.width - border.left - padding.left - border.right - padding.right;
     width = _bounds.width - border.left - padding.left - border.right - padding.right;
     height = _bounds.height - border.top - padding.top - border.bottom - padding.bottom;
     height = _bounds.height - border.top - padding.top - border.bottom - padding.bottom;
-
     _viewportBounds.set(x, y, width, height);
     _viewportBounds.set(x, y, width, height);
 
 
     // Calculate the clip area.
     // Calculate the clip area.
     // Absolute bounds, minus border and padding,
     // Absolute bounds, minus border and padding,
     // clipped to the parent container's clip area.
     // clipped to the parent container's clip area.
-    clipX2 = clip.x + clip.width;
+    if (container)
+    {
+        clipX2 = parentAbsoluteClip.x + parentAbsoluteClip.width;
+        clipY2 = parentAbsoluteClip.y + parentAbsoluteClip.height;
+    }
+    else
+    {
+        clipX2 = parentAbsoluteClip.width;
+        clipY2 = parentAbsoluteClip.height;
+    }
     x2 = x + width;
     x2 = x + width;
     if (x2 > clipX2)
     if (x2 > clipX2)
         width = clipX2 - x;
         width = clipX2 - x;
-
-    clipY2 = clip.y + clip.height;
     y2 = y + height;
     y2 = y + height;
     if (y2 > clipY2)
     if (y2 > clipY2)
         height = clipY2 - y;
         height = clipY2 - y;
 
 
-    if (x < clip.x)
+    if (x < parentAbsoluteClip.x)
     {
     {
-        float dx = clip.x - x;
+        float dx = parentAbsoluteClip.x - x;
         width -= dx;
         width -= dx;
-        x = clip.x;
+        x = parentAbsoluteClip.x;
     }
     }
 
 
-    if (y < clip.y)
+    if (y < parentAbsoluteClip.y)
     {
     {
-        float dy = clip.y - y;
+        float dy = parentAbsoluteClip.y - y;
         height -= dy;
         height -= dy;
-        y = clip.y;
+        y = parentAbsoluteClip.y;
     }
     }
- 
+
     _viewportClipBounds.set(x, y, width, height);
     _viewportClipBounds.set(x, y, width, height);
 
 
     width += border.left + padding.left + border.right + padding.right;
     width += border.left + padding.left + border.right + padding.right;
@@ -1057,12 +1229,14 @@ void Control::update(const Control* container, const Vector2& offset)
     _skin = getSkin(_state);
     _skin = getSkin(_state);
 
 
     // Current opacity should be multiplied by that of the parent container.
     // Current opacity should be multiplied by that of the parent container.
-    _opacity = getOpacity(_state) * container->_opacity;
+    _opacity = getOpacity(_state);
+    if (container)
+        _opacity *= container->_opacity;
 }
 }
 
 
 void Control::drawBorder(SpriteBatch* spriteBatch, const Rectangle& clip)
 void Control::drawBorder(SpriteBatch* spriteBatch, const Rectangle& clip)
 {
 {
-    if (!spriteBatch || !_skin || _bounds.width <= 0 || _bounds.height <= 0)
+    if (!spriteBatch || !_skin || _absoluteBounds.width <= 0 || _absoluteBounds.height <= 0)
         return;
         return;
 
 
     // Get the border and background images for this control's current state.
     // Get the border and background images for this control's current state.
@@ -1082,18 +1256,18 @@ void Control::drawBorder(SpriteBatch* spriteBatch, const Rectangle& clip)
     Vector4 skinColor = _skin->getColor();
     Vector4 skinColor = _skin->getColor();
     skinColor.w *= _opacity;
     skinColor.w *= _opacity;
 
 
-    float midWidth = _bounds.width - border.left - border.right;
-    float midHeight = _bounds.height - border.top - border.bottom;
+    float midWidth = _absoluteBounds.width - border.left - border.right;
+    float midHeight = _absoluteBounds.height - border.top - border.bottom;
     float midX = _absoluteBounds.x + border.left;
     float midX = _absoluteBounds.x + border.left;
     float midY = _absoluteBounds.y + border.top;
     float midY = _absoluteBounds.y + border.top;
-    float rightX = _absoluteBounds.x + _bounds.width - border.right;
-    float bottomY = _absoluteBounds.y + _bounds.height - border.bottom;
+    float rightX = _absoluteBounds.x + _absoluteBounds.width - border.right;
+    float bottomY = _absoluteBounds.y + _absoluteBounds.height - border.bottom;
 
 
     // Draw themed border sprites.
     // Draw themed border sprites.
     if (!border.left && !border.right && !border.top && !border.bottom)
     if (!border.left && !border.right && !border.top && !border.bottom)
     {
     {
         // No border, just draw the image.
         // No border, just draw the image.
-        spriteBatch->draw(_absoluteBounds.x, _absoluteBounds.y, _bounds.width, _bounds.height, center.u1, center.v1, center.u2, center.v2, skinColor, clip);
+        spriteBatch->draw(_absoluteBounds.x, _absoluteBounds.y, _absoluteBounds.width, _absoluteBounds.height, center.u1, center.v1, center.u2, center.v2, skinColor, clip);
     }
     }
     else
     else
     {
     {
@@ -1107,7 +1281,7 @@ void Control::drawBorder(SpriteBatch* spriteBatch, const Rectangle& clip)
             spriteBatch->draw(_absoluteBounds.x, midY, border.left, midHeight, left.u1, left.v1, left.u2, left.v2, skinColor, clip);
             spriteBatch->draw(_absoluteBounds.x, midY, border.left, midHeight, left.u1, left.v1, left.u2, left.v2, skinColor, clip);
 
 
         // Always draw the background.
         // Always draw the background.
-        spriteBatch->draw(_absoluteBounds.x + border.left, _absoluteBounds.y + border.top, _bounds.width - border.left - border.right, _bounds.height - border.top - border.bottom,
+        spriteBatch->draw(_absoluteBounds.x + border.left, _absoluteBounds.y + border.top, _absoluteBounds.width - border.left - border.right, _absoluteBounds.height - border.top - border.bottom,
             center.u1, center.v1, center.u2, center.v2, skinColor, clip);
             center.u1, center.v1, center.u2, center.v2, skinColor, clip);
 
 
         if (border.right)
         if (border.right)
@@ -1237,7 +1411,7 @@ void Control::getAnimationPropertyValue(int propertyId, AnimationValue* value)
 {
 {
     GP_ASSERT(value);
     GP_ASSERT(value);
 
 
-    switch(propertyId)
+    switch (propertyId)
     {
     {
     case ANIMATE_POSITION:
     case ANIMATE_POSITION:
         value->setFloat(0, _bounds.x);
         value->setFloat(0, _bounds.x);
@@ -1274,38 +1448,30 @@ void Control::setAnimationPropertyValue(int propertyId, AnimationValue* value, f
     switch(propertyId)
     switch(propertyId)
     {
     {
     case ANIMATE_POSITION:
     case ANIMATE_POSITION:
-        _bounds.x = Curve::lerp(blendWeight, _bounds.x, value->getFloat(0));
-        _bounds.y = Curve::lerp(blendWeight, _bounds.y, value->getFloat(1));
-        _dirty = true;
+        setX(Curve::lerp(blendWeight, _bounds.x, value->getFloat(0)), isXPercentage());
+        setY(Curve::lerp(blendWeight, _bounds.y, value->getFloat(1)), isYPercentage());
         break;
         break;
     case ANIMATE_POSITION_X:
     case ANIMATE_POSITION_X:
-        _bounds.x = Curve::lerp(blendWeight, _bounds.x, value->getFloat(0));
-        _dirty = true;
+        setX(Curve::lerp(blendWeight, _bounds.x, value->getFloat(0)), isXPercentage());
         break;
         break;
     case ANIMATE_POSITION_Y:
     case ANIMATE_POSITION_Y:
-        _bounds.y = Curve::lerp(blendWeight, _bounds.y, value->getFloat(0));
-        _dirty = true;
+        setY(Curve::lerp(blendWeight, _bounds.y, value->getFloat(0)), isYPercentage());
         break;
         break;
     case ANIMATE_SIZE:
     case ANIMATE_SIZE:
-        _bounds.width = Curve::lerp(blendWeight, _bounds.width, value->getFloat(0));
-        _bounds.height = Curve::lerp(blendWeight, _bounds.height, value->getFloat(1));
-        _dirty = true;
+        setWidth(Curve::lerp(blendWeight, _bounds.width, value->getFloat(0)), isWidthPercentage());
+        setHeight(Curve::lerp(blendWeight, _bounds.height, value->getFloat(1)), isHeightPercentage());
         break;
         break;
     case ANIMATE_SIZE_WIDTH:
     case ANIMATE_SIZE_WIDTH:
-        _bounds.width = Curve::lerp(blendWeight, _bounds.width, value->getFloat(0));
-        _dirty = true;
+        setWidth(Curve::lerp(blendWeight, _bounds.width, value->getFloat(0)), isWidthPercentage());
         break;
         break;
     case ANIMATE_SIZE_HEIGHT:
     case ANIMATE_SIZE_HEIGHT:
-        _bounds.height = Curve::lerp(blendWeight, _bounds.height, value->getFloat(0));
-        _dirty = true;
+        setHeight(Curve::lerp(blendWeight, _bounds.height, value->getFloat(0)), isHeightPercentage());
         break;
         break;
     case ANIMATE_OPACITY:
     case ANIMATE_OPACITY:
         setOpacity(Curve::lerp(blendWeight, _opacity, value->getFloat(0)));
         setOpacity(Curve::lerp(blendWeight, _opacity, value->getFloat(0)));
-        _dirty = true;
         break;
         break;
     }
     }
 }
 }
-    
 
 
 Theme::Style::Overlay** Control::getOverlays(unsigned char overlayTypes, Theme::Style::Overlay** overlays)
 Theme::Style::Overlay** Control::getOverlays(unsigned char overlayTypes, Theme::Style::Overlay** overlays)
 {
 {

+ 193 - 67
gameplay/src/Control.h

@@ -91,6 +91,29 @@ public:
         ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT
         ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT
     };
     };
 
 
+    /**
+     * Defines supported auto sizing modes for controls.
+     */
+    enum AutoSize
+    {
+        /**
+         * No auto sizing is applied.
+         */
+        AUTO_SIZE_NONE = 0x00,
+
+        /**
+         * The control's size is stretched to fill the content area of its parent container.
+         */
+        AUTO_SIZE_STRETCH = 0x01,
+
+        /**
+         * The control's size is set to tightly fit its contents.
+         *
+         * Not all controls support this auto sizing mode.
+         */
+        AUTO_SIZE_FIT = 0x02
+    };
+
     /**
     /**
      * Implement Control::Listener and call Control::addListener()
      * Implement Control::Listener and call Control::addListener()
      * in order to listen for events on controls.
      * in order to listen for events on controls.
@@ -215,42 +238,128 @@ public:
     const char* getId() const;
     const char* getId() const;
 
 
     /**
     /**
-     * Set the position of this control relative to its parent container.
+     * Get the x coordinate of this control.
      *
      *
-     * @param x The x coordinate.
-     * @param y The y coordinate.
+     * @return The x coordinate of this control.
      */
      */
-    void setPosition(float x, float y);
+    float getX() const;
 
 
     /**
     /**
-     * Set the desired size of this control, including its border and padding, before clipping.
+     * Sets the X coordinate for the control.
      *
      *
-     * @param width The width.
-     * @param height The height.
+     * If the value is passed as a percentage of its parent container's clip region, it is interpreted as a value
+     * between 0-1, where 1 equals the full size of it's parent.
+     *
+     * @param x The new X coordinate.
+     * @param percentage True if the value should be interpreted as a percentage (0-1), false if it is regular number.
      */
      */
-    virtual void setSize(float width, float height);
+    void setX(float x, bool percentage = false);
 
 
-    /** 
+    /**
+     * Determines if the X coordinate of this control computed as a percentage of its parent container.
+     *
+     * @return True if the X value is computed as a percentage of its parent container.
+     */
+    bool isXPercentage() const;
+
+    /**
+     * Get the y coordinate of this control.
+     *
+     * @return The y coordinate of this control.
+     */
+    float getY() const;
+
+    /**
+     * Sets the Y coordinate for the control.
+     *
+     * If the value is passed as a percentage of its parent container's clip region, it is interpreted as a value
+     * between 0-1, where 1 equals the full size of it's parent.
+     *
+     * @param y The new Y coordinate.
+     * @param percentage True if the value should be interpreted as a percentage (0-1), false if it is regular number.
+     */
+    void setY(float y, bool percentage = false);
+
+    /**
+     * Determines if the Y coordinate of this control is computed as a percentage of its parent container.
+     *
+     * @return True if the Y value is computed as a percentage of its parent container.
+     */
+    bool isYPercentage() const;
+
+    /**
+     * Get the width of this control.
+     *
+     * @return The width of this control.
+     */
+    float getWidth() const;
+
+    /**
      * Set the desired width of the control, including it's border and padding, before clipping.
      * Set the desired width of the control, including it's border and padding, before clipping.
      *
      *
+     * If the value is passed as a percentage of its parent container's clip region, it is interpreted as a value
+     * between 0-1, where 1 equals the full size of it's parent.
+     *
      * @param width The width.
      * @param width The width.
+     * @param percentage True if the value should be interpreted as a percentage (0-1), false if it is regular number.
      */
      */
-    virtual void setWidth(float width);
+    void setWidth(float width, bool percentage = false);
 
 
-    /** 
+    /**
+     * Determines if the width of this control is computed as a percentage of its parent container.
+     *
+     * @return True if the width is computed as a percentage of its parent container.
+     */
+    bool isWidthPercentage() const;
+
+    /**
+     * Get the height of this control.
+     *
+     * @return The height of this control.
+     */
+    float getHeight() const;
+
+    /**
      * Set the desired height of the control, including it's border and padding, before clipping.
      * Set the desired height of the control, including it's border and padding, before clipping.
      *
      *
+     * If the value is passed as a percentage of its parent container's clip region, it is interpreted as a value
+     * between 0-1, where 1 equals the full size of it's parent.
+     *
      * @param height The height.
      * @param height The height.
+     * @param percentage True if the value should be interpreted as a percentage (0-1), false if it is regular number.
      */
      */
-    virtual void setHeight(float height);
+    void setHeight(float height, bool percentage = false);
 
 
     /**
     /**
-     * Set the bounds of this control, relative to its parent container and including its
-     * border and padding, before clipping.
+     * Determines if the height of this control is computed as a percentage of its parent container.
      *
      *
-     * @param bounds The new bounds to set.
+     * @return True if the height is computed as a percentage of its parent container.
      */
      */
-    virtual void setBounds(const Rectangle& bounds);
+    bool isHeightPercentage() const;
+
+    /**
+     * Set the position of this control relative to its parent container.
+     *
+     * This method sets the local position of the control, relative to its container.
+     * Setting percetage values is not supported with this method, use setX
+     * and setY instead.
+     *
+     * @param x The x coordinate.
+     * @param y The y coordinate.
+     */
+    void setPosition(float x, float y);
+
+    /**
+     * Set the desired size of this control, including its border and padding, before clipping.
+     *
+     * This method sets the size of the control, relative to its container.
+     * Setting percetage values is not supported with this method, use setWidth
+     * and setHeight instead.
+     *
+     * @param width The width.
+     * @param height The height.
+     */
+    void setSize(float width, float height);
 
 
     /**
     /**
      * Get the bounds of this control, relative to its parent container and including its
      * Get the bounds of this control, relative to its parent container and including its
@@ -260,85 +369,106 @@ public:
      */
      */
     const Rectangle& getBounds() const;
     const Rectangle& getBounds() const;
 
 
+    /**
+     * Set the bounds of this control, relative to its parent container and including its
+     * border and padding, before clipping.
+     *
+     * This method sets the local bounds of the control, relative to its container.
+     * Setting percetage values is not supported with this method, use setX,
+     * setY, setWidth and setHeight instead.
+     *
+     * @param bounds The new bounds to set.
+     */
+    void setBounds(const Rectangle& bounds);
+
     /**
     /**
      * Get the absolute bounds of this control, in pixels, including border and padding,
      * Get the absolute bounds of this control, in pixels, including border and padding,
      * before clipping.
      * before clipping.
      *
      *
+     * The absolute bounds of a control represents its final computed bounds after all 
+     * alignment, auto sizing, relative position and sizing has been computed. The
+     * returned bounds is in absolute coordinates, relative to the control's top-most
+     * parent container (usually its form).
+     *
      * @return The absolute bounds of this control.
      * @return The absolute bounds of this control.
      */
      */
     const Rectangle& getAbsoluteBounds() const;
     const Rectangle& getAbsoluteBounds() const;
 
 
     /**
     /**
-     * Get the x coordinate of this control's bounds.
+     * Get the bounds of this control, relative to its parent container, after clipping.
      *
      *
-     * @return The x coordinate of this control's bounds.
+     * @return The bounds of this control.
      */
      */
-    float getX() const;
-    
+    const Rectangle& getClipBounds() const;
+
     /**
     /**
-     * Get the y coordinate of this control's bounds.
+     * Get the content area of this control, in screen coordinates, after clipping.
      *
      *
-     * @return The y coordinate of this control's bounds.
+     * @return The clipping area of this control.
      */
      */
-    float getY() const;
+    const Rectangle& getClip() const;
 
 
     /**
     /**
-     * Get the width of this control's bounds.
+     * Returns the auto sizing mode for this control's width.
      *
      *
-     * @return The width of this control's bounds.
+     * @return The auto size mode for this control's width.
      */
      */
-    float getWidth() const;
+    AutoSize getAutoWidth() const;
 
 
     /**
     /**
-     * Get the height of this control's bounds.
+     * Enables or disables auto sizing for this control's width.
      *
      *
-     * @return The height of this control's bounds.
+     * This method is a simplified version of setAutoWidth(AutoSize) left intact for legacy reasons.
+     * It enables or disables the AUTO_SIZE_STRETCH mode for the control's width.
+     *
+     * @param autoWidth True to enable AUTO_SIZE_STRETCH for this control's width.
      */
      */
-    float getHeight() const;
+    void setAutoWidth(bool autoWidth);
 
 
     /**
     /**
-     * Set the alignment of this control within its parent container.
+     * Sets the auto size mode for this control's width.
      *
      *
-     * @param alignment This control's alignment.
+     * @param mode The new auto size mode for this control's width.
      */
      */
-    void setAlignment(Alignment alignment);
+    void setAutoWidth(AutoSize mode);
 
 
     /**
     /**
-     * Get the alignment of this control within its parent container.
+     * Returns the auto sizing mode for this control's height.
      *
      *
-     * @return The alignment of this control within its parent container.
+     * @return The auto size mode for this control's height.
      */
      */
-    Alignment getAlignment() const;
+    AutoSize getAutoHeight() const;
 
 
     /**
     /**
-     * Set this control to fit horizontally within its parent container.
+     * Enables or disables auto sizing for this control's height.
+     *
+     * This method is a simplified version of setAutoHeight(AutoSize) left intact for legacy reasons.
+     * It enables or disables the AUTO_SIZE_STRETCH mode for the control's height.
      *
      *
-     * @param autoWidth Whether to size this control to fit horizontally within its parent container.
+     * @param autoWidth True to enable AUTO_SIZE_STRETCH for this control's height.
      */
      */
-    virtual void setAutoWidth(bool autoWidth);
+    void setAutoHeight(bool autoHeight);
 
 
     /**
     /**
-     * Get whether this control's width is set to automatically adjust to
-     * fit horizontally within its parent container.
+     * Sets the auto size mode for this control's height.
      *
      *
-     * @return Whether this control's width is set to automatically adjust.
+     * @param mode The new auto size mode for this control's height.
      */
      */
-    bool getAutoWidth() const;
+    void setAutoHeight(AutoSize mode);
 
 
     /**
     /**
-     * Set this control to fit vertically within its parent container.
+     * Set the alignment of this control within its parent container.
      *
      *
-     * @param autoHeight Whether to size this control to fit vertically within its parent container.
+     * @param alignment This control's alignment.
      */
      */
-    virtual void setAutoHeight(bool autoHeight);
+    void setAlignment(Alignment alignment);
 
 
     /**
     /**
-     * Get whether this control's height is set to automatically adjust to
-     * fit vertically within its parent container.
+     * Get the alignment of this control within its parent container.
      *
      *
-     * @return Whether this control's height is set to automatically adjust.
+     * @return The alignment of this control within its parent container.
      */
      */
-    bool getAutoHeight() const;
+    Alignment getAlignment() const;
 
 
     /**
     /**
      * Set the size of this control's border.
      * Set the size of this control's border.
@@ -661,20 +791,6 @@ public:
      */
      */
     bool isEnabled() const;
     bool isEnabled() const;
 
 
-    /**
-     * Get the bounds of this control, relative to its parent container, after clipping.
-     *
-     * @return The bounds of this control.
-     */
-    const Rectangle& getClipBounds() const;
-
-    /**
-     * Get the content area of this control, in screen coordinates, after clipping.
-     *
-     * @return The clipping area of this control.
-     */
-    const Rectangle& getClip() const;
-
     /**
     /**
      * Change this control's state.
      * Change this control's state.
      *
      *
@@ -985,12 +1101,22 @@ protected:
     State _state;
     State _state;
 
 
     /**
     /**
-     * Position, relative to parent container's clipping window, and desired size.
+     * Bits indicating whether bounds values are absolute values or percentages.
+     */
+    int _boundsBits;
+
+    /**
+     * Local bounds, relative to parent container's clipping window, possibly stored as percentages (see _boundsBits).
+     */
+    Rectangle _relativeBounds;
+
+    /**
+     * Local bounds, relative to parent container's clipping window, and desired size.
      */
      */
     Rectangle _bounds;
     Rectangle _bounds;
 
 
     /**
     /**
-     * Position, relative to parent container's clipping window, including border and padding, after clipping.
+     * Local bounds, relative to parent container's clipping window, including border and padding, after clipping.
      */
      */
     Rectangle _clipBounds;
     Rectangle _clipBounds;
 
 
@@ -1042,12 +1168,12 @@ protected:
     /**
     /**
      * Whether the Control's width is auto-sized.
      * Whether the Control's width is auto-sized.
      */
      */
-    bool _autoWidth;
+    AutoSize _autoWidth;
     
     
     /**
     /**
      * Whether the Control's height is auto-sized.
      * Whether the Control's height is auto-sized.
      */
      */
-    bool _autoHeight;
+    AutoSize _autoHeight;
     
     
     /**
     /**
      * Listeners map of EventType's to a list of Listeners.
      * Listeners map of EventType's to a list of Listeners.

+ 20 - 3
gameplay/src/FlowLayout.cpp

@@ -8,7 +8,7 @@ namespace gameplay
 
 
 static FlowLayout* __instance;
 static FlowLayout* __instance;
 
 
-FlowLayout::FlowLayout()
+FlowLayout::FlowLayout() : _horizontalSpacing(0), _verticalSpacing(0)
 {
 {
 }
 }
 
 
@@ -36,6 +36,22 @@ Layout::Type FlowLayout::getType()
     return Layout::LAYOUT_FLOW;
     return Layout::LAYOUT_FLOW;
 }
 }
 
 
+int FlowLayout::getHorizontalSpacing() const
+{
+    return _horizontalSpacing;
+}
+
+int FlowLayout::getVerticalSpacing() const
+{
+    return _verticalSpacing;
+}
+
+void FlowLayout::setSpacing(int horizontalSpacing, int verticalSpacing)
+{
+    _horizontalSpacing = horizontalSpacing;
+    _verticalSpacing = verticalSpacing;
+}
+
 void FlowLayout::update(const Container* container, const Vector2& offset)
 void FlowLayout::update(const Container* container, const Vector2& offset)
 {
 {
     GP_ASSERT(container);
     GP_ASSERT(container);
@@ -71,7 +87,8 @@ void FlowLayout::update(const Container* container, const Vector2& offset)
         if (xPosition + bounds.width >= clipWidth)
         if (xPosition + bounds.width >= clipWidth)
         {
         {
             xPosition = margin.left;
             xPosition = margin.left;
-            rowY += tallestHeight;
+            rowY += tallestHeight + _verticalSpacing;
+            tallestHeight = 0;
         }
         }
 
 
         yPosition = rowY + margin.top;
         yPosition = rowY + margin.top;
@@ -79,7 +96,7 @@ void FlowLayout::update(const Container* container, const Vector2& offset)
         control->setPosition(xPosition, yPosition);
         control->setPosition(xPosition, yPosition);
         control->update(container, offset);
         control->update(container, offset);
 
 
-        xPosition += bounds.width + margin.right;
+        xPosition += bounds.width + margin.right + _horizontalSpacing;
 
 
         float height = bounds.height + margin.top + margin.bottom;
         float height = bounds.height + margin.top + margin.bottom;
         if (height > tallestHeight)
         if (height > tallestHeight)

+ 32 - 0
gameplay/src/FlowLayout.h

@@ -23,6 +23,28 @@ public:
      */
      */
     Layout::Type getType();
     Layout::Type getType();
 
 
+    /**
+     * Returns the horizontal spacing between controls in the layout.
+     *
+     * @return The horizontal spacing between controls.
+     */
+    int getHorizontalSpacing() const;
+
+    /**
+     * Returns the vertical spacing between controls in the layout.
+     *
+     * @return The vertical spacing between controls.
+     */
+    int getVerticalSpacing() const;
+
+    /**
+     * Sets the spacing to add between controls in the layout.
+     *
+     * @param horizontalSpacing The horizontal spacing between controls.
+     * @param verticalSpacing The vertical spacing between controls.
+     */
+    void setSpacing(int horizontalSpacing, int verticalSpacing);
+
 protected:
 protected:
 
 
     /**
     /**
@@ -33,6 +55,16 @@ protected:
      */
      */
     void update(const Container* container, const Vector2& offset);
     void update(const Container* container, const Vector2& offset);
 
 
+    /**
+     * Horizontal spacing between controls.
+     */
+    int _horizontalSpacing;
+
+    /**
+     * Vertical spacing between controls.
+     */
+    int _verticalSpacing;
+
 private:
 private:
 
 
     /**
     /**

+ 22 - 4
gameplay/src/Font.cpp

@@ -16,7 +16,7 @@ static std::vector<Font*> __fontCache;
 static Effect* __fontEffect = NULL;
 static Effect* __fontEffect = NULL;
 
 
 Font::Font() :
 Font::Font() :
-    _style(PLAIN), _size(0), _spacing(0.125f), _glyphs(NULL), _glyphCount(0), _texture(NULL), _batch(NULL)
+    _format(BITMAP), _style(PLAIN), _size(0), _spacing(0.125f), _glyphs(NULL), _glyphCount(0), _texture(NULL), _batch(NULL), _cutoffParam(NULL)
 {
 {
 }
 }
 
 
@@ -90,7 +90,7 @@ Font* Font::create(const char* path, const char* id)
     return font;
     return font;
 }
 }
 
 
-Font* Font::create(const char* family, Style style, unsigned int size, Glyph* glyphs, int glyphCount, Texture* texture)
+Font* Font::create(const char* family, Style style, unsigned int size, Glyph* glyphs, int glyphCount, Texture* texture, Font::Format format)
 {
 {
     GP_ASSERT(family);
     GP_ASSERT(family);
     GP_ASSERT(glyphs);
     GP_ASSERT(glyphs);
@@ -99,7 +99,10 @@ Font* Font::create(const char* family, Style style, unsigned int size, Glyph* gl
     // Create the effect for the font's sprite batch.
     // Create the effect for the font's sprite batch.
     if (__fontEffect == NULL)
     if (__fontEffect == NULL)
     {
     {
-        __fontEffect = Effect::createFromFile(FONT_VSH, FONT_FSH);
+        char * defines = NULL;
+        if (format == DISTANCE_FIELD)
+            defines = "DISTANCE_FIELD";
+        __fontEffect = Effect::createFromFile(FONT_VSH, FONT_FSH, defines);
         if (__fontEffect == NULL)
         if (__fontEffect == NULL)
         {
         {
             GP_ERROR("Failed to create effect for font.");
             GP_ERROR("Failed to create effect for font.");
@@ -126,12 +129,14 @@ Font* Font::create(const char* family, Style style, unsigned int size, Glyph* gl
 
 
     // Add linear filtering for better font quality.
     // Add linear filtering for better font quality.
     Texture::Sampler* sampler = batch->getSampler();
     Texture::Sampler* sampler = batch->getSampler();
-    sampler->setFilterMode(Texture::LINEAR, Texture::LINEAR);
+    sampler->setFilterMode(Texture::LINEAR_MIPMAP_LINEAR, Texture::LINEAR);
+    sampler->setWrapMode(Texture::CLAMP, Texture::CLAMP);
 
 
     // Increase the ref count of the texture to retain it.
     // Increase the ref count of the texture to retain it.
     texture->addRef();
     texture->addRef();
 
 
     Font* font = new Font();
     Font* font = new Font();
+    font->_format = format;
     font->_family = family;
     font->_family = family;
     font->_style = style;
     font->_style = style;
     font->_size = size;
     font->_size = size;
@@ -151,6 +156,11 @@ unsigned int Font::getSize()
     return _size;
     return _size;
 }
 }
 
 
+Font::Format Font::getFormat()
+{
+    return _format;
+}
+
 void Font::start()
 void Font::start()
 {
 {
     GP_ASSERT(_batch);
     GP_ASSERT(_batch);
@@ -509,6 +519,14 @@ void Font::drawText(const char* text, int x, int y, const Vector4& color, unsign
                 if (index >= 0 && index < (int)_glyphCount)
                 if (index >= 0 && index < (int)_glyphCount)
                 {
                 {
                     Glyph& g = _glyphs[index];
                     Glyph& g = _glyphs[index];
+
+                    if (getFormat() == DISTANCE_FIELD )
+                    {
+                        if (_cutoffParam == NULL)
+                            _cutoffParam = getSpriteBatch()->getMaterial()->getParameter("u_cutoff");    
+                        // TODO: Fix me so that smaller font are much smoother
+                        _cutoffParam->setVector2(Vector2(1.0, 1.0));
+                    }
                     _batch->draw(xPos, yPos, g.width * scale, size, g.uvs[0], g.uvs[1], g.uvs[2], g.uvs[3], color);
                     _batch->draw(xPos, yPos, g.width * scale, size, g.uvs[0], g.uvs[1], g.uvs[2], g.uvs[3], color);
                     xPos += floor(g.width * scale + spacing);
                     xPos += floor(g.width * scale + spacing);
                     break;
                     break;

+ 19 - 2
gameplay/src/Font.h

@@ -49,6 +49,15 @@ public:
         ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT
         ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT
     };
     };
 
 
+    /**
+     * Defines the format of the font.
+     */
+    enum Format
+    {
+        BITMAP = 0,
+        DISTANCE_FIELD = 1
+    };
+
     /**
     /**
      * Vertex coordinates, UVs and indices can be computed and stored in a Text object.
      * Vertex coordinates, UVs and indices can be computed and stored in a Text object.
      * For static text labels that do not change frequently, this means these computations
      * For static text labels that do not change frequently, this means these computations
@@ -111,10 +120,15 @@ public:
     static Font* create(const char* path, const char* id = NULL);
     static Font* create(const char* path, const char* id = NULL);
 
 
     /**
     /**
-     * Returns the font size (max height of glyphs) in pixels.
+     * Gets the font size (max height of glyphs) in pixels.
      */
      */
     unsigned int getSize();
     unsigned int getSize();
 
 
+    /**
+     * Gets the font format. BITMAP or DISTANCEMAP.
+     */
+    Format getFormat();
+
     /**
     /**
      * Starts text drawing for this font.
      * Starts text drawing for this font.
      */
      */
@@ -327,10 +341,11 @@ private:
      * @param glyphs An array of font glyphs, defining each character in the font within the texture map.
      * @param glyphs An array of font glyphs, defining each character in the font within the texture map.
      * @param glyphCount The number of items in the glyph array.
      * @param glyphCount The number of items in the glyph array.
      * @param texture A texture map containing rendered glyphs.
      * @param texture A texture map containing rendered glyphs.
+     * @param format The format of the font (bitmap or distance fields)
      * 
      * 
      * @return The new Font.
      * @return The new Font.
      */
      */
-    static Font* create(const char* family, Style style, unsigned int size, Glyph* glyphs, int glyphCount, Texture* texture);
+    static Font* create(const char* family, Style style, unsigned int size, Glyph* glyphs, int glyphCount, Texture* texture, Font::Format format);
 
 
     void getMeasurementInfo(const char* text, const Rectangle& area, unsigned int size, Justify justify, bool wrap, bool rightToLeft,
     void getMeasurementInfo(const char* text, const Rectangle& area, unsigned int size, Justify justify, bool wrap, bool rightToLeft,
                             std::vector<int>* xPositions, int* yPosition, std::vector<unsigned int>* lineLengths);
                             std::vector<int>* xPositions, int* yPosition, std::vector<unsigned int>* lineLengths);
@@ -349,6 +364,7 @@ private:
     void addLineInfo(const Rectangle& area, int lineWidth, int lineLength, Justify hAlign,
     void addLineInfo(const Rectangle& area, int lineWidth, int lineLength, Justify hAlign,
                      std::vector<int>* xPositions, std::vector<unsigned int>* lineLengths, bool rightToLeft);
                      std::vector<int>* xPositions, std::vector<unsigned int>* lineLengths, bool rightToLeft);
 
 
+    Format _format;
     std::string _path;
     std::string _path;
     std::string _id;
     std::string _id;
     std::string _family;
     std::string _family;
@@ -360,6 +376,7 @@ private:
     Texture* _texture;
     Texture* _texture;
     SpriteBatch* _batch;
     SpriteBatch* _batch;
     Rectangle _viewport;
     Rectangle _viewport;
+    MaterialParameter* _cutoffParam;
 };
 };
 
 
 }
 }

+ 118 - 242
gameplay/src/Form.cpp

@@ -77,11 +77,7 @@ Form* Form::create(const char* id, Theme::Style* style, Layout::Type layoutType)
     form->_theme = style->getTheme();
     form->_theme = style->getTheme();
     form->_theme->addRef();
     form->_theme->addRef();
 
 
-    // Get default projection matrix.
-    Game* game = Game::getInstance();
-    Matrix::createOrthographicOffCenter(0, game->getWidth(), game->getHeight(), 0, 0, 1, &form->_defaultProjectionMatrix);
-
-    form->updateBounds();
+    form->updateFrameBuffer();
 
 
     __forms.push_back(form);
     __forms.push_back(form);
 
 
@@ -109,37 +105,57 @@ Form* Form::create(const char* url)
     }
     }
 
 
     // Create new form with given ID, theme and layout.
     // Create new form with given ID, theme and layout.
-    const char* themeFile = formProperties->getString("theme");
-    const char* layoutString = formProperties->getString("layout");
-        
-    Layout* layout;
-    switch (getLayoutType(layoutString))
+    std::string themeFile;
+    formProperties->getPath("theme", &themeFile);
+
+    // Parse layout
+    Layout* layout = NULL;
+    Properties* layoutNS = formProperties->getNamespace("layout", true, false);
+    if (layoutNS)
     {
     {
-    case Layout::LAYOUT_ABSOLUTE:
-        layout = AbsoluteLayout::create();
-        break;
-    case Layout::LAYOUT_FLOW:
-        layout = FlowLayout::create();
-        break;
-    case Layout::LAYOUT_VERTICAL:
-        layout = VerticalLayout::create();
-        break;
-    default:
-        GP_ERROR("Unsupported layout type '%d'.", getLayoutType(layoutString));
-        break;
+        Layout::Type layoutType = getLayoutType(layoutNS->getString("type"));
+        switch (layoutType)
+        {
+        case Layout::LAYOUT_ABSOLUTE:
+            layout = AbsoluteLayout::create();
+            break;
+        case Layout::LAYOUT_FLOW:
+            layout = FlowLayout::create();
+            static_cast<FlowLayout*>(layout)->setSpacing(layoutNS->getInt("horizontalSpacing"), layoutNS->getInt("verticalSpacing"));
+            break;
+        case Layout::LAYOUT_VERTICAL:
+            layout = VerticalLayout::create();
+            static_cast<VerticalLayout*>(layout)->setSpacing(layoutNS->getInt("spacing"));
+            break;
+        }
+    }
+    else
+    {
+        switch (getLayoutType(formProperties->getString("layout")))
+        {
+        case Layout::LAYOUT_ABSOLUTE:
+            layout = AbsoluteLayout::create();
+            break;
+        case Layout::LAYOUT_FLOW:
+            layout = FlowLayout::create();
+            break;
+        case Layout::LAYOUT_VERTICAL:
+            layout = VerticalLayout::create();
+            break;
+        }
+    }
+    if (layout == NULL)
+    {
+        GP_ERROR("Unsupported layout type for form: %s", url);
     }
     }
 
 
-    Theme* theme = Theme::create(themeFile);
+    Theme* theme = Theme::create(themeFile.c_str());
     GP_ASSERT(theme);
     GP_ASSERT(theme);
 
 
     Form* form = new Form();
     Form* form = new Form();
     form->_layout = layout;
     form->_layout = layout;
     form->_theme = theme;
     form->_theme = theme;
 
 
-    // Get default projection matrix.
-    Game* game = Game::getInstance();
-    Matrix::createOrthographicOffCenter(0, game->getWidth(), game->getHeight(), 0, 0, 1, &form->_defaultProjectionMatrix);
-
     Theme::Style* style = NULL;
     Theme::Style* style = NULL;
     const char* styleName = formProperties->getString("style");
     const char* styleName = formProperties->getString("style");
     if (styleName)
     if (styleName)
@@ -154,25 +170,6 @@ Form* Form::create(const char* url)
 
 
     form->_consumeInputEvents = formProperties->getBool("consumeInputEvents", false);
     form->_consumeInputEvents = formProperties->getBool("consumeInputEvents", false);
 
 
-    // Alignment
-    if ((form->_alignment & Control::ALIGN_BOTTOM) == Control::ALIGN_BOTTOM)
-    {
-        form->_bounds.y = Game::getInstance()->getHeight() - form->_bounds.height;
-    }
-    else if ((form->_alignment & Control::ALIGN_VCENTER) == Control::ALIGN_VCENTER)
-    {
-        form->_bounds.y = Game::getInstance()->getHeight() * 0.5f - form->_bounds.height * 0.5f;
-    }
-
-    if ((form->_alignment & Control::ALIGN_RIGHT) == Control::ALIGN_RIGHT)
-    {
-        form->_bounds.x = Game::getInstance()->getWidth() - form->_bounds.width;
-    }
-    else if ((form->_alignment & Control::ALIGN_HCENTER) == Control::ALIGN_HCENTER)
-    {
-        form->_bounds.x = Game::getInstance()->getWidth() * 0.5f - form->_bounds.width * 0.5f;
-    }
-
     form->_scroll = getScroll(formProperties->getString("scroll"));
     form->_scroll = getScroll(formProperties->getString("scroll"));
     form->_scrollBarsAutoHide = formProperties->getBool("scrollBarsAutoHide");
     form->_scrollBarsAutoHide = formProperties->getBool("scrollBarsAutoHide");
     if (form->_scrollBarsAutoHide)
     if (form->_scrollBarsAutoHide)
@@ -185,7 +182,7 @@ Form* Form::create(const char* url)
 
 
     SAFE_DELETE(properties);
     SAFE_DELETE(properties);
     
     
-    form->updateBounds();
+    form->updateFrameBuffer();
 
 
     __forms.push_back(form);
     __forms.push_back(form);
 
 
@@ -212,42 +209,37 @@ Theme* Form::getTheme() const
     return _theme;
     return _theme;
 }
 }
 
 
-void Form::setSize(float width, float height)
+void Form::updateFrameBuffer()
 {
 {
-    if (_autoWidth)
-    {
-        width = Game::getInstance()->getWidth();
-    }
+    float width = _absoluteClipBounds.width;
+    float height = _absoluteClipBounds.height;
 
 
-    if (_autoHeight)
-    {
-        height = Game::getInstance()->getHeight();
-    }
+    SAFE_RELEASE(_frameBuffer);
+    SAFE_DELETE(_spriteBatch);
 
 
-    if (width != 0.0f && height != 0.0f &&
-        (width != _bounds.width || height != _bounds.height))
+    if (width != 0.0f && height != 0.0f)
     {
     {
         // Width and height must be powers of two to create a texture.
         // Width and height must be powers of two to create a texture.
         unsigned int w = nextPowerOfTwo(width);
         unsigned int w = nextPowerOfTwo(width);
         unsigned int h = nextPowerOfTwo(height);
         unsigned int h = nextPowerOfTwo(height);
         _u2 = width / (float)w;
         _u2 = width / (float)w;
         _v1 = height / (float)h;
         _v1 = height / (float)h;
-
-        // Create framebuffer if necessary. TODO: Use pool to cache.
-        if (_frameBuffer)
-            SAFE_RELEASE(_frameBuffer)
         
         
         _frameBuffer = FrameBuffer::create(_id.c_str(), w, h);
         _frameBuffer = FrameBuffer::create(_id.c_str(), w, h);
         GP_ASSERT(_frameBuffer);
         GP_ASSERT(_frameBuffer);
 
 
-        // Re-create projection matrix.
+        // Re-create projection matrix for drawing onto framebuffer
         Matrix::createOrthographicOffCenter(0, width, height, 0, 0, 1, &_projectionMatrix);
         Matrix::createOrthographicOffCenter(0, width, height, 0, 0, 1, &_projectionMatrix);
 
 
-        // Re-create sprite batch.
-        SAFE_DELETE(_spriteBatch);
+        // Re-create sprite batch
         _spriteBatch = SpriteBatch::create(_frameBuffer->getRenderTarget()->getTexture());
         _spriteBatch = SpriteBatch::create(_frameBuffer->getRenderTarget()->getTexture());
         GP_ASSERT(_spriteBatch);
         GP_ASSERT(_spriteBatch);
 
 
+        // Compute full-viewport ortho matrix for drawing frame buffer onto screen
+        Matrix viewportProjection;
+        Matrix::createOrthographicOffCenter(0, Game::getInstance()->getViewport().width, Game::getInstance()->getViewport().height, 0, 0, 1, &viewportProjection);
+        _spriteBatch->setProjectionMatrix(viewportProjection);
+
         // Clear the framebuffer black
         // Clear the framebuffer black
         Game* game = Game::getInstance();
         Game* game = Game::getInstance();
         FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
         FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
@@ -256,57 +248,12 @@ void Form::setSize(float width, float height)
         game->setViewport(Rectangle(0, 0, width, height));
         game->setViewport(Rectangle(0, 0, width, height));
         _theme->setProjectionMatrix(_projectionMatrix);
         _theme->setProjectionMatrix(_projectionMatrix);
         game->clear(Game::CLEAR_COLOR, Vector4::zero(), 1.0, 0);
         game->clear(Game::CLEAR_COLOR, Vector4::zero(), 1.0, 0);
-        _theme->setProjectionMatrix(_defaultProjectionMatrix);
 
 
         previousFrameBuffer->bind();
         previousFrameBuffer->bind();
         game->setViewport(previousViewport);
         game->setViewport(previousViewport);
-    }
-    _bounds.width = width;
-    _bounds.height = height;
-    _dirty = true;
-}
-
-void Form::setBounds(const Rectangle& bounds)
-{
-    setPosition(bounds.x, bounds.y);
-    setSize(bounds.width, bounds.height);
-}
 
 
-void Form::setWidth(float width)
-{
-    setSize(width, _bounds.height);
-}
-
-void Form::setHeight(float height)
-{
-    setSize(_bounds.width, height);
-}
-
-void Form::setAutoWidth(bool autoWidth)
-{
-    if (_autoWidth != autoWidth)
-    {
-        _autoWidth = autoWidth;
-        _dirty = true;
-
-        if (_autoWidth)
-        {
-            setSize(_bounds.width, Game::getInstance()->getWidth());
-        }
-    }
-}
-
-void Form::setAutoHeight(bool autoHeight)
-{
-    if (_autoHeight != autoHeight)
-    {
-        _autoHeight = autoHeight;
-        _dirty = true;
-
-        if (_autoHeight)
-        {
-            setSize(_bounds.width, Game::getInstance()->getHeight());
-        }
+        // Force any attached node to be updated
+        setNode(_node);
     }
     }
 }
 }
 
 
@@ -332,12 +279,20 @@ static Effect* createEffect()
 
 
 void Form::setNode(Node* node)
 void Form::setNode(Node* node)
 {
 {
-    // If the user wants a custom node then we need to create a 3D quad
-    if (node && node != _node)
+    // If we were already attached to a node, remove ourself from it
+    if (_node)
+    {
+        _node->setModel(NULL);
+        _nodeQuad = NULL;
+        _nodeMaterial = NULL;
+        _node = NULL;
+    }
+
+    if (node)
     {
     {
         // Set this Form up to be 3D by initializing a quad.
         // Set this Form up to be 3D by initializing a quad.
-        float x2 = _bounds.width;
-        float y2 = _bounds.height;
+        float x2 = _absoluteBounds.width;
+        float y2 = _absoluteBounds.height;
         float vertices[] =
         float vertices[] =
         {
         {
             0, y2, 0,   0, _v1,
             0, y2, 0,   0, _v1,
@@ -374,11 +329,14 @@ void Form::setNode(Node* node)
         _nodeMaterial->setParameterAutoBinding("u_worldViewProjectionMatrix", RenderState::WORLD_VIEW_PROJECTION_MATRIX);
         _nodeMaterial->setParameterAutoBinding("u_worldViewProjectionMatrix", RenderState::WORLD_VIEW_PROJECTION_MATRIX);
 
 
         // Bind the texture from the framebuffer and set the texture to clamp
         // Bind the texture from the framebuffer and set the texture to clamp
-        Texture::Sampler* sampler = Texture::Sampler::create(_frameBuffer->getRenderTarget()->getTexture());
-        GP_ASSERT(sampler);
-        sampler->setWrapMode(Texture::CLAMP, Texture::CLAMP);
-        _nodeMaterial->getParameter("u_texture")->setValue(sampler);
-        sampler->release();
+        if (_frameBuffer)
+        {
+            Texture::Sampler* sampler = Texture::Sampler::create(_frameBuffer->getRenderTarget()->getTexture());
+            GP_ASSERT(sampler);
+            sampler->setWrapMode(Texture::CLAMP, Texture::CLAMP);
+            _nodeMaterial->getParameter("u_texture")->setValue(sampler);
+            sampler->release();
+        }
 
 
         RenderState::StateBlock* rsBlock = _nodeMaterial->getStateBlock();
         RenderState::StateBlock* rsBlock = _nodeMaterial->getStateBlock();
         rsBlock->setDepthWrite(true);
         rsBlock->setDepthWrite(true);
@@ -386,14 +344,15 @@ void Form::setNode(Node* node)
         rsBlock->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
         rsBlock->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
         rsBlock->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
         rsBlock->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
     }
     }
+
     _node = node;
     _node = node;
 }
 }
 
 
 void Form::update(float elapsedTime)
 void Form::update(float elapsedTime)
 {
 {
-    if (isDirty())
+    if (true)//isDirty())
     {
     {
-        updateBounds();
+        update(NULL, Vector2::zero());
 
 
         // Cache themed attributes for performance.
         // Cache themed attributes for performance.
         _skin = getSkin(_state);
         _skin = getSkin(_state);
@@ -411,122 +370,26 @@ void Form::update(float elapsedTime)
     }
     }
 }
 }
 
 
-void Form::updateBounds()
-{   
-    _clearBounds.set(_absoluteClipBounds);
-
-    // Calculate the clipped bounds.
-    float x = 0;
-    float y = 0;
-    float width = _bounds.width;
-    float height = _bounds.height;
-
-    Rectangle clip(0, 0, _bounds.width, _bounds.height);
-
-    float clipX2 = clip.x + clip.width;
-    float x2 = clip.x + x + width;
-    if (x2 > clipX2)
-        width -= x2 - clipX2;
-
-    float clipY2 = clip.y + clip.height;
-    float y2 = clip.y + y + height;
-    if (y2 > clipY2)
-        height -= y2 - clipY2;
-
-    if (x < 0)
-    {
-        width += x;
-        x = -x;
-    }
-    else
-    {
-        x = 0;
-    }
-
-    if (y < 0)
-    {
-        height += y;
-        y = -y;
-    }
-    else
-    {
-        y = 0;
-    }
-
-    _clipBounds.set(x, y, width, height);
-
-    // Calculate the absolute bounds.
-    x = 0;
-    y = 0;
-    _absoluteBounds.set(x, y, _bounds.width, _bounds.height);
-
-    // Calculate the absolute viewport bounds. Absolute bounds minus border and padding.
-    const Theme::Border& border = getBorder(_state);
-    const Theme::Padding& padding = getPadding();
-
-    x += border.left + padding.left;
-    y += border.top + padding.top;
-    width = _bounds.width - border.left - padding.left - border.right - padding.right;
-    height = _bounds.height - border.top - padding.top - border.bottom - padding.bottom;
-
-    _viewportBounds.set(x, y, width, height);
-
-    // Calculate the clip area. Absolute bounds, minus border and padding, clipped to the parent container's clip area.
-    clipX2 = clip.x + clip.width;
-    x2 = x + width;
-    if (x2 > clipX2)
-        width = clipX2 - x;
-
-    clipY2 = clip.y + clip.height;
-    y2 = y + height;
-    if (y2 > clipY2)
-        height = clipY2 - y;
-
-    if (x < clip.x)
-    {
-        float dx = clip.x - x;
-        width -= dx;
-        x = clip.x;
-    }
-
-    if (y < clip.y)
-    {
-        float dy = clip.y - y;
-        height -= dy;
-        y = clip.y;
-    }
- 
-    _viewportClipBounds.set(x, y, width, height);
-    _absoluteClipBounds.set(x - border.left - padding.left, y - border.top - padding.top,
-                            width + border.left + padding.left + border.right + padding.right,
-                            height + border.top + padding.top + border.bottom + padding.bottom);
-    if (_clearBounds.isEmpty())
-    {
-        _clearBounds.set(_absoluteClipBounds);
-    }
+void Form::update(const Control* container, const Vector2& offset)
+{
+    // Store previous absolute bounds
+    Rectangle oldAbsoluteClipBounds = _absoluteClipBounds;
 
 
-    // Get scrollbar images and diminish clipping bounds to make room for scrollbars.
-    if ((_scroll & SCROLL_HORIZONTAL) == SCROLL_HORIZONTAL)
-    {
-        _scrollBarLeftCap = getImage("scrollBarLeftCap", _state);
-        _scrollBarHorizontal = getImage("horizontalScrollBar", _state);
-        _scrollBarRightCap = getImage("scrollBarRightCap", _state);
+    _layout->align(this, NULL);
 
 
-        _viewportClipBounds.height -= _scrollBarHorizontal->getRegion().height;
-    }
+    Container::update(container, offset);
 
 
-    if ((_scroll & SCROLL_VERTICAL) == SCROLL_VERTICAL)
+    if (_absoluteClipBounds.width != oldAbsoluteClipBounds.width || _absoluteClipBounds.height != oldAbsoluteClipBounds.height)
     {
     {
-        _scrollBarTopCap = getImage("scrollBarTopCap", _state);
-        _scrollBarVertical = getImage("verticalScrollBar", _state);
-        _scrollBarBottomCap = getImage("scrollBarBottomCap", _state);
-        
-        _viewportClipBounds.width -= _scrollBarVertical->getRegion().width;
+        updateFrameBuffer();
     }
     }
 }
 }
 
 
 void Form::draw()
 void Form::draw()
 {
 {
+    if (!_visible || !_frameBuffer)
+        return;
+
     // The first time a form is drawn, its contents are rendered into a framebuffer.
     // The first time a form is drawn, its contents are rendered into a framebuffer.
     // The framebuffer will only be drawn into again when the contents of the form change.
     // The framebuffer will only be drawn into again when the contents of the form change.
     // If this form has a node then it's a 3D form and the framebuffer will be used
     // If this form has a node then it's a 3D form and the framebuffer will be used
@@ -536,25 +399,22 @@ void Form::draw()
     // to render the contents of the framebuffer directly to the display.
     // to render the contents of the framebuffer directly to the display.
 
 
     // Check whether this form has changed since the last call to draw() and if so, render into the framebuffer.
     // Check whether this form has changed since the last call to draw() and if so, render into the framebuffer.
-    if (isDirty())
+    if (true)//isDirty())
     {
     {
-        GP_ASSERT(_frameBuffer);
         FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
         FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
 
 
         Game* game = Game::getInstance();
         Game* game = Game::getInstance();
         Rectangle prevViewport = game->getViewport();
         Rectangle prevViewport = game->getViewport();
-        game->setViewport(Rectangle(0, 0, _bounds.width, _bounds.height));
+        game->setViewport(Rectangle(0, 0, _absoluteClipBounds.width, _absoluteClipBounds.height));
 
 
         GP_ASSERT(_theme);
         GP_ASSERT(_theme);
         _theme->setProjectionMatrix(_projectionMatrix);
         _theme->setProjectionMatrix(_projectionMatrix);
-        
+
         // By setting needsClear to true here, an optimization meant to clear and redraw only areas of the form
         // By setting needsClear to true here, an optimization meant to clear and redraw only areas of the form
         // that have changed is disabled.  Currently, repositioning controls can result in areas of the screen being cleared
         // that have changed is disabled.  Currently, repositioning controls can result in areas of the screen being cleared
         // after another control has been drawn there.  This should probably be done in two passes -- one to clear areas where
         // after another control has been drawn there.  This should probably be done in two passes -- one to clear areas where
         // dirty controls were last frame, and another to draw them where they are now.
         // dirty controls were last frame, and another to draw them where they are now.
-        Container::draw(_theme->getSpriteBatch(), Rectangle(0, 0, _bounds.width, _bounds.height),
-                        /*_skin != NULL*/ true, false, _bounds.height);
-        _theme->setProjectionMatrix(_defaultProjectionMatrix);
+        Container::draw(_theme->getSpriteBatch(), _absoluteClipBounds, /*_skin != NULL*/ true, false, _absoluteClipBounds.height);
 
 
         // Restore the previous game viewport.
         // Restore the previous game viewport.
         game->setViewport(prevViewport);
         game->setViewport(prevViewport);
@@ -571,11 +431,6 @@ void Form::draw()
     else
     else
     {
     {
         // Otherwise we draw the framebuffer in ortho space with a spritebatch.
         // Otherwise we draw the framebuffer in ortho space with a spritebatch.
-        if (!_spriteBatch)
-        {
-            _spriteBatch = SpriteBatch::create(_frameBuffer->getRenderTarget()->getTexture());
-            GP_ASSERT(_spriteBatch);
-        }
         _spriteBatch->start();
         _spriteBatch->start();
         _spriteBatch->draw(_bounds.x, _bounds.y, 0, _bounds.width, _bounds.height, 0, _v1, _u2, 0, Vector4::one());
         _spriteBatch->draw(_bounds.x, _bounds.y, 0, _bounds.width, _bounds.height, 0, _v1, _u2, 0, Vector4::one());
         _spriteBatch->finish();
         _spriteBatch->finish();
@@ -740,6 +595,27 @@ void Form::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, uns
     }
     }
 }
 }
 
 
+void Form::resizeEventInternal(unsigned int width, unsigned int height)
+{
+    for (size_t i = 0; i < __forms.size(); ++i)
+    {
+        Form* form = __forms[i];
+        if (form)
+        {
+            if (form->_spriteBatch)
+            {
+                // Update viewport projection matrix
+                Matrix viewportProjection;
+                Matrix::createOrthographicOffCenter(0, Game::getInstance()->getViewport().width, Game::getInstance()->getViewport().height, 0, 0, 1, &viewportProjection);
+                form->_spriteBatch->setProjectionMatrix(viewportProjection);
+            }
+
+            // Dirty the form
+            form->_dirty = true;
+        }
+    }
+}
+
 bool Form::projectPoint(int x, int y, Vector3* point)
 bool Form::projectPoint(int x, int y, Vector3* point)
 {
 {
     Scene* scene = _node->getScene();
     Scene* scene = _node->getScene();

+ 20 - 49
gameplay/src/Form.h

@@ -92,49 +92,6 @@ public:
      */
      */
     Theme* getTheme() const;
     Theme* getTheme() const;
 
 
-    /**
-     * Set the desired size of this form.
-     *
-     * @param width The width.
-     * @param height The height.
-     */
-    virtual void setSize(float width, float height);
-
-    /**
-     * Set the bounds of this form.
-     *
-     * @param bounds The new bounds to set.
-     */
-    virtual void setBounds(const Rectangle& bounds);
-
-    /** 
-     * Set the desired width of the form.
-     *
-     * @param width The width.
-     */
-    virtual void setWidth(float width);
-
-    /** 
-     * Set the desired height of the form.
-     *
-     * @param height The height.
-     */
-    virtual void setHeight(float height);
-
-    /**
-     * Set this form's width to that of the display.
-     *
-     * @param autoWidth Whether to set this form's width to that of the display.
-     */
-    virtual void setAutoWidth(bool autoWidth);
-
-    /**
-     * Set this form's height to that of the display.
-     *
-     * @param autoHeight Whether to set this form's height to that of the display.
-     */
-    virtual void setAutoHeight(bool autoHeight);
-
     /**
     /**
      * Attach this form to a node.
      * Attach this form to a node.
      *
      *
@@ -162,6 +119,13 @@ public:
      */
      */
     const char* getType() const;
     const char* getType() const;
 
 
+protected:
+
+    /**
+     * @see Control::update
+     */
+    void update(const Control* container, const Vector2& offset);
+
 private:
 private:
     
     
     /**
     /**
@@ -186,11 +150,6 @@ private:
      */
      */
     void initializeQuad(Mesh* mesh);
     void initializeQuad(Mesh* mesh);
 
 
-    /**
-     * Update this form's bounds.
-     */
-    void updateBounds();
-
     /**
     /**
      * Updates all visible, enabled forms.
      * Updates all visible, enabled forms.
      */
      */
@@ -226,6 +185,14 @@ private:
      */
      */
     static void gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex);
     static void gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex);
 
 
+    /**
+     * Fired by the platform when the game window resizes.
+     *
+     * @param width The new window width.
+     * @param height The new window height.
+     */
+    static void resizeEventInternal(unsigned int width, unsigned int height);
+
     /**
     /**
      * Get the next highest power of two of an integer.  Used when creating framebuffers.
      * Get the next highest power of two of an integer.  Used when creating framebuffers.
      *
      *
@@ -246,6 +213,11 @@ private:
      */
      */
     bool projectPoint(int x, int y, Vector3* point);
     bool projectPoint(int x, int y, Vector3* point);
 
 
+    /**
+     * Called when the form is resized to update its internal frame buffer.
+     */
+    void updateFrameBuffer();
+
     Theme* _theme;                      // The Theme applied to this Form.
     Theme* _theme;                      // The Theme applied to this Form.
     FrameBuffer* _frameBuffer;          // FBO the Form is rendered into for texturing the quad. 
     FrameBuffer* _frameBuffer;          // FBO the Form is rendered into for texturing the quad. 
     SpriteBatch* _spriteBatch;
     SpriteBatch* _spriteBatch;
@@ -255,7 +227,6 @@ private:
     float _u2;
     float _u2;
     float _v1;
     float _v1;
     Matrix _projectionMatrix;           // Orthographic projection matrix to be set on SpriteBatch objects when rendering into the FBO.
     Matrix _projectionMatrix;           // Orthographic projection matrix to be set on SpriteBatch objects when rendering into the FBO.
-    Matrix _defaultProjectionMatrix;
     bool _isGamepad;
     bool _isGamepad;
 };
 };
 
 

+ 13 - 1
gameplay/src/Game.cpp

@@ -24,7 +24,7 @@ Game::Game()
       _clearDepth(1.0f), _clearStencil(0), _properties(NULL),
       _clearDepth(1.0f), _clearStencil(0), _properties(NULL),
       _animationController(NULL), _audioController(NULL),
       _animationController(NULL), _audioController(NULL),
       _physicsController(NULL), _aiController(NULL), _audioListener(NULL),
       _physicsController(NULL), _aiController(NULL), _audioListener(NULL),
-      _timeEvents(NULL), _scriptController(NULL), _scriptListeners(NULL)
+      _timeEvents(NULL), _scriptController(NULL), _socialController(NULL), _scriptListeners(NULL)
 {
 {
     GP_ASSERT(__gameInstance == NULL);
     GP_ASSERT(__gameInstance == NULL);
     __gameInstance = this;
     __gameInstance = this;
@@ -114,6 +114,9 @@ bool Game::startup()
     _scriptController = new ScriptController();
     _scriptController = new ScriptController();
     _scriptController->initialize();
     _scriptController->initialize();
 
 
+    _socialController = new SocialController();
+    _socialController->initialize();
+
     // Load any gamepads, ui or physical.
     // Load any gamepads, ui or physical.
     loadGamepads();
     loadGamepads();
 
 
@@ -194,6 +197,9 @@ void Game::shutdown()
         _aiController->finalize();
         _aiController->finalize();
         SAFE_DELETE(_aiController);
         SAFE_DELETE(_aiController);
 
 
+        _socialController->initialize();
+        SAFE_DELETE(_socialController);
+
         // Note: we do not clean up the script controller here
         // Note: we do not clean up the script controller here
         // because users can call Game::exit() from a script.
         // because users can call Game::exit() from a script.
 
 
@@ -222,6 +228,7 @@ void Game::pause()
         _audioController->pause();
         _audioController->pause();
         _physicsController->pause();
         _physicsController->pause();
         _aiController->pause();
         _aiController->pause();
+        _socialController->pause();
     }
     }
 
 
     ++_pausedCount;
     ++_pausedCount;
@@ -245,6 +252,7 @@ void Game::resume()
             _audioController->resume();
             _audioController->resume();
             _physicsController->resume();
             _physicsController->resume();
             _aiController->resume();
             _aiController->resume();
+            _socialController->resume();
         }
         }
     }
     }
 }
 }
@@ -329,6 +337,9 @@ void Game::frame()
         // Audio Rendering.
         // Audio Rendering.
         _audioController->update(elapsedTime);
         _audioController->update(elapsedTime);
 
 
+        // Social Update.
+        _socialController->update(elapsedTime);
+
         // Graphics Rendering.
         // Graphics Rendering.
         render(elapsedTime);
         render(elapsedTime);
 
 
@@ -391,6 +402,7 @@ void Game::updateOnce()
     _aiController->update(elapsedTime);
     _aiController->update(elapsedTime);
     _audioController->update(elapsedTime);
     _audioController->update(elapsedTime);
     _scriptController->update(elapsedTime);
     _scriptController->update(elapsedTime);
+    _socialController->update(elapsedTime);
 }
 }
 
 
 void Game::setViewport(const Rectangle& viewport)
 void Game::setViewport(const Rectangle& viewport)

+ 12 - 0
gameplay/src/Game.h

@@ -9,6 +9,7 @@
 #include "AudioController.h"
 #include "AudioController.h"
 #include "AnimationController.h"
 #include "AnimationController.h"
 #include "PhysicsController.h"
 #include "PhysicsController.h"
+#include "SocialController.h"
 #include "AIController.h"
 #include "AIController.h"
 #include "AudioListener.h"
 #include "AudioListener.h"
 #include "Rectangle.h"
 #include "Rectangle.h"
@@ -258,6 +259,16 @@ public:
      */
      */
     inline ScriptController* getScriptController() const;
     inline ScriptController* getScriptController() const;
 
 
+    /**
+     * Gets the social controller for managing control of social apis
+     * associated with the game.
+     *
+     * @return The script controller for this game.
+     *
+     * @script{ignore}
+     */
+    inline SocialController* getSocialController() const;
+
     /**
     /**
      * Gets the audio listener for 3D audio.
      * Gets the audio listener for 3D audio.
      * 
      * 
@@ -735,6 +746,7 @@ private:
     AudioListener* _audioListener;              // The audio listener in 3D space.
     AudioListener* _audioListener;              // The audio listener in 3D space.
     std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents;     // Contains the scheduled time events.
     std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents;     // Contains the scheduled time events.
     ScriptController* _scriptController;            // Controls the scripting engine.
     ScriptController* _scriptController;            // Controls the scripting engine.
+    SocialController* _socialController;		// Controls social aspect of the game.
     std::vector<ScriptListener*>* _scriptListeners; // Lua script listeners.
     std::vector<ScriptListener*>* _scriptListeners; // Lua script listeners.
 
 
     // Note: Do not add STL object member variables on the stack; this will cause false memory leaks to be reported.
     // Note: Do not add STL object member variables on the stack; this will cause false memory leaks to be reported.

+ 5 - 0
gameplay/src/Game.inl

@@ -63,6 +63,11 @@ inline AIController* Game::getAIController() const
     return _aiController;
     return _aiController;
 }
 }
 
 
+inline SocialController* Game::getSocialController() const
+{
+    return _socialController;
+}
+
 template <class T>
 template <class T>
 void Game::renderOnce(T* instance, void (T::*method)(void*), void* cookie)
 void Game::renderOnce(T* instance, void (T::*method)(void*), void* cookie)
 {
 {

+ 18 - 0
gameplay/src/ImageControl.cpp

@@ -150,4 +150,22 @@ void ImageControl::drawImages(SpriteBatch* spriteBatch, const Rectangle& clip)
     spriteBatch->start();
     spriteBatch->start();
 }
 }
 
 
+void ImageControl::update(const Control* container, const Vector2& offset)
+{
+    Button::update(container, offset);
+
+    if (_batch)
+    {
+        if (_autoWidth == Control::AUTO_SIZE_FIT)
+        {
+            setWidth(_batch->getSampler()->getTexture()->getWidth());
+        }
+
+        if (_autoHeight == Control::AUTO_SIZE_FIT)
+        {
+            setHeight(_batch->getSampler()->getTexture()->getWidth());
+        }
+    }
+}
+
 }
 }

+ 5 - 0
gameplay/src/ImageControl.h

@@ -124,6 +124,11 @@ protected:
 
 
     void drawImages(SpriteBatch* spriteBatch, const Rectangle& clip);
     void drawImages(SpriteBatch* spriteBatch, const Rectangle& clip);
 
 
+    /**
+     * @see Control#update(const Control*, const Vector2&)
+     */
+    void update(const Control* container, const Vector2& offset);
+
     // Source region.
     // Source region.
     Rectangle _srcRegion;
     Rectangle _srcRegion;
     // Destination region.
     // Destination region.

+ 12 - 1
gameplay/src/Label.cpp

@@ -87,11 +87,22 @@ void Label::update(const Control* container, const Vector2& offset)
 {
 {
     Control::update(container, offset);
     Control::update(container, offset);
 
 
-    _textBounds.set(_viewportBounds);
+    _textBounds.set((int)_viewportBounds.x, (int)_viewportBounds.y, _viewportBounds.width, _viewportBounds.height);
 
 
     _font = getFont(_state);
     _font = getFont(_state);
     _textColor = getTextColor(_state);
     _textColor = getTextColor(_state);
     _textColor.w *= _opacity;
     _textColor.w *= _opacity;
+
+    Font* font = getFont(_state);
+    if ((_autoWidth == Control::AUTO_SIZE_FIT || _autoHeight == Control::AUTO_SIZE_FIT) && font)
+    {
+        unsigned int w, h;
+        font->measureText(_text.c_str(), getFontSize(_state), &w, &h);
+        if (_autoWidth == Control::AUTO_SIZE_FIT)
+            setWidth(w + getBorder(_state).left + getBorder(_state).right + getPadding().left + getPadding().right);
+        if (_autoHeight == Control::AUTO_SIZE_FIT)
+            setHeight(h + getBorder(_state).top + getBorder(_state).bottom + getPadding().top + getPadding().bottom);
+    }
 }
 }
 
 
 void Label::drawText(const Rectangle& clip)
 void Label::drawText(const Rectangle& clip)

+ 15 - 28
gameplay/src/Layout.cpp

@@ -2,6 +2,7 @@
 #include "Layout.h"
 #include "Layout.h"
 #include "Control.h"
 #include "Control.h"
 #include "Container.h"
 #include "Container.h"
+#include "Game.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {
@@ -9,21 +10,19 @@ namespace gameplay
 void Layout::align(Control* control, const Container* container)
 void Layout::align(Control* control, const Container* container)
 {
 {
     GP_ASSERT(control);
     GP_ASSERT(control);
-    GP_ASSERT(container);
 
 
     if (control->_alignment != Control::ALIGN_TOP_LEFT ||
     if (control->_alignment != Control::ALIGN_TOP_LEFT ||
-        control->_isAlignmentSet ||
-        control->_autoWidth || control->_autoHeight)
+        control->_isAlignmentSet)
     {
     {
-        Rectangle controlBounds = control->getBounds();
+        const Rectangle& controlBounds = control->getBounds();
         const Theme::Margin& controlMargin = control->getMargin();
         const Theme::Margin& controlMargin = control->getMargin();
-        const Rectangle& containerBounds = container->getBounds();
-        const Theme::Border& containerBorder = container->getBorder(container->getState());
-        const Theme::Padding& containerPadding = container->getPadding();
+        const Rectangle& containerBounds = container ? container->getBounds() : Game::getInstance()->getViewport();
+        const Theme::Border& containerBorder = container ? container->getBorder(container->getState()) : Theme::Border::empty();
+        const Theme::Padding& containerPadding = container ? container->getPadding() : Theme::Padding::empty();
 
 
         float clipWidth;
         float clipWidth;
         float clipHeight; 
         float clipHeight; 
-        if (container->getScroll() != Container::SCROLL_NONE)
+        if (container && (container->getScroll() != Container::SCROLL_NONE))
         {
         {
             const Rectangle& verticalScrollBarBounds = container->getImageRegion("verticalScrollBar", container->getState());
             const Rectangle& verticalScrollBarBounds = container->getImageRegion("verticalScrollBar", container->getState());
             const Rectangle& horizontalScrollBarBounds = container->getImageRegion("horizontalScrollBar", container->getState());
             const Rectangle& horizontalScrollBarBounds = container->getImageRegion("horizontalScrollBar", container->getState());
@@ -36,51 +35,39 @@ void Layout::align(Control* control, const Container* container)
             clipHeight = containerBounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom;
             clipHeight = containerBounds.height - containerBorder.top - containerBorder.bottom - containerPadding.top - containerPadding.bottom;
         }
         }
 
 
-        if (control->_autoWidth)
-        {
-            controlBounds.width = clipWidth - controlMargin.left - controlMargin.right;
-        }
-
-        if (control->_autoHeight)
-        {
-            controlBounds.height = clipHeight - controlMargin.top - controlMargin.bottom;
-        }
-
         // Vertical alignment
         // Vertical alignment
-        if(control->_isAlignmentSet || control->_autoHeight)
+        if (control->_isAlignmentSet || control->_autoHeight)
         {
         {
             if ((control->_alignment & Control::ALIGN_BOTTOM) == Control::ALIGN_BOTTOM)
             if ((control->_alignment & Control::ALIGN_BOTTOM) == Control::ALIGN_BOTTOM)
             {
             {
-                controlBounds.y = clipHeight - controlBounds.height - controlMargin.bottom;
+                control->setY(clipHeight - controlBounds.height - controlMargin.bottom);
             }
             }
             else if ((control->_alignment & Control::ALIGN_VCENTER) == Control::ALIGN_VCENTER)
             else if ((control->_alignment & Control::ALIGN_VCENTER) == Control::ALIGN_VCENTER)
             {
             {
-                controlBounds.y = clipHeight * 0.5f - controlBounds.height * 0.5f;
+                control->setY(clipHeight * 0.5f - controlBounds.height * 0.5f);
             }
             }
             else if ((control->_alignment & Control::ALIGN_TOP) == Control::ALIGN_TOP)
             else if ((control->_alignment & Control::ALIGN_TOP) == Control::ALIGN_TOP)
             {
             {
-                controlBounds.y = controlMargin.top;
+                control->setY(controlMargin.top);
             }
             }
         }
         }
 
 
         // Horizontal alignment
         // Horizontal alignment
-        if(control->_isAlignmentSet || control->_autoWidth)
+        if (control->_isAlignmentSet)
         {
         {
             if ((control->_alignment & Control::ALIGN_RIGHT) == Control::ALIGN_RIGHT)
             if ((control->_alignment & Control::ALIGN_RIGHT) == Control::ALIGN_RIGHT)
             {
             {
-                controlBounds.x = clipWidth - controlBounds.width - controlMargin.right;
+                control->setX(clipWidth - controlBounds.width - controlMargin.right);
             }
             }
             else if ((control->_alignment & Control::ALIGN_HCENTER) == Control::ALIGN_HCENTER)
             else if ((control->_alignment & Control::ALIGN_HCENTER) == Control::ALIGN_HCENTER)
             {
             {
-                controlBounds.x = clipWidth * 0.5f - controlBounds.width * 0.5f;
+                control->setX(clipWidth * 0.5f - controlBounds.width * 0.5f);
             }
             }
             else if ((control->_alignment & Control::ALIGN_LEFT) == Control::ALIGN_LEFT)
             else if ((control->_alignment & Control::ALIGN_LEFT) == Control::ALIGN_LEFT)
             {
             {
-                controlBounds.x = controlMargin.left;
+                control->setX(controlMargin.left);
             }
             }
         }
         }
-
-        control->setBounds(controlBounds);
     }
     }
 }
 }
 
 

+ 1 - 1
gameplay/src/ParticleEmitter.cpp

@@ -9,7 +9,7 @@
 #define PARTICLE_COUNT_MAX                       100
 #define PARTICLE_COUNT_MAX                       100
 #define PARTICLE_EMISSION_RATE                   10
 #define PARTICLE_EMISSION_RATE                   10
 #define PARTICLE_EMISSION_RATE_TIME_INTERVAL     1000.0f / (float)PARTICLE_EMISSION_RATE
 #define PARTICLE_EMISSION_RATE_TIME_INTERVAL     1000.0f / (float)PARTICLE_EMISSION_RATE
-#define PARTICLE_UPDATE_RATE_MAX                 16
+#define PARTICLE_UPDATE_RATE_MAX                 8
 
 
 namespace gameplay
 namespace gameplay
 {
 {

+ 2 - 0
gameplay/src/Platform.cpp

@@ -74,6 +74,8 @@ void Platform::resizeEventInternal(unsigned int width, unsigned int height)
         game->resizeEvent(width, height);
         game->resizeEvent(width, height);
         game->getScriptController()->resizeEvent(width, height);
         game->getScriptController()->resizeEvent(width, height);
     }
     }
+
+    Form::resizeEventInternal(width, height);
 }
 }
 
 
 void Platform::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)
 void Platform::gamepadEventInternal(Gamepad::GamepadEvent evt, Gamepad* gamepad, unsigned int analogIndex)

+ 1 - 2
gameplay/src/Platform.h

@@ -36,12 +36,11 @@ public:
      * Creates a platform for the specified game which it will interact with.
      * Creates a platform for the specified game which it will interact with.
      *
      *
      * @param game The game to create a platform for.
      * @param game The game to create a platform for.
-     * @param attachToWindow The native window handle to optionally attach to.
      * 
      * 
      * @return The created platform interface.
      * @return The created platform interface.
      * @script{ignore}
      * @script{ignore}
      */
      */
-    static Platform* create(Game* game, void* attachToWindow = NULL);
+    static Platform* create(Game* game);
 
 
     /**
     /**
      * Begins processing the platform messages.
      * Begins processing the platform messages.

+ 1 - 1
gameplay/src/PlatformAndroid.cpp

@@ -974,7 +974,7 @@ Platform::~Platform()
 {
 {
 }
 }
 
 
-Platform* Platform::create(Game* game, void* attachToWindow)
+Platform* Platform::create(Game* game)
 {
 {
     Platform* platform = new Platform(game);
     Platform* platform = new Platform(game);
     return platform;
     return platform;

+ 14 - 1
gameplay/src/PlatformBlackBerry.cpp

@@ -3,6 +3,7 @@
 #include "Base.h"
 #include "Base.h"
 #include "Platform.h"
 #include "Platform.h"
 #include "FileSystem.h"
 #include "FileSystem.h"
+#include "SocialController.h"
 #include "Game.h"
 #include "Game.h"
 #include "Form.h"
 #include "Form.h"
 #include "ScriptController.h"
 #include "ScriptController.h"
@@ -689,7 +690,7 @@ Platform::~Platform()
     }
     }
 }
 }
 
 
-Platform* Platform::create(Game* game, void* attachToWindow)
+Platform* Platform::create(Game* game)
 {
 {
     FileSystem::setResourcePath("./app/native/");
     FileSystem::setResourcePath("./app/native/");
     Platform* platform = new Platform(game);
     Platform* platform = new Platform(game);
@@ -792,6 +793,14 @@ Platform* Platform::create(Game* game, void* attachToWindow)
         goto error;
         goto error;
     }
     }
 
 
+    // Window group
+	rc = screen_create_window_group(__screenWindow, "windowgroup");
+	if (rc)
+	{
+		perror("screen_create_window_group failed");
+		goto error;
+	}
+
     // Set/get any window properties.
     // Set/get any window properties.
     rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_FORMAT, &screenFormat);
     rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_FORMAT, &screenFormat);
     if (rc)
     if (rc)
@@ -1086,6 +1095,10 @@ int Platform::enterMessagePump()
             if (event == NULL)
             if (event == NULL)
                 break;
                 break;
 
 
+            // if the social controller needs to deal with the event do that here
+            if (Game::getInstance()->getSocialController()->handleEvent(event))
+            	break;
+
             domain = bps_event_get_domain(event);
             domain = bps_event_get_domain(event);
 
 
             if (domain == screen_get_domain())
             if (domain == screen_get_domain())

+ 1 - 3
gameplay/src/PlatformLinux.cpp

@@ -89,7 +89,6 @@ static Display* __display;
 static Window   __window;
 static Window   __window;
 static int __windowSize[2];
 static int __windowSize[2];
 static GLXContext __context;
 static GLXContext __context;
-static Window __attachToWindow;
 static Atom __atomWmDeleteWindow;
 static Atom __atomWmDeleteWindow;
 static list<ConnectedGamepadDevInfo> __connectedGamepads;
 static list<ConnectedGamepadDevInfo> __connectedGamepads;
 
 
@@ -551,12 +550,11 @@ namespace gameplay
     {
     {
     }
     }
 
 
-    Platform* Platform::create(Game* game, void* attachToWindow)
+    Platform* Platform::create(Game* game)
     {
     {
 
 
         GP_ASSERT(game);
         GP_ASSERT(game);
 
 
-        __attachToWindow = (Window)attachToWindow;
         FileSystem::setResourcePath("./");
         FileSystem::setResourcePath("./");
         Platform* platform = new Platform(game);
         Platform* platform = new Platform(game);
 
 

+ 1 - 3
gameplay/src/PlatformMacOSX.mm

@@ -48,7 +48,6 @@ static bool __shiftDown = false;
 static char* __title = NULL;
 static char* __title = NULL;
 static bool __fullscreen = false;
 static bool __fullscreen = false;
 static bool __resizable = false;
 static bool __resizable = false;
-static void* __attachToWindow = NULL;
 static bool __mouseCaptured = false;
 static bool __mouseCaptured = false;
 static bool __mouseCapturedFirstPass = false;
 static bool __mouseCapturedFirstPass = false;
 static CGPoint __mouseCapturePoint;
 static CGPoint __mouseCapturePoint;
@@ -1623,9 +1622,8 @@ Platform::~Platform()
 }
 }
 
 
     
     
-Platform* Platform::create(Game* game, void* attachToWindow)
+Platform* Platform::create(Game* game)
 {
 {
-    __attachToWindow = attachToWindow;
     Platform* platform = new Platform(game);
     Platform* platform = new Platform(game);
     
     
     return platform;
     return platform;

+ 40 - 59
gameplay/src/PlatformWindows.cpp

@@ -28,7 +28,6 @@ static double __timeStart;
 static double __timeAbsolute;
 static double __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 static bool __vsync = WINDOW_VSYNC;
 static HINSTANCE __hinstance = 0;
 static HINSTANCE __hinstance = 0;
-static HWND __attachToWindow = 0;
 static HWND __hwnd = 0;
 static HWND __hwnd = 0;
 static HDC __hdc = 0;
 static HDC __hdc = 0;
 static HGLRC __hrc = 0;
 static HGLRC __hrc = 0;
@@ -787,7 +786,7 @@ bool initializeGL(WindowCreationParams* params)
     return true;
     return true;
 }
 }
 
 
-Platform* Platform::create(Game* game, void* attachToWindow)
+Platform* Platform::create(Game* game)
 {
 {
     GP_ASSERT(game);
     GP_ASSERT(game);
 
 
@@ -797,8 +796,6 @@ Platform* Platform::create(Game* game, void* attachToWindow)
     // Get the application module handle.
     // Get the application module handle.
     __hinstance = ::GetModuleHandle(NULL);
     __hinstance = ::GetModuleHandle(NULL);
 
 
-    __attachToWindow = (HWND)attachToWindow;
-
     // Read window settings from config.
     // Read window settings from config.
     WindowCreationParams params;
     WindowCreationParams params;
     params.fullscreen = false;
     params.fullscreen = false;
@@ -890,65 +887,52 @@ Platform* Platform::create(Game* game, void* attachToWindow)
         }
         }
     }
     }
 
 
-    if (!__attachToWindow)
+
+    // Register our window class.
+    WNDCLASSEX wc;
+    wc.cbSize = sizeof(WNDCLASSEX);
+    wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+    wc.lpfnWndProc    = (WNDPROC)__WndProc;
+    wc.cbClsExtra     = 0;
+    wc.cbWndExtra     = 0;
+    wc.hInstance      = __hinstance;
+    wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
+    wc.hIconSm        = NULL;
+    wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
+    wc.hbrBackground  = NULL;  // No brush - we are going to paint our own background
+    wc.lpszMenuName   = NULL;  // No default menu
+    wc.lpszClassName  = L"gameplay";
+
+    if (!::RegisterClassEx(&wc))
     {
     {
-        // Register our window class.
-        WNDCLASSEX wc;
-        wc.cbSize = sizeof(WNDCLASSEX);
-        wc.style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
-        wc.lpfnWndProc    = (WNDPROC)__WndProc;
-        wc.cbClsExtra     = 0;
-        wc.cbWndExtra     = 0;
-        wc.hInstance      = __hinstance;
-        wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
-        wc.hIconSm        = NULL;
-        wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
-        wc.hbrBackground  = NULL;  // No brush - we are going to paint our own background
-        wc.lpszMenuName   = NULL;  // No default menu
-        wc.lpszClassName  = L"gameplay";
-
-        if (!::RegisterClassEx(&wc))
-        {
-            GP_ERROR("Failed to register window class.");
-            goto error;
-        }
+        GP_ERROR("Failed to register window class.");
+        goto error;
+    }
 
 
-        if (params.fullscreen)
+    if (params.fullscreen)
+    {
+        DEVMODE dm;
+        memset(&dm, 0, sizeof(dm));
+        dm.dmSize= sizeof(dm);
+        dm.dmPelsWidth  = width;
+        dm.dmPelsHeight = height;
+        dm.dmBitsPerPel = DEFAULT_COLOR_BUFFER_SIZE;
+        dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
+
+        // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar.
+        if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
         {
         {
-            DEVMODE dm;
-            memset(&dm, 0, sizeof(dm));
-            dm.dmSize= sizeof(dm);
-            dm.dmPelsWidth  = width;
-            dm.dmPelsHeight = height;
-            dm.dmBitsPerPel = DEFAULT_COLOR_BUFFER_SIZE;
-            dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
-
-            // Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar.
-            if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
-            {
-                params.fullscreen = false;
-                GP_ERROR("Failed to start game in full-screen mode with resolution %dx%d.", width, height);
-                goto error;
-            }
-        }
-
-        if (!initializeGL(&params))
+            params.fullscreen = false;
+            GP_ERROR("Failed to start game in full-screen mode with resolution %dx%d.", width, height);
             goto error;
             goto error;
-
-        // Show the window.
-        ShowWindow(__hwnd, SW_SHOW);
+        }
     }
     }
-    else
-    {
-        // Attach to a previous windows
-        __hwnd = (HWND)__attachToWindow;
-        __hdc = GetDC(__hwnd);
 
 
-        SetWindowLongPtr(__hwnd, GWLP_WNDPROC, (LONG)(WNDPROC)__WndProc);
+    if (!initializeGL(&params))
+        goto error;
 
 
-        if (!initializeGL(NULL))
-            goto error;
-    }
+    // Show the window.
+    ShowWindow(__hwnd, SW_SHOW);
 
 
 #ifdef GP_USE_GAMEPAD
 #ifdef GP_USE_GAMEPAD
     // Initialize XInputGamepads.
     // Initialize XInputGamepads.
@@ -992,9 +976,6 @@ int Platform::enterMessagePump()
     if (_game->getState() != Game::RUNNING)
     if (_game->getState() != Game::RUNNING)
         _game->run();
         _game->run();
 
 
-    if (__attachToWindow)
-        return 0;
-
     // Enter event dispatch loop.
     // Enter event dispatch loop.
     MSG msg;
     MSG msg;
     while (true)
     while (true)

+ 6 - 1
gameplay/src/PlatformiOS.mm

@@ -863,6 +863,11 @@ int getUnicode(int key);
     return YES;
     return YES;
 }
 }
 
 
+- (BOOL)prefersStatusBarHidden
+{
+    return YES;
+}
+
 - (void)getAccelerometerPitch:(float*)pitch roll:(float*)roll 
 - (void)getAccelerometerPitch:(float*)pitch roll:(float*)roll 
 {
 {
     float p = 0.0f;
     float p = 0.0f;
@@ -1336,7 +1341,7 @@ Platform::~Platform()
 {
 {
 }
 }
 
 
-Platform* Platform::create(Game* game, void* attachToWindow)
+Platform* Platform::create(Game* game)
 {
 {
     Platform* platform = new Platform(game);
     Platform* platform = new Platform(game);
     return platform;
     return platform;

+ 14 - 18
gameplay/src/Properties.cpp

@@ -184,7 +184,7 @@ void Properties::readProperties(Stream* stream)
                 name = trimWhiteSpace(name);
                 name = trimWhiteSpace(name);
 
 
                 // Scan for next token, the property's value.
                 // Scan for next token, the property's value.
-                value = strtok(NULL, "=");
+                value = strtok(NULL, "");
                 if (value == NULL)
                 if (value == NULL)
                 {
                 {
                     GP_ERROR("Error parsing properties file: attribute with name ('%s') but no value.", name);
                     GP_ERROR("Error parsing properties file: attribute with name ('%s') but no value.", name);
@@ -594,30 +594,26 @@ void Properties::rewind()
     _namespacesItr = _namespaces.end();
     _namespacesItr = _namespaces.end();
 }
 }
 
 
-Properties* Properties::getNamespace(const char* id, bool searchNames) const
+Properties* Properties::getNamespace(const char* id, bool searchNames, bool recurse) const
 {
 {
     GP_ASSERT(id);
     GP_ASSERT(id);
 
 
-    Properties* ret = NULL;
-    std::vector<Properties*>::const_iterator it;
-    
-    for (it = _namespaces.begin(); it < _namespaces.end(); ++it)
+    for (std::vector<Properties*>::const_iterator it = _namespaces.begin(); it < _namespaces.end(); ++it)
     {
     {
-        ret = *it;
-        if (strcmp(searchNames ? ret->_namespace.c_str() : ret->_id.c_str(), id) == 0)
-        {
-            return ret;
-        }
+        Properties* p = *it;
+        if (strcmp(searchNames ? p->_namespace.c_str() : p->_id.c_str(), id) == 0)
+            return p;
         
         
-        // Search recursively.
-        ret = ret->getNamespace(id, searchNames);
-        if (ret != NULL)
+        if (recurse)
         {
         {
-            return ret;
+            // Search recursively.
+            p = p->getNamespace(id, searchNames, true);
+            if (p)
+                return p;
         }
         }
     }
     }
 
 
-    return ret;
+    return NULL;
 }
 }
 
 
 const char* Properties::getNamespace() const
 const char* Properties::getNamespace() const
@@ -704,7 +700,7 @@ Properties::Type Properties::getType(const char* name) const
     }
     }
 }
 }
 
 
-const char* Properties::getString(const char* name) const
+const char* Properties::getString(const char* name, const char* defaultValue) const
 {
 {
     if (name)
     if (name)
     {
     {
@@ -722,7 +718,7 @@ const char* Properties::getString(const char* name) const
         }
         }
     }
     }
 
 
-    return NULL;
+    return defaultValue;
 }
 }
 
 
 bool Properties::getBool(const char* name, bool defaultValue) const
 bool Properties::getBool(const char* name, bool defaultValue) const

+ 8 - 5
gameplay/src/Properties.h

@@ -182,18 +182,20 @@ public:
     void rewind();
     void rewind();
 
 
     /**
     /**
-     * Get a specific namespace by ID or name. This method will perform
-     * a depth-first search on all namespaces and inner namespaces within
-     * this Property.
+     * Get a specific namespace by ID or name. This method will optionally
+     * perform a depth-first search on all namespaces and inner namespaces
+     * within this Property.
      *
      *
      * @param id The ID or name of the namespace to find.
      * @param id The ID or name of the namespace to find.
      * @param searchNames If true, namespace names are used in the search,
      * @param searchNames If true, namespace names are used in the search,
      *      instead of namespace IDs. By default this parameter is false
      *      instead of namespace IDs. By default this parameter is false
      *      and namespace IDs are searched.
      *      and namespace IDs are searched.
+     * @param recurse If true, perform a depth-first search, otherwise search
+     *      only the immediate child namespaces.
      * 
      * 
      * @return A properties object with the given ID or name.
      * @return A properties object with the given ID or name.
      */
      */
-    Properties* getNamespace(const char* id, bool searchNames = false) const;
+    Properties* getNamespace(const char* id, bool searchNames = false, bool recurse = true) const;
 
 
     /**
     /**
      * Get the name of this Property's namespace.
      * Get the name of this Property's namespace.
@@ -233,10 +235,11 @@ public:
      * whatever the intended type of the property.
      * whatever the intended type of the property.
      *
      *
      * @param name The name of the property to interpret, or NULL to return the current property's value.
      * @param name The name of the property to interpret, or NULL to return the current property's value.
+     * @param defaultValue The default value to return if the specified property does not exist.
      * 
      * 
      * @return The value of the given property as a string, or the empty string if no property with that name exists.
      * @return The value of the given property as a string, or the empty string if no property with that name exists.
      */
      */
-    const char* getString(const char* name = NULL) const;
+    const char* getString(const char* name = NULL, const char* defaultValue = NULL) const;
 
 
     /**
     /**
      * Interpret the value of the given property as a boolean.
      * Interpret the value of the given property as a boolean.

+ 13 - 3
gameplay/src/RadioButton.cpp

@@ -196,11 +196,21 @@ void RadioButton::update(const Control* container, const Vector2& offset)
     {
     {
         size.set(_imageSize);
         size.set(_imageSize);
     }
     }
-    float iconWidth = size.x;
 
 
-    _textBounds.x += iconWidth + 5;
-    _textBounds.width -= iconWidth + 5;
+    if (_autoWidth == Control::AUTO_SIZE_FIT)
+    {
+        // Text-only width was already measured in Label::update - append image
+        setWidth(size.x + _bounds.width + 5);
+    }
+
+    if (_autoHeight == Control::AUTO_SIZE_FIT)
+    {
+        // Text-only width was already measured in Label::update - append image
+        setHeight(std::max(getHeight(), size.y));
+    }
 
 
+    _textBounds.x += size.x + 5;
+    
     if (_selected)
     if (_selected)
     {
     {
         _image = getImage("selected", _state);
         _image = getImage("selected", _state);

+ 10 - 10
gameplay/src/RenderState.cpp

@@ -315,7 +315,7 @@ void RenderState::applyAutoBinding(const char* uniformName, const char* autoBind
         else
         else
         {
         {
             bound = false;
             bound = false;
-            GP_WARN("Unsupported auto binding type (%d).", autoBinding);
+            GP_WARN("Unsupported auto binding type (%s).", autoBinding);
         }
         }
     }
     }
 
 
@@ -471,7 +471,7 @@ RenderState* RenderState::getTopmost(RenderState* below)
         }
         }
         rs = rs->_parent;
         rs = rs->_parent;
     }
     }
-    
+
     return NULL;
     return NULL;
 }
 }
 
 
@@ -514,8 +514,8 @@ void RenderState::cloneInto(RenderState* renderState, NodeCloneContext& context)
 RenderState::StateBlock::StateBlock()
 RenderState::StateBlock::StateBlock()
     : _cullFaceEnabled(false), _depthTestEnabled(false), _depthWriteEnabled(true), _depthFunction(RenderState::DEPTH_LESS),
     : _cullFaceEnabled(false), _depthTestEnabled(false), _depthWriteEnabled(true), _depthFunction(RenderState::DEPTH_LESS),
       _blendEnabled(false), _blendSrc(RenderState::BLEND_ONE), _blendDst(RenderState::BLEND_ZERO),
       _blendEnabled(false), _blendSrc(RenderState::BLEND_ONE), _blendDst(RenderState::BLEND_ZERO),
-      _cullFaceSide(CULL_FACE_SIDE_BACK), _frontFace(FRONT_FACE_CCW), _stencilTestEnabled(false), _stencilWrite(RS_ALL_ONES), 
-	  _stencilFunction(RenderState::STENCIL_ALWAYS), _stencilFunctionRef(0), _stencilFunctionMask(RS_ALL_ONES), 
+      _cullFaceSide(CULL_FACE_SIDE_BACK), _frontFace(FRONT_FACE_CCW), _stencilTestEnabled(false), _stencilWrite(RS_ALL_ONES),
+	  _stencilFunction(RenderState::STENCIL_ALWAYS), _stencilFunctionRef(0), _stencilFunctionMask(RS_ALL_ONES),
 	  _stencilOpSfail(RenderState::STENCIL_OP_KEEP), _stencilOpDpfail(RenderState::STENCIL_OP_KEEP), _stencilOpDppass(RenderState::STENCIL_OP_KEEP),
 	  _stencilOpSfail(RenderState::STENCIL_OP_KEEP), _stencilOpDpfail(RenderState::STENCIL_OP_KEEP), _stencilOpDppass(RenderState::STENCIL_OP_KEEP),
       _bits(0L)
       _bits(0L)
 {
 {
@@ -586,9 +586,9 @@ void RenderState::StateBlock::bindNoRestore()
     }
     }
     if ((_bits & RS_DEPTH_TEST) && (_depthTestEnabled != _defaultState->_depthTestEnabled))
     if ((_bits & RS_DEPTH_TEST) && (_depthTestEnabled != _defaultState->_depthTestEnabled))
     {
     {
-        if (_depthTestEnabled) 
+        if (_depthTestEnabled)
             GL_ASSERT( glEnable(GL_DEPTH_TEST) );
             GL_ASSERT( glEnable(GL_DEPTH_TEST) );
-        else 
+        else
             GL_ASSERT( glDisable(GL_DEPTH_TEST) );
             GL_ASSERT( glDisable(GL_DEPTH_TEST) );
         _defaultState->_depthTestEnabled = _depthTestEnabled;
         _defaultState->_depthTestEnabled = _depthTestEnabled;
     }
     }
@@ -604,9 +604,9 @@ void RenderState::StateBlock::bindNoRestore()
     }
     }
 	if ((_bits & RS_STENCIL_TEST) && (_stencilTestEnabled != _defaultState->_stencilTestEnabled))
 	if ((_bits & RS_STENCIL_TEST) && (_stencilTestEnabled != _defaultState->_stencilTestEnabled))
     {
     {
-        if (_stencilTestEnabled) 
+        if (_stencilTestEnabled)
 			GL_ASSERT( glEnable(GL_STENCIL_TEST) );
 			GL_ASSERT( glEnable(GL_STENCIL_TEST) );
-        else 
+        else
             GL_ASSERT( glDisable(GL_STENCIL_TEST) );
             GL_ASSERT( glDisable(GL_STENCIL_TEST) );
         _defaultState->_stencilTestEnabled = _stencilTestEnabled;
         _defaultState->_stencilTestEnabled = _stencilTestEnabled;
     }
     }
@@ -615,7 +615,7 @@ void RenderState::StateBlock::bindNoRestore()
 		GL_ASSERT( glStencilMask(_stencilWrite) );
 		GL_ASSERT( glStencilMask(_stencilWrite) );
         _defaultState->_stencilWrite = _stencilWrite;
         _defaultState->_stencilWrite = _stencilWrite;
     }
     }
-	if ((_bits & RS_STENCIL_FUNC) && (_stencilFunction != _defaultState->_stencilFunction || 
+	if ((_bits & RS_STENCIL_FUNC) && (_stencilFunction != _defaultState->_stencilFunction ||
 										_stencilFunctionRef != _defaultState->_stencilFunctionRef ||
 										_stencilFunctionRef != _defaultState->_stencilFunctionRef ||
 										_stencilFunctionMask != _defaultState->_stencilFunctionMask))
 										_stencilFunctionMask != _defaultState->_stencilFunctionMask))
     {
     {
@@ -624,7 +624,7 @@ void RenderState::StateBlock::bindNoRestore()
 		_defaultState->_stencilFunctionRef = _stencilFunctionRef;
 		_defaultState->_stencilFunctionRef = _stencilFunctionRef;
 		_defaultState->_stencilFunctionMask = _stencilFunctionMask;
 		_defaultState->_stencilFunctionMask = _stencilFunctionMask;
     }
     }
-	if ((_bits & RS_STENCIL_OP) && (_stencilOpSfail != _defaultState->_stencilOpSfail || 
+	if ((_bits & RS_STENCIL_OP) && (_stencilOpSfail != _defaultState->_stencilOpSfail ||
 									_stencilOpDpfail != _defaultState->_stencilOpDpfail ||
 									_stencilOpDpfail != _defaultState->_stencilOpDpfail ||
 									_stencilOpDppass != _defaultState->_stencilOpDppass))
 									_stencilOpDppass != _defaultState->_stencilOpDppass))
     {
     {

+ 17 - 5
gameplay/src/ScriptController.cpp

@@ -431,12 +431,20 @@ void ScriptController::loadScript(const char* path, bool forceReload)
     std::set<std::string>::iterator iter = _loadedScripts.find(path);
     std::set<std::string>::iterator iter = _loadedScripts.find(path);
     if (iter == _loadedScripts.end() || forceReload)
     if (iter == _loadedScripts.end() || forceReload)
     {
     {
+        bool success = false;
+        if (iter == _loadedScripts.end())
+            _loadedScripts.insert(path); // insert before loading script to prevent load recursion
+
 #ifdef __ANDROID__
 #ifdef __ANDROID__
         const char* scriptContents = FileSystem::readAll(path);
         const char* scriptContents = FileSystem::readAll(path);
         if (luaL_dostring(_lua, scriptContents))
         if (luaL_dostring(_lua, scriptContents))
         {
         {
             GP_WARN("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1));
             GP_WARN("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1));
         }
         }
+        else
+        {
+            success = true;
+        }
         SAFE_DELETE_ARRAY(scriptContents);
         SAFE_DELETE_ARRAY(scriptContents);
 #else
 #else
         std::string fullPath;
         std::string fullPath;
@@ -449,10 +457,15 @@ void ScriptController::loadScript(const char* path, bool forceReload)
         {
         {
             GP_WARN("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1));
             GP_WARN("Failed to run Lua script with error: '%s'.", lua_tostring(_lua, -1));
         }
         }
+        else
+        {
+            success = true;
+        }
 #endif
 #endif
-        if (iter == _loadedScripts.end())
+        if (!success && (iter == _loadedScripts.end()))
         {
         {
-            _loadedScripts.insert(path);
+            iter = _loadedScripts.find(path);
+            _loadedScripts.erase(iter);
         }
         }
     }
     }
 }
 }
@@ -463,11 +476,10 @@ std::string ScriptController::loadUrl(const char* url)
     std::string id;
     std::string id;
     splitURL(url, &file, &id);
     splitURL(url, &file, &id);
 
 
-    // Make sure the function isn't empty.
     if (id.size() <= 0)
     if (id.size() <= 0)
     {
     {
-        GP_ERROR("Got an empty function name when parsing function url '%s'.", url);
-        return std::string();
+        // The url does not reference a script - only a function
+        return file;
     }
     }
 
 
     // Ensure the script is loaded.
     // Ensure the script is loaded.

+ 14 - 2
gameplay/src/Slider.cpp

@@ -126,7 +126,7 @@ bool Slider::isValueTextVisible() const
 
 
 void Slider::setValueTextAlignment(Font::Justify alignment)
 void Slider::setValueTextAlignment(Font::Justify alignment)
 {
 {
-    if (alignment != _alignment)
+    if (alignment != _valueTextAlignment)
     {
     {
         _dirty = true;
         _dirty = true;
     }
     }
@@ -495,7 +495,7 @@ void Slider::update(const Control* container, const Vector2& offset)
         {
         {
             _value += (total * GAMEPAD_FRACTION) * _delta;
             _value += (total * GAMEPAD_FRACTION) * _delta;
         }
         }
-            
+
         if (_value > _max)
         if (_value > _max)
             _value = _max;
             _value = _max;
         else if (_value < _min)
         else if (_value < _min)
@@ -506,6 +506,18 @@ void Slider::update(const Control* container, const Vector2& offset)
             notifyListeners(Control::Listener::VALUE_CHANGED);
             notifyListeners(Control::Listener::VALUE_CHANGED);
         }
         }
     }
     }
+
+    if (_autoHeight == Control::AUTO_SIZE_FIT)
+    {
+        float height = _minImage->getRegion().height;
+        height = std::max(height, _maxImage->getRegion().height);
+        height = std::max(height, _markerImage->getRegion().height);
+        height = std::max(height, _trackImage->getRegion().height);
+        height += _bounds.height;
+        if (_valueTextVisible && _font)
+            height += getFontSize(_state);
+        setHeight(height);
+    }
 }
 }
 
 
 void Slider::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight)
 void Slider::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight)

+ 9 - 2
gameplay/src/SocialAchievement.h

@@ -5,7 +5,9 @@ namespace gameplay
 {
 {
 
 
 /**
 /**
- * Defines a class for typical social game activities running with an authenticated session.
+ * Defines a social achievement in a game.
+ *
+ * @script{ignore}
  */
  */
 class SocialAchievement
 class SocialAchievement
 {
 {
@@ -13,10 +15,15 @@ class SocialAchievement
 public:
 public:
 
 
     /**
     /**
-     * The name/title of the achievement.
+     * The name of the achievement.
      */
      */
     std::string name;
     std::string name;
 
 
+    /**
+     * The title of the achievement.
+     */
+    std::string title;
+
     /**
     /**
      * The value of progress (0 to getTotal) representing the current unit value of completion.
      * The value of progress (0 to getTotal) representing the current unit value of completion.
      */
      */

+ 16 - 0
gameplay/src/SocialChallenge.cpp

@@ -0,0 +1,16 @@
+#include "Base.h"
+#include "SocialChallenge.h"
+
+namespace gameplay
+{
+
+SocialChallenge::SocialChallenge()
+    : state(INVALID), score(0.0f)
+{
+}
+
+SocialChallenge::~SocialChallenge()
+{
+}
+
+}

+ 86 - 0
gameplay/src/SocialChallenge.h

@@ -0,0 +1,86 @@
+#ifndef SOCIALCHALLENGE_H_
+#define SOCIALCHALLENGE_H_
+
+namespace gameplay
+{
+
+/**
+ * Defines a social challenge between social players.
+ *
+ * @script{ignore}
+ */
+class SocialChallenge
+{
+
+public:
+
+	/**
+	 * The challenge state.
+	 */
+    enum State
+    {
+        PENDING,
+        COMPLETE,
+        DECLINED,
+        INVALID
+    };
+
+    /**
+     * The name of the challenge.
+     */
+    std::string name;
+
+    /**
+     * The title of the challenge.
+     */
+    std::string title;
+
+    /**
+     * The name of the player issuing the challenge.
+     */
+    std::string issuedPlayerName;
+
+    /**
+     * The name of the player being challenged.
+     */
+    std::string challengedPlayerName;
+
+    /**
+     * The state of the challenge.
+     */
+    State state;
+
+    /**
+     * The score for the challenge.
+     */
+    float score;
+
+    /**
+     * The date/time the challenge was issued. (UTC string format "2013-06-27T07:40::05")
+     */
+    std::string dateTimeIssued;
+
+    /**
+     * The date/time the challenge was completed. (UTC string format "2013-06-27T07:40::05")
+     */
+    std::string dateTimeCompleted;
+
+    /**
+     * The provider handle for an challenge.
+     */
+    SocialChallengeHandle handle;
+
+    /**
+     * Constructor.
+     */
+    SocialChallenge();
+
+    /**
+     * Destructor.
+     */
+    ~SocialChallenge();
+};
+
+}
+
+#endif

+ 51 - 5
gameplay/src/SocialController.cpp

@@ -2,6 +2,7 @@
 #include "SocialController.h"
 #include "SocialController.h"
 #include "Game.h"
 #include "Game.h"
 #include "social/ScoreloopSocialSession.h"
 #include "social/ScoreloopSocialSession.h"
+#include "social/GoogleGamesSocialSession.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {
@@ -20,6 +21,18 @@ void SocialController::initialize()
 }
 }
 
 
 void SocialController::finalize()
 void SocialController::finalize()
+{
+	if (_session)
+		_session->synchronizeAchievements();
+}
+
+void SocialController::pause()
+{
+	if (_session)
+		_session->synchronizeAchievements();
+}
+
+void SocialController::resume()
 {
 {
 }
 }
 
 
@@ -27,20 +40,53 @@ void SocialController::update(float elapsedTime)
 {
 {
 }
 }
 
 
+bool SocialController::handleEvent(void *event)
+{
+	if (_session)
+		return _session->handleEvent(event);
+
+	return false;
+}
+
 void SocialController::authenticate(SocialSessionListener* listener)
 void SocialController::authenticate(SocialSessionListener* listener)
 {
 {
-#if defined(__QNX__) && defined(GP_USE_SOCIAL)
-    Properties* socialProperties = Game::getInstance()->getConfig()->getNamespace("social");
-    const char* providerStr = socialProperties->getString("provider");
-    if(strcmp(providerStr, "Scoreloop") == 0)
+#ifdef GP_USE_SOCIAL
+#if defined(__QNX__)
+    Properties* socialProperties = Game::getInstance()->getConfig()->getNamespace("social", true);
+    const char* providerStr = "";
+
+    if (socialProperties)
     {
     {
-        ScoreloopSocialSession::authenticate(listener, socialProperties);
+    	providerStr = socialProperties->getString("provider");
+    }
+
+    if (strcmp(providerStr, "Scoreloop") == 0)
+    {
+        _session = ScoreloopSocialSession::authenticate(listener, socialProperties);
+    }
+    else
+    {
+        listener->authenticateEvent(SocialSessionListener::ERROR_INITIALIZATION, NULL);
+    }
+#elif defined(__ANDROID__)
+    Properties* socialProperties = Game::getInstance()->getConfig()->getNamespace("social", true);
+    const char* providerStr = "";
+
+    if (socialProperties)
+    {
+    	providerStr = socialProperties->getString("provider");
+    }
+
+    if (strcmp(providerStr, "GoogleGames") == 0)
+    {
+        _session = GoogleGamesSocialSession::authenticate(listener, socialProperties);
     }
     }
     else
     else
     {
     {
         listener->authenticateEvent(SocialSessionListener::ERROR_INITIALIZATION, NULL);
         listener->authenticateEvent(SocialSessionListener::ERROR_INITIALIZATION, NULL);
     }
     }
 #endif
 #endif
+#endif
 }
 }
 
 
 }
 }

+ 20 - 4
gameplay/src/SocialController.h

@@ -21,9 +21,9 @@ namespace gameplay
          provider = Scoreloop
          provider = Scoreloop
          id  = d346c484-12aa-49a2-a0a0-de2f87492d72
          id  = d346c484-12aa-49a2-a0a0-de2f87492d72
          secret = aAa+DehBfyGO/CYaE3nWomgu7SIbWFczUih+Qwf3/n7u0y3nyq5Hag==
          secret = aAa+DehBfyGO/CYaE3nWomgu7SIbWFczUih+Qwf3/n7u0y3nyq5Hag==
-         version = "1.0"
-         language = "en"
-         currency = "ASC"
+         version = 1.0
+         language = en
+         currency = ASC
          leaderboard_mappings
          leaderboard_mappings
          {
          {
              // Format: leaderboardId = provider value
              // Format: leaderboardId = provider value
@@ -32,7 +32,8 @@ namespace gameplay
              hard = 2
              hard = 2
          }
          }
     }
     }
-
+ *
+ * @script{ignore}
  */
  */
 class SocialController
 class SocialController
 {
 {
@@ -47,6 +48,11 @@ public:
      */
      */
     void authenticate(SocialSessionListener* listener);
     void authenticate(SocialSessionListener* listener);
 
 
+    /**
+     * Handle the event from the event loop if needed.
+     */
+    bool handleEvent(void *event);
+
 private:
 private:
 
 
     /**
     /**
@@ -69,6 +75,16 @@ private:
      */
      */
     void finalize();
     void finalize();
 
 
+    /**
+     * Pauses the controller.
+     */
+    void pause();
+
+    /**
+     * Resumes the controller.
+     */
+    void resume();
+
     /**
     /**
      * Callback for when the controller receives a frame update event.
      * Callback for when the controller receives a frame update event.
      */
      */

+ 2 - 0
gameplay/src/SocialPlayer.h

@@ -8,6 +8,8 @@ namespace gameplay
  * Defines a social player.
  * Defines a social player.
  *
  *
  * This can either be the authenticated user, friend or community user (not friend yet...).
  * This can either be the authenticated user, friend or community user (not friend yet...).
+ *
+ * @script{ignore}
  */
  */
 class SocialPlayer
 class SocialPlayer
 {
 {

+ 3 - 1
gameplay/src/SocialScore.h

@@ -5,7 +5,9 @@ namespace gameplay
 {
 {
 
 
 /**
 /**
- * Defines an abstract class for a score that resides in a leaderboard
+ * Defines an abstract class for a score that resides in a leaderboard.
+ *
+ * @script{ignore}
  */
  */
 class SocialScore
 class SocialScore
 {
 {

+ 26 - 3
gameplay/src/SocialSession.h

@@ -5,6 +5,7 @@
 #include "SocialPlayer.h"
 #include "SocialPlayer.h"
 #include "SocialAchievement.h"
 #include "SocialAchievement.h"
 #include "SocialScore.h"
 #include "SocialScore.h"
+#include "SocialChallenge.h"
 #include "Properties.h"
 #include "Properties.h"
 
 
 namespace gameplay
 namespace gameplay
@@ -12,6 +13,8 @@ namespace gameplay
 
 
 /**
 /**
  * Defines an abstract class for typical social game activities running with an authenticated session.
  * Defines an abstract class for typical social game activities running with an authenticated session.
+ *
+ * @script{ignore}
  */
  */
 class SocialSession
 class SocialSession
 {
 {
@@ -22,7 +25,7 @@ public:
     enum CommunityScope
     enum CommunityScope
     {
     {
         COMMUNITY_SCOPE_FRIENDS,
         COMMUNITY_SCOPE_FRIENDS,
-        COMMUNITY_SCOPE_ALL,
+        COMMUNITY_SCOPE_ALL
     };
     };
 
 
     enum TimeScope
     enum TimeScope
@@ -39,13 +42,17 @@ public:
      */
      */
     virtual SocialSessionListener* getListener() = 0;
     virtual SocialSessionListener* getListener() = 0;
 
 
-    virtual SocialPlayer* getUser() = 0;
+    virtual const SocialPlayer& getUser() const = 0;
 
 
     virtual void loadFriends() = 0;
     virtual void loadFriends() = 0;
 
 
     virtual void loadAchievements() = 0;
     virtual void loadAchievements() = 0;
 
 
-    virtual void submitAchievement(const char* achievementId, unsigned int value) = 0;
+    virtual void submitAchievement(const char* achievementId, unsigned int value, bool achieved=false) = 0;
+
+    virtual void incrementAchievement(const char* achievementId, unsigned int increment=1) = 0;
+
+    virtual void synchronizeAchievements() = 0;
 
 
     /**
     /**
      * Asynchronously request the scores for the count where the player is in the middle.
      * Asynchronously request the scores for the count where the player is in the middle.
@@ -67,10 +74,26 @@ public:
 
 
     virtual void submitScore(const char* leaderboardId, float value) = 0;
     virtual void submitScore(const char* leaderboardId, float value) = 0;
 
 
+    virtual void submitChallenge(const SocialPlayer *player, unsigned int wager, float score, const char* leaderboardId=0) = 0;
+
+    virtual void loadChallenges(bool showOpenChallengesOnly=true) = 0;
+
+    virtual void replyToChallenge(const SocialChallenge *challenge, bool accept) = 0;
+
     virtual void loadSavedData(const char* key) = 0;
     virtual void loadSavedData(const char* key) = 0;
 
 
     virtual void submitSavedData(const char* key, std::string data) = 0;
     virtual void submitSavedData(const char* key, std::string data) = 0;
 
 
+    virtual void displayLeaderboard(const char* leaderboardId) = 0;
+
+    virtual void displayAchievements() = 0;
+
+    virtual void displayChallenges() = 0;
+
+    virtual void displayChallengeSubmit(const SocialChallenge *challenge, float score) = 0;
+
+    virtual bool handleEvent(void *event) { return true; }
+
 protected:
 protected:
 
 
     /**
     /**

+ 40 - 0
gameplay/src/SocialSessionListener.cpp

@@ -27,10 +27,18 @@ void SocialSessionListener::loadAchievementsEvent(ResponseCode code, std::vector
 {
 {
 }
 }
 
 
+void SocialSessionListener::synchronizeAchievementEvent(ResponseCode code)
+{
+}
+
 void SocialSessionListener::submitAchievementEvent(ResponseCode code)
 void SocialSessionListener::submitAchievementEvent(ResponseCode code)
 {
 {
 }
 }
 
 
+void SocialSessionListener::awardAchievedEvent(ResponseCode code, const SocialAchievement &achievement)
+{
+}
+
 void SocialSessionListener::loadScoresEvent(ResponseCode code, std::vector<SocialScore> scores)
 void SocialSessionListener::loadScoresEvent(ResponseCode code, std::vector<SocialScore> scores)
 {
 {
 }
 }
@@ -39,6 +47,22 @@ void SocialSessionListener::submitScoreEvent(ResponseCode code)
 {
 {
 }
 }
 
 
+void SocialSessionListener::submitChallengeEvent(ResponseCode code, const SocialChallenge &challenge)
+{
+}
+
+void SocialSessionListener::startChallengeEvent(ResponseCode code, const SocialChallenge &challenge)
+{
+}
+
+void SocialSessionListener::replyToChallengeEvent(ResponseCode code)
+{
+}
+
+void SocialSessionListener::loadChallengesEvent(ResponseCode code, std::vector<SocialChallenge> challenges)
+{
+}
+
 void SocialSessionListener::loadSavedDataEvent(ResponseCode code, std::string data)
 void SocialSessionListener::loadSavedDataEvent(ResponseCode code, std::string data)
 {
 {
 }
 }
@@ -47,6 +71,22 @@ void SocialSessionListener::submitSavedDataEvent(ResponseCode code)
 {
 {
 }
 }
 
 
+void SocialSessionListener::uiEvent(ResponseCode code, std::string errorMessage)
+{
+}
+
+void SocialSessionListener::displayedLeaderboardEvent(ResponseCode code, std::string errorMessage)
+{
+}
+
+void SocialSessionListener::displayedAchievementsEvent(ResponseCode code, std::string errorMessage)
+{
+}
+
+void SocialSessionListener::displayedChallengesEvent(ResponseCode code, std::string errorMessage)
+{
+}
+
 }
 }
 
 
 
 

+ 25 - 0
gameplay/src/SocialSessionListener.h

@@ -4,6 +4,7 @@
 #include "SocialPlayer.h"
 #include "SocialPlayer.h"
 #include "SocialAchievement.h"
 #include "SocialAchievement.h"
 #include "SocialScore.h"
 #include "SocialScore.h"
+#include "SocialChallenge.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {
@@ -12,6 +13,8 @@ class SocialSession;
 
 
 /**
 /**
  * Defines a class for handling session responses to various session request.
  * Defines a class for handling session responses to various session request.
+ *
+ * @script{ignore}
  */
  */
 class SocialSessionListener
 class SocialSessionListener
 {
 {
@@ -43,6 +46,8 @@ public:
         ERROR_INVALID_USER,
         ERROR_INVALID_USER,
         ERROR_INVALID_ARG,
         ERROR_INVALID_ARG,
         ERROR_SERVER,
         ERROR_SERVER,
+        ERROR_CANCELLED,
+        ERROR_NOT_SUPPORTED,
         ERROR_UNKNOWN
         ERROR_UNKNOWN
     };
     };
 
 
@@ -52,16 +57,36 @@ public:
 
 
     virtual void loadAchievementsEvent(ResponseCode code, std::vector<SocialAchievement> achievements);
     virtual void loadAchievementsEvent(ResponseCode code, std::vector<SocialAchievement> achievements);
 
 
+    virtual void synchronizeAchievementEvent(ResponseCode code);
+
     virtual void submitAchievementEvent(ResponseCode code);
     virtual void submitAchievementEvent(ResponseCode code);
 
 
+    virtual void awardAchievedEvent(ResponseCode code, const SocialAchievement &achievement);
+
     virtual void loadScoresEvent(ResponseCode code, std::vector<SocialScore> scores);
     virtual void loadScoresEvent(ResponseCode code, std::vector<SocialScore> scores);
 
 
     virtual void submitScoreEvent(ResponseCode code);
     virtual void submitScoreEvent(ResponseCode code);
 
 
+    virtual void submitChallengeEvent(ResponseCode code, const SocialChallenge &challenge);
+
+    virtual void startChallengeEvent(ResponseCode code, const SocialChallenge &challenge);
+
+    virtual void replyToChallengeEvent(ResponseCode code);
+
+    virtual void loadChallengesEvent(ResponseCode code, std::vector<SocialChallenge> challenges);
+
     virtual void loadSavedDataEvent(ResponseCode code, std::string data);
     virtual void loadSavedDataEvent(ResponseCode code, std::string data);
 
 
     virtual void submitSavedDataEvent(ResponseCode code);
     virtual void submitSavedDataEvent(ResponseCode code);
 
 
+    virtual void uiEvent(ResponseCode code, std::string errorMessage="");
+
+    virtual void displayedLeaderboardEvent(ResponseCode code, std::string errorMessage="");
+
+    virtual void displayedAchievementsEvent(ResponseCode code, std::string errorMessage="");
+
+    virtual void displayedChallengesEvent(ResponseCode code, std::string errorMessage="");
+
 };
 };
 
 
 }
 }

+ 1 - 1
gameplay/src/SpriteBatch.cpp

@@ -133,7 +133,7 @@ SpriteBatch* SpriteBatch::create(Texture* texture,  Effect* effect, unsigned int
 
 
 	// Bind an ortho projection to the material by default (user can override with setProjectionMatrix)
 	// Bind an ortho projection to the material by default (user can override with setProjectionMatrix)
 	Game* game = Game::getInstance();
 	Game* game = Game::getInstance();
-	Matrix::createOrthographicOffCenter(0, game->getWidth(), game->getHeight(), 0, 0, 1, &batch->_projectionMatrix);
+    Matrix::createOrthographicOffCenter(0, game->getViewport().width, game->getViewport().height, 0, 0, 1, &batch->_projectionMatrix);
 	material->getParameter("u_projectionMatrix")->bindValue(batch, &SpriteBatch::getProjectionMatrix);
 	material->getParameter("u_projectionMatrix")->bindValue(batch, &SpriteBatch::getProjectionMatrix);
 	
 	
     return batch;
     return batch;

+ 11 - 9
gameplay/src/Theme.cpp

@@ -88,12 +88,14 @@ Theme* Theme::create(const char* url)
     theme->_url = url;
     theme->_url = url;
         
         
     // Parse the Properties object and set up the theme.
     // Parse the Properties object and set up the theme.
-    const char* textureFile = themeProperties->getString("texture");
-    theme->_texture = Texture::create(textureFile, false);
+    std::string textureFile;
+    themeProperties->getPath("texture", &textureFile);
+    theme->_texture = Texture::create(textureFile.c_str(), false);
     GP_ASSERT(theme->_texture);
     GP_ASSERT(theme->_texture);
     theme->_spriteBatch = SpriteBatch::create(theme->_texture);
     theme->_spriteBatch = SpriteBatch::create(theme->_texture);
     GP_ASSERT(theme->_spriteBatch);
     GP_ASSERT(theme->_spriteBatch);
-    theme->_spriteBatch->getSampler()->setFilterMode(Texture::NEAREST, Texture::NEAREST);
+    theme->_spriteBatch->getSampler()->setFilterMode(Texture::LINEAR, Texture::LINEAR);
+    theme->_spriteBatch->getSampler()->setWrapMode(Texture::CLAMP, Texture::CLAMP);
 
 
     float tw = 1.0f / theme->_texture->getWidth();
     float tw = 1.0f / theme->_texture->getWidth();
     float th = 1.0f / theme->_texture->getHeight();
     float th = 1.0f / theme->_texture->getHeight();
@@ -176,11 +178,11 @@ Theme* Theme::create(const char* url)
                         innerSpace->getColor("textColor", &textColor);
                         innerSpace->getColor("textColor", &textColor);
                     }
                     }
 
 
-                    const char* fontPath = innerSpace->getString("font");
                     Font* font = NULL;
                     Font* font = NULL;
-                    if (fontPath)
+                    std::string fontPath;
+                    if (innerSpace->getPath("font", &fontPath))
                     {
                     {
-                        font = Font::create(fontPath);
+                        font = Font::create(fontPath.c_str());
                     }
                     }
                     unsigned int fontSize = innerSpace->getInt("fontSize");
                     unsigned int fontSize = innerSpace->getInt("fontSize");
                     const char* textAlignmentString = innerSpace->getString("textAlignment");
                     const char* textAlignmentString = innerSpace->getString("textAlignment");
@@ -260,11 +262,11 @@ Theme* Theme::create(const char* url)
                         textColor.set(normal->getTextColor());
                         textColor.set(normal->getTextColor());
                     }
                     }
 
 
-                    const char* fontPath = innerSpace->getString("font");
                     Font* font = NULL;
                     Font* font = NULL;
-                    if (fontPath)
+                    std::string fontPath;
+                    if (innerSpace->getPath("font", &fontPath))
                     {
                     {
-                        font = Font::create(fontPath);
+                        font = Font::create(fontPath.c_str());
                     }
                     }
                     if (!font)
                     if (!font)
                     {
                     {

+ 12 - 2
gameplay/src/VerticalLayout.cpp

@@ -4,7 +4,7 @@
 namespace gameplay
 namespace gameplay
 {
 {
 
 
-VerticalLayout::VerticalLayout() : _bottomToTop(false)
+VerticalLayout::VerticalLayout() : _bottomToTop(false), _spacing(0)
 {
 {
 }
 }
 
 
@@ -32,6 +32,16 @@ Layout::Type VerticalLayout::getType()
     return Layout::LAYOUT_VERTICAL;
     return Layout::LAYOUT_VERTICAL;
 }
 }
 
 
+int VerticalLayout::getSpacing() const
+{
+    return _spacing;
+}
+
+void VerticalLayout::setSpacing(int spacing)
+{
+    _spacing = spacing;
+}
+
 void VerticalLayout::update(const Container* container, const Vector2& offset)
 void VerticalLayout::update(const Container* container, const Vector2& offset)
 {
 {
     GP_ASSERT(container);
     GP_ASSERT(container);
@@ -75,7 +85,7 @@ void VerticalLayout::update(const Container* container, const Vector2& offset)
             control->setPosition(margin.left, yPosition);
             control->setPosition(margin.left, yPosition);
             control->update(container, offset);
             control->update(container, offset);
 
 
-            yPosition += bounds.height + margin.bottom;
+            yPosition += bounds.height + margin.bottom + _spacing;
         }
         }
 
 
         i += iter;
         i += iter;

+ 19 - 0
gameplay/src/VerticalLayout.h

@@ -40,6 +40,20 @@ public:
      */
      */
     Layout::Type getType();
     Layout::Type getType();
 
 
+    /**
+     * Returns the vertical spacing between controls in the layout.
+     *
+     * @return The vertical spacing between controls.
+     */
+    int getSpacing() const;
+
+    /**
+     * Sets the vertical spacing to add between controls in the layout.
+     *
+     * @param spacing The vertical spacing between controls.
+     */
+    void setSpacing(int spacing);
+
 protected:
 protected:
 
 
     /**
     /**
@@ -69,6 +83,11 @@ protected:
      */
      */
     bool _bottomToTop;
     bool _bottomToTop;
 
 
+    /**
+     * Spacing between controls in the layout.
+     */
+    int _spacing;
+
 private:
 private:
 
 
     /**
     /**

+ 72 - 0
gameplay/src/lua/lua_Bundle.cpp

@@ -22,6 +22,8 @@ void luaRegister_Bundle()
         {"getObjectCount", lua_Bundle_getObjectCount},
         {"getObjectCount", lua_Bundle_getObjectCount},
         {"getObjectId", lua_Bundle_getObjectId},
         {"getObjectId", lua_Bundle_getObjectId},
         {"getRefCount", lua_Bundle_getRefCount},
         {"getRefCount", lua_Bundle_getRefCount},
+        {"getVersionMajor", lua_Bundle_getVersionMajor},
+        {"getVersionMinor", lua_Bundle_getVersionMinor},
         {"loadFont", lua_Bundle_loadFont},
         {"loadFont", lua_Bundle_loadFont},
         {"loadMesh", lua_Bundle_loadMesh},
         {"loadMesh", lua_Bundle_loadMesh},
         {"loadNode", lua_Bundle_loadNode},
         {"loadNode", lua_Bundle_loadNode},
@@ -264,6 +266,76 @@ int lua_Bundle_getRefCount(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Bundle_getVersionMajor(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))
+            {
+                Bundle* instance = getInstance(state);
+                unsigned int result = instance->getVersionMajor();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Bundle_getVersionMajor - 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_Bundle_getVersionMinor(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))
+            {
+                Bundle* instance = getInstance(state);
+                unsigned int result = instance->getVersionMinor();
+
+                // Push the return value onto the stack.
+                lua_pushunsigned(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Bundle_getVersionMinor - 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_Bundle_loadFont(lua_State* state)
 int lua_Bundle_loadFont(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.

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

@@ -11,6 +11,8 @@ int lua_Bundle_contains(lua_State* state);
 int lua_Bundle_getObjectCount(lua_State* state);
 int lua_Bundle_getObjectCount(lua_State* state);
 int lua_Bundle_getObjectId(lua_State* state);
 int lua_Bundle_getObjectId(lua_State* state);
 int lua_Bundle_getRefCount(lua_State* state);
 int lua_Bundle_getRefCount(lua_State* state);
+int lua_Bundle_getVersionMajor(lua_State* state);
+int lua_Bundle_getVersionMinor(lua_State* state);
 int lua_Bundle_loadFont(lua_State* state);
 int lua_Bundle_loadFont(lua_State* state);
 int lua_Bundle_loadMesh(lua_State* state);
 int lua_Bundle_loadMesh(lua_State* state);
 int lua_Bundle_loadNode(lua_State* state);
 int lua_Bundle_loadNode(lua_State* state);

+ 367 - 24
gameplay/src/lua/lua_Button.cpp

@@ -14,6 +14,7 @@
 #include "ScriptController.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
 #include "ScriptTarget.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAlignment.h"
+#include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
 #include "lua_ControlState.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_CurveInterpolationType.h"
@@ -74,7 +75,11 @@ void luaRegister_Button()
         {"getZIndex", lua_Button_getZIndex},
         {"getZIndex", lua_Button_getZIndex},
         {"isContainer", lua_Button_isContainer},
         {"isContainer", lua_Button_isContainer},
         {"isEnabled", lua_Button_isEnabled},
         {"isEnabled", lua_Button_isEnabled},
+        {"isHeightPercentage", lua_Button_isHeightPercentage},
         {"isVisible", lua_Button_isVisible},
         {"isVisible", lua_Button_isVisible},
+        {"isWidthPercentage", lua_Button_isWidthPercentage},
+        {"isXPercentage", lua_Button_isXPercentage},
+        {"isYPercentage", lua_Button_isYPercentage},
         {"release", lua_Button_release},
         {"release", lua_Button_release},
         {"removeListener", lua_Button_removeListener},
         {"removeListener", lua_Button_removeListener},
         {"removeScriptCallback", lua_Button_removeScriptCallback},
         {"removeScriptCallback", lua_Button_removeScriptCallback},
@@ -109,6 +114,8 @@ void luaRegister_Button()
         {"setTextRightToLeft", lua_Button_setTextRightToLeft},
         {"setTextRightToLeft", lua_Button_setTextRightToLeft},
         {"setVisible", lua_Button_setVisible},
         {"setVisible", lua_Button_setVisible},
         {"setWidth", lua_Button_setWidth},
         {"setWidth", lua_Button_setWidth},
+        {"setX", lua_Button_setX},
+        {"setY", lua_Button_setY},
         {"setZIndex", lua_Button_setZIndex},
         {"setZIndex", lua_Button_setZIndex},
         {NULL, NULL}
         {NULL, NULL}
     };
     };
@@ -932,10 +939,10 @@ int lua_Button_getAutoHeight(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 Button* instance = getInstance(state);
                 Button* instance = getInstance(state);
-                bool result = instance->getAutoHeight();
+                Control::AutoSize result = instance->getAutoHeight();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -967,10 +974,10 @@ int lua_Button_getAutoWidth(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 Button* instance = getInstance(state);
                 Button* instance = getInstance(state);
-                bool result = instance->getAutoWidth();
+                Control::AutoSize result = instance->getAutoWidth();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -2602,6 +2609,41 @@ int lua_Button_isEnabled(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Button_isHeightPercentage(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))
+            {
+                Button* instance = getInstance(state);
+                bool result = instance->isHeightPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Button_isHeightPercentage - 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_Button_isVisible(lua_State* state)
 int lua_Button_isVisible(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -2637,6 +2679,111 @@ int lua_Button_isVisible(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Button_isWidthPercentage(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))
+            {
+                Button* instance = getInstance(state);
+                bool result = instance->isWidthPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Button_isWidthPercentage - 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_Button_isXPercentage(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))
+            {
+                Button* instance = getInstance(state);
+                bool result = instance->isXPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Button_isXPercentage - 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_Button_isYPercentage(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))
+            {
+                Button* instance = getInstance(state);
+                bool result = instance->isYPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Button_isYPercentage - 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_Button_release(lua_State* state)
 int lua_Button_release(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -2875,17 +3022,35 @@ int lua_Button_setAutoHeight(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                Button* instance = getInstance(state);
-                instance->setAutoHeight(param1);
-                
-                return 0;
-            }
+                    Button* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    Button* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_Button_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_Button_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -2911,17 +3076,35 @@ int lua_Button_setAutoWidth(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                Button* instance = getInstance(state);
-                instance->setAutoWidth(param1);
-                
-                return 0;
-            }
+                    Button* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    Button* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_Button_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_Button_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -3415,9 +3598,31 @@ int lua_Button_setHeight(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Button* instance = getInstance(state);
+                instance->setHeight(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Button_setHeight - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
@@ -4317,9 +4522,147 @@ int lua_Button_setWidth(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Button* instance = getInstance(state);
+                instance->setWidth(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Button_setWidth - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Button_setX(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);
+
+                Button* instance = getInstance(state);
+                instance->setX(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Button_setX - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Button* instance = getInstance(state);
+                instance->setX(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Button_setX - 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 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Button_setY(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);
+
+                Button* instance = getInstance(state);
+                instance->setY(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Button_setY - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Button* instance = getInstance(state);
+                instance->setY(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Button_setY - 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 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

+ 6 - 0
gameplay/src/lua/lua_Button.h

@@ -54,7 +54,11 @@ int lua_Button_getY(lua_State* state);
 int lua_Button_getZIndex(lua_State* state);
 int lua_Button_getZIndex(lua_State* state);
 int lua_Button_isContainer(lua_State* state);
 int lua_Button_isContainer(lua_State* state);
 int lua_Button_isEnabled(lua_State* state);
 int lua_Button_isEnabled(lua_State* state);
+int lua_Button_isHeightPercentage(lua_State* state);
 int lua_Button_isVisible(lua_State* state);
 int lua_Button_isVisible(lua_State* state);
+int lua_Button_isWidthPercentage(lua_State* state);
+int lua_Button_isXPercentage(lua_State* state);
+int lua_Button_isYPercentage(lua_State* state);
 int lua_Button_release(lua_State* state);
 int lua_Button_release(lua_State* state);
 int lua_Button_removeListener(lua_State* state);
 int lua_Button_removeListener(lua_State* state);
 int lua_Button_removeScriptCallback(lua_State* state);
 int lua_Button_removeScriptCallback(lua_State* state);
@@ -89,6 +93,8 @@ int lua_Button_setTextColor(lua_State* state);
 int lua_Button_setTextRightToLeft(lua_State* state);
 int lua_Button_setTextRightToLeft(lua_State* state);
 int lua_Button_setVisible(lua_State* state);
 int lua_Button_setVisible(lua_State* state);
 int lua_Button_setWidth(lua_State* state);
 int lua_Button_setWidth(lua_State* state);
+int lua_Button_setX(lua_State* state);
+int lua_Button_setY(lua_State* state);
 int lua_Button_setZIndex(lua_State* state);
 int lua_Button_setZIndex(lua_State* state);
 int lua_Button_static_ANIMATE_OPACITY(lua_State* state);
 int lua_Button_static_ANIMATE_OPACITY(lua_State* state);
 int lua_Button_static_ANIMATE_POSITION(lua_State* state);
 int lua_Button_static_ANIMATE_POSITION(lua_State* state);

+ 367 - 24
gameplay/src/lua/lua_CheckBox.cpp

@@ -15,6 +15,7 @@
 #include "ScriptController.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
 #include "ScriptTarget.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAlignment.h"
+#include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
 #include "lua_ControlState.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_CurveInterpolationType.h"
@@ -78,7 +79,11 @@ void luaRegister_CheckBox()
         {"isChecked", lua_CheckBox_isChecked},
         {"isChecked", lua_CheckBox_isChecked},
         {"isContainer", lua_CheckBox_isContainer},
         {"isContainer", lua_CheckBox_isContainer},
         {"isEnabled", lua_CheckBox_isEnabled},
         {"isEnabled", lua_CheckBox_isEnabled},
+        {"isHeightPercentage", lua_CheckBox_isHeightPercentage},
         {"isVisible", lua_CheckBox_isVisible},
         {"isVisible", lua_CheckBox_isVisible},
+        {"isWidthPercentage", lua_CheckBox_isWidthPercentage},
+        {"isXPercentage", lua_CheckBox_isXPercentage},
+        {"isYPercentage", lua_CheckBox_isYPercentage},
         {"release", lua_CheckBox_release},
         {"release", lua_CheckBox_release},
         {"removeListener", lua_CheckBox_removeListener},
         {"removeListener", lua_CheckBox_removeListener},
         {"removeScriptCallback", lua_CheckBox_removeScriptCallback},
         {"removeScriptCallback", lua_CheckBox_removeScriptCallback},
@@ -115,6 +120,8 @@ void luaRegister_CheckBox()
         {"setTextRightToLeft", lua_CheckBox_setTextRightToLeft},
         {"setTextRightToLeft", lua_CheckBox_setTextRightToLeft},
         {"setVisible", lua_CheckBox_setVisible},
         {"setVisible", lua_CheckBox_setVisible},
         {"setWidth", lua_CheckBox_setWidth},
         {"setWidth", lua_CheckBox_setWidth},
+        {"setX", lua_CheckBox_setX},
+        {"setY", lua_CheckBox_setY},
         {"setZIndex", lua_CheckBox_setZIndex},
         {"setZIndex", lua_CheckBox_setZIndex},
         {NULL, NULL}
         {NULL, NULL}
     };
     };
@@ -938,10 +945,10 @@ int lua_CheckBox_getAutoHeight(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 CheckBox* instance = getInstance(state);
                 CheckBox* instance = getInstance(state);
-                bool result = instance->getAutoHeight();
+                Control::AutoSize result = instance->getAutoHeight();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -973,10 +980,10 @@ int lua_CheckBox_getAutoWidth(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 CheckBox* instance = getInstance(state);
                 CheckBox* instance = getInstance(state);
-                bool result = instance->getAutoWidth();
+                Control::AutoSize result = instance->getAutoWidth();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -2722,6 +2729,41 @@ int lua_CheckBox_isEnabled(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_CheckBox_isHeightPercentage(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))
+            {
+                CheckBox* instance = getInstance(state);
+                bool result = instance->isHeightPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_isHeightPercentage - 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_CheckBox_isVisible(lua_State* state)
 int lua_CheckBox_isVisible(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -2757,6 +2799,111 @@ int lua_CheckBox_isVisible(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_CheckBox_isWidthPercentage(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))
+            {
+                CheckBox* instance = getInstance(state);
+                bool result = instance->isWidthPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_isWidthPercentage - 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_CheckBox_isXPercentage(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))
+            {
+                CheckBox* instance = getInstance(state);
+                bool result = instance->isXPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_isXPercentage - 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_CheckBox_isYPercentage(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))
+            {
+                CheckBox* instance = getInstance(state);
+                bool result = instance->isYPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_isYPercentage - 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_CheckBox_release(lua_State* state)
 int lua_CheckBox_release(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -2995,17 +3142,35 @@ int lua_CheckBox_setAutoHeight(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                CheckBox* instance = getInstance(state);
-                instance->setAutoHeight(param1);
-                
-                return 0;
-            }
+                    CheckBox* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    CheckBox* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_CheckBox_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_CheckBox_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -3031,17 +3196,35 @@ int lua_CheckBox_setAutoWidth(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                CheckBox* instance = getInstance(state);
-                instance->setAutoWidth(param1);
-                
-                return 0;
-            }
+                    CheckBox* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    CheckBox* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_CheckBox_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_CheckBox_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -3571,9 +3754,31 @@ int lua_CheckBox_setHeight(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                CheckBox* instance = getInstance(state);
+                instance->setHeight(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_setHeight - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
@@ -4513,9 +4718,147 @@ int lua_CheckBox_setWidth(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                CheckBox* instance = getInstance(state);
+                instance->setWidth(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_setWidth - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_CheckBox_setX(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);
+
+                CheckBox* instance = getInstance(state);
+                instance->setX(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_setX - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                CheckBox* instance = getInstance(state);
+                instance->setX(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_setX - 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 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_CheckBox_setY(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);
+
+                CheckBox* instance = getInstance(state);
+                instance->setY(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_setY - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                CheckBox* instance = getInstance(state);
+                instance->setY(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_CheckBox_setY - 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 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

+ 6 - 0
gameplay/src/lua/lua_CheckBox.h

@@ -57,7 +57,11 @@ int lua_CheckBox_getZIndex(lua_State* state);
 int lua_CheckBox_isChecked(lua_State* state);
 int lua_CheckBox_isChecked(lua_State* state);
 int lua_CheckBox_isContainer(lua_State* state);
 int lua_CheckBox_isContainer(lua_State* state);
 int lua_CheckBox_isEnabled(lua_State* state);
 int lua_CheckBox_isEnabled(lua_State* state);
+int lua_CheckBox_isHeightPercentage(lua_State* state);
 int lua_CheckBox_isVisible(lua_State* state);
 int lua_CheckBox_isVisible(lua_State* state);
+int lua_CheckBox_isWidthPercentage(lua_State* state);
+int lua_CheckBox_isXPercentage(lua_State* state);
+int lua_CheckBox_isYPercentage(lua_State* state);
 int lua_CheckBox_release(lua_State* state);
 int lua_CheckBox_release(lua_State* state);
 int lua_CheckBox_removeListener(lua_State* state);
 int lua_CheckBox_removeListener(lua_State* state);
 int lua_CheckBox_removeScriptCallback(lua_State* state);
 int lua_CheckBox_removeScriptCallback(lua_State* state);
@@ -94,6 +98,8 @@ int lua_CheckBox_setTextColor(lua_State* state);
 int lua_CheckBox_setTextRightToLeft(lua_State* state);
 int lua_CheckBox_setTextRightToLeft(lua_State* state);
 int lua_CheckBox_setVisible(lua_State* state);
 int lua_CheckBox_setVisible(lua_State* state);
 int lua_CheckBox_setWidth(lua_State* state);
 int lua_CheckBox_setWidth(lua_State* state);
+int lua_CheckBox_setX(lua_State* state);
+int lua_CheckBox_setY(lua_State* state);
 int lua_CheckBox_setZIndex(lua_State* state);
 int lua_CheckBox_setZIndex(lua_State* state);
 int lua_CheckBox_static_ANIMATE_OPACITY(lua_State* state);
 int lua_CheckBox_static_ANIMATE_OPACITY(lua_State* state);
 int lua_CheckBox_static_ANIMATE_POSITION(lua_State* state);
 int lua_CheckBox_static_ANIMATE_POSITION(lua_State* state);

+ 369 - 26
gameplay/src/lua/lua_Container.cpp

@@ -25,6 +25,7 @@
 #include "VerticalLayout.h"
 #include "VerticalLayout.h"
 #include "lua_ContainerScroll.h"
 #include "lua_ContainerScroll.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAlignment.h"
+#include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
 #include "lua_ControlState.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_CurveInterpolationType.h"
@@ -95,9 +96,13 @@ void luaRegister_Container()
         {"insertControl", lua_Container_insertControl},
         {"insertControl", lua_Container_insertControl},
         {"isContainer", lua_Container_isContainer},
         {"isContainer", lua_Container_isContainer},
         {"isEnabled", lua_Container_isEnabled},
         {"isEnabled", lua_Container_isEnabled},
+        {"isHeightPercentage", lua_Container_isHeightPercentage},
         {"isScrollBarsAutoHide", lua_Container_isScrollBarsAutoHide},
         {"isScrollBarsAutoHide", lua_Container_isScrollBarsAutoHide},
         {"isScrolling", lua_Container_isScrolling},
         {"isScrolling", lua_Container_isScrolling},
         {"isVisible", lua_Container_isVisible},
         {"isVisible", lua_Container_isVisible},
+        {"isWidthPercentage", lua_Container_isWidthPercentage},
+        {"isXPercentage", lua_Container_isXPercentage},
+        {"isYPercentage", lua_Container_isYPercentage},
         {"release", lua_Container_release},
         {"release", lua_Container_release},
         {"removeControl", lua_Container_removeControl},
         {"removeControl", lua_Container_removeControl},
         {"removeListener", lua_Container_removeListener},
         {"removeListener", lua_Container_removeListener},
@@ -138,6 +143,8 @@ void luaRegister_Container()
         {"setTextRightToLeft", lua_Container_setTextRightToLeft},
         {"setTextRightToLeft", lua_Container_setTextRightToLeft},
         {"setVisible", lua_Container_setVisible},
         {"setVisible", lua_Container_setVisible},
         {"setWidth", lua_Container_setWidth},
         {"setWidth", lua_Container_setWidth},
+        {"setX", lua_Container_setX},
+        {"setY", lua_Container_setY},
         {"setZIndex", lua_Container_setZIndex},
         {"setZIndex", lua_Container_setZIndex},
         {NULL, NULL}
         {NULL, NULL}
     };
     };
@@ -1007,10 +1014,10 @@ int lua_Container_getAutoHeight(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 Container* instance = getInstance(state);
                 Container* instance = getInstance(state);
-                bool result = instance->getAutoHeight();
+                Control::AutoSize result = instance->getAutoHeight();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -1042,10 +1049,10 @@ int lua_Container_getAutoWidth(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 Container* instance = getInstance(state);
                 Container* instance = getInstance(state);
-                bool result = instance->getAutoWidth();
+                Control::AutoSize result = instance->getAutoWidth();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -2192,7 +2199,7 @@ int lua_Container_getScrollPosition(lua_State* state)
                 void* returnPtr = (void*)&(instance->getScrollPosition());
                 void* returnPtr = (void*)&(instance->getScrollPosition());
                 if (returnPtr)
                 if (returnPtr)
                 {
                 {
-                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
                     object->instance = returnPtr;
                     object->instance = returnPtr;
                     object->owns = false;
                     object->owns = false;
                     luaL_getmetatable(state, "Vector2");
                     luaL_getmetatable(state, "Vector2");
@@ -3029,6 +3036,41 @@ int lua_Container_isEnabled(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Container_isHeightPercentage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                bool result = instance->isHeightPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_isHeightPercentage - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Container_isScrollBarsAutoHide(lua_State* state)
 int lua_Container_isScrollBarsAutoHide(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -3134,6 +3176,111 @@ int lua_Container_isVisible(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Container_isWidthPercentage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                bool result = instance->isWidthPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_isWidthPercentage - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_isXPercentage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                bool result = instance->isXPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_isXPercentage - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_isYPercentage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Container* instance = getInstance(state);
+                bool result = instance->isYPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Container_isYPercentage - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Container_release(lua_State* state)
 int lua_Container_release(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -3444,17 +3591,35 @@ int lua_Container_setAutoHeight(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                Container* instance = getInstance(state);
-                instance->setAutoHeight(param1);
-                
-                return 0;
-            }
+                    Container* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    Container* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_Container_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_Container_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -3480,17 +3645,35 @@ int lua_Container_setAutoWidth(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                Container* instance = getInstance(state);
-                instance->setAutoWidth(param1);
-                
-                return 0;
-            }
+                    Container* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    Container* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_Container_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_Container_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -3984,9 +4167,31 @@ int lua_Container_setHeight(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Container* instance = getInstance(state);
+                instance->setHeight(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setHeight - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
@@ -4431,7 +4636,7 @@ int lua_Container_setScrollPosition(lua_State* state)
             {
             {
                 // Get parameter 1 off the stack.
                 // Get parameter 1 off the stack.
                 bool param1Valid;
                 bool param1Valid;
-                ScriptUtil::LuaArray<Vector2> param1 = ScriptUtil::getObjectPointer<Vector2>(2, "Vector2", true, &param1Valid);
+                gameplay::ScriptUtil::LuaArray<Vector2> param1 = gameplay::ScriptUtil::getObjectPointer<Vector2>(2, "Vector2", true, &param1Valid);
                 if (!param1Valid)
                 if (!param1Valid)
                 {
                 {
                     lua_pushstring(state, "Failed to convert parameter 1 to type 'Vector2'.");
                     lua_pushstring(state, "Failed to convert parameter 1 to type 'Vector2'.");
@@ -5072,9 +5277,147 @@ int lua_Container_setWidth(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Container* instance = getInstance(state);
+                instance->setWidth(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setWidth - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_setX(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Container* instance = getInstance(state);
+                instance->setX(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setX - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Container* instance = getInstance(state);
+                instance->setX(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setX - 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 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Container_setY(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Container* instance = getInstance(state);
+                instance->setY(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setY - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Container* instance = getInstance(state);
+                instance->setY(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Container_setY - 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 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

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

@@ -63,9 +63,13 @@ int lua_Container_getZIndex(lua_State* state);
 int lua_Container_insertControl(lua_State* state);
 int lua_Container_insertControl(lua_State* state);
 int lua_Container_isContainer(lua_State* state);
 int lua_Container_isContainer(lua_State* state);
 int lua_Container_isEnabled(lua_State* state);
 int lua_Container_isEnabled(lua_State* state);
+int lua_Container_isHeightPercentage(lua_State* state);
 int lua_Container_isScrollBarsAutoHide(lua_State* state);
 int lua_Container_isScrollBarsAutoHide(lua_State* state);
 int lua_Container_isScrolling(lua_State* state);
 int lua_Container_isScrolling(lua_State* state);
 int lua_Container_isVisible(lua_State* state);
 int lua_Container_isVisible(lua_State* state);
+int lua_Container_isWidthPercentage(lua_State* state);
+int lua_Container_isXPercentage(lua_State* state);
+int lua_Container_isYPercentage(lua_State* state);
 int lua_Container_release(lua_State* state);
 int lua_Container_release(lua_State* state);
 int lua_Container_removeControl(lua_State* state);
 int lua_Container_removeControl(lua_State* state);
 int lua_Container_removeListener(lua_State* state);
 int lua_Container_removeListener(lua_State* state);
@@ -106,6 +110,8 @@ int lua_Container_setTextColor(lua_State* state);
 int lua_Container_setTextRightToLeft(lua_State* state);
 int lua_Container_setTextRightToLeft(lua_State* state);
 int lua_Container_setVisible(lua_State* state);
 int lua_Container_setVisible(lua_State* state);
 int lua_Container_setWidth(lua_State* state);
 int lua_Container_setWidth(lua_State* state);
+int lua_Container_setX(lua_State* state);
+int lua_Container_setY(lua_State* state);
 int lua_Container_setZIndex(lua_State* state);
 int lua_Container_setZIndex(lua_State* state);
 int lua_Container_static_ANIMATE_OPACITY(lua_State* state);
 int lua_Container_static_ANIMATE_OPACITY(lua_State* state);
 int lua_Container_static_ANIMATE_POSITION(lua_State* state);
 int lua_Container_static_ANIMATE_POSITION(lua_State* state);

+ 367 - 24
gameplay/src/lua/lua_Control.cpp

@@ -11,6 +11,7 @@
 #include "ScriptController.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
 #include "ScriptTarget.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAlignment.h"
+#include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
 #include "lua_ControlState.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_CurveInterpolationType.h"
@@ -71,7 +72,11 @@ void luaRegister_Control()
         {"getZIndex", lua_Control_getZIndex},
         {"getZIndex", lua_Control_getZIndex},
         {"isContainer", lua_Control_isContainer},
         {"isContainer", lua_Control_isContainer},
         {"isEnabled", lua_Control_isEnabled},
         {"isEnabled", lua_Control_isEnabled},
+        {"isHeightPercentage", lua_Control_isHeightPercentage},
         {"isVisible", lua_Control_isVisible},
         {"isVisible", lua_Control_isVisible},
+        {"isWidthPercentage", lua_Control_isWidthPercentage},
+        {"isXPercentage", lua_Control_isXPercentage},
+        {"isYPercentage", lua_Control_isYPercentage},
         {"release", lua_Control_release},
         {"release", lua_Control_release},
         {"removeListener", lua_Control_removeListener},
         {"removeListener", lua_Control_removeListener},
         {"removeScriptCallback", lua_Control_removeScriptCallback},
         {"removeScriptCallback", lua_Control_removeScriptCallback},
@@ -105,6 +110,8 @@ void luaRegister_Control()
         {"setTextRightToLeft", lua_Control_setTextRightToLeft},
         {"setTextRightToLeft", lua_Control_setTextRightToLeft},
         {"setVisible", lua_Control_setVisible},
         {"setVisible", lua_Control_setVisible},
         {"setWidth", lua_Control_setWidth},
         {"setWidth", lua_Control_setWidth},
+        {"setX", lua_Control_setX},
+        {"setY", lua_Control_setY},
         {"setZIndex", lua_Control_setZIndex},
         {"setZIndex", lua_Control_setZIndex},
         {NULL, NULL}
         {NULL, NULL}
     };
     };
@@ -927,10 +934,10 @@ int lua_Control_getAutoHeight(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 Control* instance = getInstance(state);
                 Control* instance = getInstance(state);
-                bool result = instance->getAutoHeight();
+                Control::AutoSize result = instance->getAutoHeight();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -962,10 +969,10 @@ int lua_Control_getAutoWidth(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 Control* instance = getInstance(state);
                 Control* instance = getInstance(state);
-                bool result = instance->getAutoWidth();
+                Control::AutoSize result = instance->getAutoWidth();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -2597,6 +2604,41 @@ int lua_Control_isEnabled(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Control_isHeightPercentage(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))
+            {
+                Control* instance = getInstance(state);
+                bool result = instance->isHeightPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Control_isHeightPercentage - 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_Control_isVisible(lua_State* state)
 int lua_Control_isVisible(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -2632,6 +2674,111 @@ int lua_Control_isVisible(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Control_isWidthPercentage(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))
+            {
+                Control* instance = getInstance(state);
+                bool result = instance->isWidthPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Control_isWidthPercentage - 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_Control_isXPercentage(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))
+            {
+                Control* instance = getInstance(state);
+                bool result = instance->isXPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Control_isXPercentage - 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_Control_isYPercentage(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))
+            {
+                Control* instance = getInstance(state);
+                bool result = instance->isYPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Control_isYPercentage - 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_Control_release(lua_State* state)
 int lua_Control_release(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -2870,17 +3017,35 @@ int lua_Control_setAutoHeight(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                Control* instance = getInstance(state);
-                instance->setAutoHeight(param1);
-                
-                return 0;
-            }
+                    Control* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    Control* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_Control_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_Control_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -2906,17 +3071,35 @@ int lua_Control_setAutoWidth(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                Control* instance = getInstance(state);
-                instance->setAutoWidth(param1);
-                
-                return 0;
-            }
+                    Control* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    Control* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_Control_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_Control_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -3410,9 +3593,31 @@ int lua_Control_setHeight(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Control* instance = getInstance(state);
+                instance->setHeight(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Control_setHeight - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
@@ -4276,9 +4481,147 @@ int lua_Control_setWidth(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Control* instance = getInstance(state);
+                instance->setWidth(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Control_setWidth - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Control_setX(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);
+
+                Control* instance = getInstance(state);
+                instance->setX(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Control_setX - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Control* instance = getInstance(state);
+                instance->setX(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Control_setX - 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 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Control_setY(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);
+
+                Control* instance = getInstance(state);
+                instance->setY(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Control_setY - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Control* instance = getInstance(state);
+                instance->setY(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Control_setY - 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 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

+ 6 - 0
gameplay/src/lua/lua_Control.h

@@ -54,7 +54,11 @@ int lua_Control_getY(lua_State* state);
 int lua_Control_getZIndex(lua_State* state);
 int lua_Control_getZIndex(lua_State* state);
 int lua_Control_isContainer(lua_State* state);
 int lua_Control_isContainer(lua_State* state);
 int lua_Control_isEnabled(lua_State* state);
 int lua_Control_isEnabled(lua_State* state);
+int lua_Control_isHeightPercentage(lua_State* state);
 int lua_Control_isVisible(lua_State* state);
 int lua_Control_isVisible(lua_State* state);
+int lua_Control_isWidthPercentage(lua_State* state);
+int lua_Control_isXPercentage(lua_State* state);
+int lua_Control_isYPercentage(lua_State* state);
 int lua_Control_release(lua_State* state);
 int lua_Control_release(lua_State* state);
 int lua_Control_removeListener(lua_State* state);
 int lua_Control_removeListener(lua_State* state);
 int lua_Control_removeScriptCallback(lua_State* state);
 int lua_Control_removeScriptCallback(lua_State* state);
@@ -88,6 +92,8 @@ int lua_Control_setTextColor(lua_State* state);
 int lua_Control_setTextRightToLeft(lua_State* state);
 int lua_Control_setTextRightToLeft(lua_State* state);
 int lua_Control_setVisible(lua_State* state);
 int lua_Control_setVisible(lua_State* state);
 int lua_Control_setWidth(lua_State* state);
 int lua_Control_setWidth(lua_State* state);
+int lua_Control_setX(lua_State* state);
+int lua_Control_setY(lua_State* state);
 int lua_Control_setZIndex(lua_State* state);
 int lua_Control_setZIndex(lua_State* state);
 int lua_Control_static_ANIMATE_OPACITY(lua_State* state);
 int lua_Control_static_ANIMATE_OPACITY(lua_State* state);
 int lua_Control_static_ANIMATE_POSITION(lua_State* state);
 int lua_Control_static_ANIMATE_POSITION(lua_State* state);

+ 36 - 0
gameplay/src/lua/lua_ControlAutoSize.cpp

@@ -0,0 +1,36 @@
+#include "Base.h"
+#include "lua_ControlAutoSize.h"
+
+namespace gameplay
+{
+
+static const char* enumStringEmpty = "";
+
+static const char* luaEnumString_ControlAutoSize_AUTO_SIZE_NONE = "AUTO_SIZE_NONE";
+static const char* luaEnumString_ControlAutoSize_AUTO_SIZE_STRETCH = "AUTO_SIZE_STRETCH";
+static const char* luaEnumString_ControlAutoSize_AUTO_SIZE_FIT = "AUTO_SIZE_FIT";
+
+Control::AutoSize lua_enumFromString_ControlAutoSize(const char* s)
+{
+    if (strcmp(s, luaEnumString_ControlAutoSize_AUTO_SIZE_NONE) == 0)
+        return Control::AUTO_SIZE_NONE;
+    if (strcmp(s, luaEnumString_ControlAutoSize_AUTO_SIZE_STRETCH) == 0)
+        return Control::AUTO_SIZE_STRETCH;
+    if (strcmp(s, luaEnumString_ControlAutoSize_AUTO_SIZE_FIT) == 0)
+        return Control::AUTO_SIZE_FIT;
+    return Control::AUTO_SIZE_NONE;
+}
+
+const char* lua_stringFromEnum_ControlAutoSize(Control::AutoSize e)
+{
+    if (e == Control::AUTO_SIZE_NONE)
+        return luaEnumString_ControlAutoSize_AUTO_SIZE_NONE;
+    if (e == Control::AUTO_SIZE_STRETCH)
+        return luaEnumString_ControlAutoSize_AUTO_SIZE_STRETCH;
+    if (e == Control::AUTO_SIZE_FIT)
+        return luaEnumString_ControlAutoSize_AUTO_SIZE_FIT;
+    return enumStringEmpty;
+}
+
+}
+

+ 15 - 0
gameplay/src/lua/lua_ControlAutoSize.h

@@ -0,0 +1,15 @@
+#ifndef LUA_CONTROLAUTOSIZE_H_
+#define LUA_CONTROLAUTOSIZE_H_
+
+#include "Control.h"
+
+namespace gameplay
+{
+
+// Lua bindings for enum conversion functions for Control::AutoSize.
+Control::AutoSize lua_enumFromString_ControlAutoSize(const char* s);
+const char* lua_stringFromEnum_ControlAutoSize(Control::AutoSize e);
+
+}
+
+#endif

+ 1 - 0
gameplay/src/lua/lua_ControlListener.cpp

@@ -11,6 +11,7 @@
 #include "ScriptController.h"
 #include "ScriptController.h"
 #include "ScriptTarget.h"
 #include "ScriptTarget.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAlignment.h"
+#include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
 #include "lua_ControlState.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_CurveInterpolationType.h"

+ 113 - 0
gameplay/src/lua/lua_FlowLayout.cpp

@@ -18,9 +18,12 @@ void luaRegister_FlowLayout()
     const luaL_Reg lua_members[] = 
     const luaL_Reg lua_members[] = 
     {
     {
         {"addRef", lua_FlowLayout_addRef},
         {"addRef", lua_FlowLayout_addRef},
+        {"getHorizontalSpacing", lua_FlowLayout_getHorizontalSpacing},
         {"getRefCount", lua_FlowLayout_getRefCount},
         {"getRefCount", lua_FlowLayout_getRefCount},
         {"getType", lua_FlowLayout_getType},
         {"getType", lua_FlowLayout_getType},
+        {"getVerticalSpacing", lua_FlowLayout_getVerticalSpacing},
         {"release", lua_FlowLayout_release},
         {"release", lua_FlowLayout_release},
+        {"setSpacing", lua_FlowLayout_setSpacing},
         {NULL, NULL}
         {NULL, NULL}
     };
     };
     const luaL_Reg* lua_statics = NULL;
     const luaL_Reg* lua_statics = NULL;
@@ -106,6 +109,41 @@ int lua_FlowLayout_addRef(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_FlowLayout_getHorizontalSpacing(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))
+            {
+                FlowLayout* instance = getInstance(state);
+                int result = instance->getHorizontalSpacing();
+
+                // Push the return value onto the stack.
+                lua_pushinteger(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FlowLayout_getHorizontalSpacing - 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_FlowLayout_getRefCount(lua_State* state)
 int lua_FlowLayout_getRefCount(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -176,6 +214,41 @@ int lua_FlowLayout_getType(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_FlowLayout_getVerticalSpacing(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))
+            {
+                FlowLayout* instance = getInstance(state);
+                int result = instance->getVerticalSpacing();
+
+                // Push the return value onto the stack.
+                lua_pushinteger(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_FlowLayout_getVerticalSpacing - 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_FlowLayout_release(lua_State* state)
 int lua_FlowLayout_release(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -208,4 +281,44 @@ int lua_FlowLayout_release(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_FlowLayout_setSpacing(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 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                int param1 = (int)luaL_checkint(state, 2);
+
+                // Get parameter 2 off the stack.
+                int param2 = (int)luaL_checkint(state, 3);
+
+                FlowLayout* instance = getInstance(state);
+                instance->setSpacing(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_FlowLayout_setSpacing - 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_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 }
 }

+ 3 - 0
gameplay/src/lua/lua_FlowLayout.h

@@ -7,9 +7,12 @@ namespace gameplay
 // Lua bindings for FlowLayout.
 // Lua bindings for FlowLayout.
 int lua_FlowLayout__gc(lua_State* state);
 int lua_FlowLayout__gc(lua_State* state);
 int lua_FlowLayout_addRef(lua_State* state);
 int lua_FlowLayout_addRef(lua_State* state);
+int lua_FlowLayout_getHorizontalSpacing(lua_State* state);
 int lua_FlowLayout_getRefCount(lua_State* state);
 int lua_FlowLayout_getRefCount(lua_State* state);
 int lua_FlowLayout_getType(lua_State* state);
 int lua_FlowLayout_getType(lua_State* state);
+int lua_FlowLayout_getVerticalSpacing(lua_State* state);
 int lua_FlowLayout_release(lua_State* state);
 int lua_FlowLayout_release(lua_State* state);
+int lua_FlowLayout_setSpacing(lua_State* state);
 
 
 void luaRegister_FlowLayout();
 void luaRegister_FlowLayout();
 
 

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

@@ -7,6 +7,7 @@
 #include "Font.h"
 #include "Font.h"
 #include "Game.h"
 #include "Game.h"
 #include "Ref.h"
 #include "Ref.h"
+#include "lua_FontFormat.h"
 #include "lua_FontJustify.h"
 #include "lua_FontJustify.h"
 
 
 namespace gameplay
 namespace gameplay
@@ -21,6 +22,7 @@ void luaRegister_Font()
         {"drawText", lua_Font_drawText},
         {"drawText", lua_Font_drawText},
         {"finish", lua_Font_finish},
         {"finish", lua_Font_finish},
         {"getCharacterSpacing", lua_Font_getCharacterSpacing},
         {"getCharacterSpacing", lua_Font_getCharacterSpacing},
+        {"getFormat", lua_Font_getFormat},
         {"getIndexAtLocation", lua_Font_getIndexAtLocation},
         {"getIndexAtLocation", lua_Font_getIndexAtLocation},
         {"getLocationAtIndex", lua_Font_getLocationAtIndex},
         {"getLocationAtIndex", lua_Font_getLocationAtIndex},
         {"getRefCount", lua_Font_getRefCount},
         {"getRefCount", lua_Font_getRefCount},
@@ -1123,6 +1125,41 @@ int lua_Font_getCharacterSpacing(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Font_getFormat(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))
+            {
+                Font* instance = getInstance(state);
+                Font::Format result = instance->getFormat();
+
+                // Push the return value onto the stack.
+                lua_pushstring(state, lua_stringFromEnum_FontFormat(result));
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Font_getFormat - 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_Font_getIndexAtLocation(lua_State* state)
 int lua_Font_getIndexAtLocation(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.

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

@@ -11,6 +11,7 @@ int lua_Font_createText(lua_State* state);
 int lua_Font_drawText(lua_State* state);
 int lua_Font_drawText(lua_State* state);
 int lua_Font_finish(lua_State* state);
 int lua_Font_finish(lua_State* state);
 int lua_Font_getCharacterSpacing(lua_State* state);
 int lua_Font_getCharacterSpacing(lua_State* state);
+int lua_Font_getFormat(lua_State* state);
 int lua_Font_getIndexAtLocation(lua_State* state);
 int lua_Font_getIndexAtLocation(lua_State* state);
 int lua_Font_getLocationAtIndex(lua_State* state);
 int lua_Font_getLocationAtIndex(lua_State* state);
 int lua_Font_getRefCount(lua_State* state);
 int lua_Font_getRefCount(lua_State* state);

+ 31 - 0
gameplay/src/lua/lua_FontFormat.cpp

@@ -0,0 +1,31 @@
+#include "Base.h"
+#include "lua_FontFormat.h"
+
+namespace gameplay
+{
+
+static const char* enumStringEmpty = "";
+
+static const char* luaEnumString_FontFormat_BITMAP = "BITMAP";
+static const char* luaEnumString_FontFormat_DISTANCE_FIELD = "DISTANCE_FIELD";
+
+Font::Format lua_enumFromString_FontFormat(const char* s)
+{
+    if (strcmp(s, luaEnumString_FontFormat_BITMAP) == 0)
+        return Font::BITMAP;
+    if (strcmp(s, luaEnumString_FontFormat_DISTANCE_FIELD) == 0)
+        return Font::DISTANCE_FIELD;
+    return Font::BITMAP;
+}
+
+const char* lua_stringFromEnum_FontFormat(Font::Format e)
+{
+    if (e == Font::BITMAP)
+        return luaEnumString_FontFormat_BITMAP;
+    if (e == Font::DISTANCE_FIELD)
+        return luaEnumString_FontFormat_DISTANCE_FIELD;
+    return enumStringEmpty;
+}
+
+}
+

+ 15 - 0
gameplay/src/lua/lua_FontFormat.h

@@ -0,0 +1,15 @@
+#ifndef LUA_FONTFORMAT_H_
+#define LUA_FONTFORMAT_H_
+
+#include "Font.h"
+
+namespace gameplay
+{
+
+// Lua bindings for enum conversion functions for Font::Format.
+Font::Format lua_enumFromString_FontFormat(const char* s);
+const char* lua_stringFromEnum_FontFormat(Font::Format e);
+
+}
+
+#endif

+ 1 - 0
gameplay/src/lua/lua_FontText.cpp

@@ -7,6 +7,7 @@
 #include "Font.h"
 #include "Font.h"
 #include "Game.h"
 #include "Game.h"
 #include "Ref.h"
 #include "Ref.h"
+#include "lua_FontFormat.h"
 #include "lua_FontJustify.h"
 #include "lua_FontJustify.h"
 
 
 namespace gameplay
 namespace gameplay

+ 369 - 26
gameplay/src/lua/lua_Form.cpp

@@ -28,6 +28,7 @@
 #include "VerticalLayout.h"
 #include "VerticalLayout.h"
 #include "lua_ContainerScroll.h"
 #include "lua_ContainerScroll.h"
 #include "lua_ControlAlignment.h"
 #include "lua_ControlAlignment.h"
+#include "lua_ControlAutoSize.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlListenerEventType.h"
 #include "lua_ControlState.h"
 #include "lua_ControlState.h"
 #include "lua_CurveInterpolationType.h"
 #include "lua_CurveInterpolationType.h"
@@ -100,9 +101,13 @@ void luaRegister_Form()
         {"insertControl", lua_Form_insertControl},
         {"insertControl", lua_Form_insertControl},
         {"isContainer", lua_Form_isContainer},
         {"isContainer", lua_Form_isContainer},
         {"isEnabled", lua_Form_isEnabled},
         {"isEnabled", lua_Form_isEnabled},
+        {"isHeightPercentage", lua_Form_isHeightPercentage},
         {"isScrollBarsAutoHide", lua_Form_isScrollBarsAutoHide},
         {"isScrollBarsAutoHide", lua_Form_isScrollBarsAutoHide},
         {"isScrolling", lua_Form_isScrolling},
         {"isScrolling", lua_Form_isScrolling},
         {"isVisible", lua_Form_isVisible},
         {"isVisible", lua_Form_isVisible},
+        {"isWidthPercentage", lua_Form_isWidthPercentage},
+        {"isXPercentage", lua_Form_isXPercentage},
+        {"isYPercentage", lua_Form_isYPercentage},
         {"release", lua_Form_release},
         {"release", lua_Form_release},
         {"removeControl", lua_Form_removeControl},
         {"removeControl", lua_Form_removeControl},
         {"removeListener", lua_Form_removeListener},
         {"removeListener", lua_Form_removeListener},
@@ -144,6 +149,8 @@ void luaRegister_Form()
         {"setTextRightToLeft", lua_Form_setTextRightToLeft},
         {"setTextRightToLeft", lua_Form_setTextRightToLeft},
         {"setVisible", lua_Form_setVisible},
         {"setVisible", lua_Form_setVisible},
         {"setWidth", lua_Form_setWidth},
         {"setWidth", lua_Form_setWidth},
+        {"setX", lua_Form_setX},
+        {"setY", lua_Form_setY},
         {"setZIndex", lua_Form_setZIndex},
         {"setZIndex", lua_Form_setZIndex},
         {"update", lua_Form_update},
         {"update", lua_Form_update},
         {NULL, NULL}
         {NULL, NULL}
@@ -1047,10 +1054,10 @@ int lua_Form_getAutoHeight(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 Form* instance = getInstance(state);
                 Form* instance = getInstance(state);
-                bool result = instance->getAutoHeight();
+                Control::AutoSize result = instance->getAutoHeight();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -1082,10 +1089,10 @@ int lua_Form_getAutoWidth(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
             {
                 Form* instance = getInstance(state);
                 Form* instance = getInstance(state);
-                bool result = instance->getAutoWidth();
+                Control::AutoSize result = instance->getAutoWidth();
 
 
                 // Push the return value onto the stack.
                 // Push the return value onto the stack.
-                lua_pushboolean(state, result);
+                lua_pushstring(state, lua_stringFromEnum_ControlAutoSize(result));
 
 
                 return 1;
                 return 1;
             }
             }
@@ -2232,7 +2239,7 @@ int lua_Form_getScrollPosition(lua_State* state)
                 void* returnPtr = (void*)&(instance->getScrollPosition());
                 void* returnPtr = (void*)&(instance->getScrollPosition());
                 if (returnPtr)
                 if (returnPtr)
                 {
                 {
-                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
                     object->instance = returnPtr;
                     object->instance = returnPtr;
                     object->owns = false;
                     object->owns = false;
                     luaL_getmetatable(state, "Vector2");
                     luaL_getmetatable(state, "Vector2");
@@ -3113,6 +3120,41 @@ int lua_Form_isEnabled(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Form_isHeightPercentage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                bool result = instance->isHeightPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_isHeightPercentage - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Form_isScrollBarsAutoHide(lua_State* state)
 int lua_Form_isScrollBarsAutoHide(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -3218,6 +3260,111 @@ int lua_Form_isVisible(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Form_isWidthPercentage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                bool result = instance->isWidthPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_isWidthPercentage - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_isXPercentage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                bool result = instance->isXPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_isXPercentage - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_isYPercentage(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA))
+            {
+                Form* instance = getInstance(state);
+                bool result = instance->isYPercentage();
+
+                // Push the return value onto the stack.
+                lua_pushboolean(state, result);
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Form_isYPercentage - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_Form_release(lua_State* state)
 int lua_Form_release(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -3528,17 +3675,35 @@ int lua_Form_setAutoHeight(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                Form* instance = getInstance(state);
-                instance->setAutoHeight(param1);
-                
-                return 0;
-            }
+                    Form* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    Form* instance = getInstance(state);
+                    instance->setAutoHeight(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_Form_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_Form_setAutoHeight - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -3564,17 +3729,35 @@ int lua_Form_setAutoWidth(lua_State* state)
     {
     {
         case 2:
         case 2:
         {
         {
-            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
-                lua_type(state, 2) == LUA_TBOOLEAN)
+            do
             {
             {
-                // Get parameter 1 off the stack.
-                bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    lua_type(state, 2) == LUA_TBOOLEAN)
+                {
+                    // Get parameter 1 off the stack.
+                    bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2);
 
 
-                Form* instance = getInstance(state);
-                instance->setAutoWidth(param1);
-                
-                return 0;
-            }
+                    Form* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
+
+            do
+            {
+                if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                    (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    Control::AutoSize param1 = (Control::AutoSize)lua_enumFromString_ControlAutoSize(luaL_checkstring(state, 2));
+
+                    Form* instance = getInstance(state);
+                    instance->setAutoWidth(param1);
+                    
+                    return 0;
+                }
+            } while (0);
 
 
             lua_pushstring(state, "lua_Form_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_pushstring(state, "lua_Form_setAutoWidth - Failed to match the given parameters to a valid function signature.");
             lua_error(state);
             lua_error(state);
@@ -4068,9 +4251,31 @@ int lua_Form_setHeight(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Form* instance = getInstance(state);
+                instance->setHeight(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setHeight - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
@@ -4557,7 +4762,7 @@ int lua_Form_setScrollPosition(lua_State* state)
             {
             {
                 // Get parameter 1 off the stack.
                 // Get parameter 1 off the stack.
                 bool param1Valid;
                 bool param1Valid;
-                ScriptUtil::LuaArray<Vector2> param1 = ScriptUtil::getObjectPointer<Vector2>(2, "Vector2", true, &param1Valid);
+                gameplay::ScriptUtil::LuaArray<Vector2> param1 = gameplay::ScriptUtil::getObjectPointer<Vector2>(2, "Vector2", true, &param1Valid);
                 if (!param1Valid)
                 if (!param1Valid)
                 {
                 {
                     lua_pushstring(state, "Failed to convert parameter 1 to type 'Vector2'.");
                     lua_pushstring(state, "Failed to convert parameter 1 to type 'Vector2'.");
@@ -5198,9 +5403,147 @@ int lua_Form_setWidth(lua_State* state)
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Form* instance = getInstance(state);
+                instance->setWidth(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setWidth - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         default:
         default:
         {
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 2).");
+            lua_pushstring(state, "Invalid number of parameters (expected 2 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_setX(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Form* instance = getInstance(state);
+                instance->setX(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setX - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Form* instance = getInstance(state);
+                instance->setX(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setX - 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 or 3).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
+int lua_Form_setY(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 2:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                Form* instance = getInstance(state);
+                instance->setY(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setY - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        case 3:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA) &&
+                lua_type(state, 2) == LUA_TNUMBER &&
+                lua_type(state, 3) == LUA_TBOOLEAN)
+            {
+                // Get parameter 1 off the stack.
+                float param1 = (float)luaL_checknumber(state, 2);
+
+                // Get parameter 2 off the stack.
+                bool param2 = gameplay::ScriptUtil::luaCheckBool(state, 3);
+
+                Form* instance = getInstance(state);
+                instance->setY(param1, param2);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_Form_setY - 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 or 3).");
             lua_error(state);
             lua_error(state);
             break;
             break;
         }
         }

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

@@ -65,9 +65,13 @@ int lua_Form_getZIndex(lua_State* state);
 int lua_Form_insertControl(lua_State* state);
 int lua_Form_insertControl(lua_State* state);
 int lua_Form_isContainer(lua_State* state);
 int lua_Form_isContainer(lua_State* state);
 int lua_Form_isEnabled(lua_State* state);
 int lua_Form_isEnabled(lua_State* state);
+int lua_Form_isHeightPercentage(lua_State* state);
 int lua_Form_isScrollBarsAutoHide(lua_State* state);
 int lua_Form_isScrollBarsAutoHide(lua_State* state);
 int lua_Form_isScrolling(lua_State* state);
 int lua_Form_isScrolling(lua_State* state);
 int lua_Form_isVisible(lua_State* state);
 int lua_Form_isVisible(lua_State* state);
+int lua_Form_isWidthPercentage(lua_State* state);
+int lua_Form_isXPercentage(lua_State* state);
+int lua_Form_isYPercentage(lua_State* state);
 int lua_Form_release(lua_State* state);
 int lua_Form_release(lua_State* state);
 int lua_Form_removeControl(lua_State* state);
 int lua_Form_removeControl(lua_State* state);
 int lua_Form_removeListener(lua_State* state);
 int lua_Form_removeListener(lua_State* state);
@@ -109,6 +113,8 @@ int lua_Form_setTextColor(lua_State* state);
 int lua_Form_setTextRightToLeft(lua_State* state);
 int lua_Form_setTextRightToLeft(lua_State* state);
 int lua_Form_setVisible(lua_State* state);
 int lua_Form_setVisible(lua_State* state);
 int lua_Form_setWidth(lua_State* state);
 int lua_Form_setWidth(lua_State* state);
+int lua_Form_setX(lua_State* state);
+int lua_Form_setY(lua_State* state);
 int lua_Form_setZIndex(lua_State* state);
 int lua_Form_setZIndex(lua_State* state);
 int lua_Form_static_ANIMATE_OPACITY(lua_State* state);
 int lua_Form_static_ANIMATE_OPACITY(lua_State* state);
 int lua_Form_static_ANIMATE_POSITION(lua_State* state);
 int lua_Form_static_ANIMATE_POSITION(lua_State* state);

+ 44 - 44
gameplay/src/lua/lua_Game.cpp

@@ -1069,6 +1069,50 @@ int lua_Game_getPhysicsController(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
+int lua_Game_getScriptController(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))
+            {
+                Game* instance = getInstance(state);
+                void* returnPtr = (void*)instance->getScriptController();
+                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, "ScriptController");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
+            }
+
+            lua_pushstring(state, "lua_Game_getScriptController - 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_Game_getSensorValues(lua_State* state)
 int lua_Game_getSensorValues(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.
@@ -1125,50 +1169,6 @@ int lua_Game_getSensorValues(lua_State* state)
     return 0;
     return 0;
 }
 }
 
 
-int lua_Game_getScriptController(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))
-            {
-                Game* instance = getInstance(state);
-                void* returnPtr = (void*)instance->getScriptController();
-                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, "ScriptController");
-                    lua_setmetatable(state, -2);
-                }
-                else
-                {
-                    lua_pushnil(state);
-                }
-
-                return 1;
-            }
-
-            lua_pushstring(state, "lua_Game_getScriptController - 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_Game_getState(lua_State* state)
 int lua_Game_getState(lua_State* state)
 {
 {
     // Get the number of parameters.
     // Get the number of parameters.

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott