浏览代码

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

Conflicts:
	gameplay-tests/src/TestsGame.cpp
Darryl Gough 13 年之前
父节点
当前提交
f487845636

+ 180 - 12
gameplay.sln

@@ -45,63 +45,231 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample06-racer", "gameplay-
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|BlackBerry = Debug|BlackBerry
+		Debug|BlackBerrySimulator = Debug|BlackBerrySimulator
 		Debug|Win32 = Debug|Win32
+		DebugMem|BlackBerry = DebugMem|BlackBerry
+		DebugMem|BlackBerrySimulator = DebugMem|BlackBerrySimulator
 		DebugMem|Win32 = DebugMem|Win32
+		Release|BlackBerry = Release|BlackBerry
+		Release|BlackBerrySimulator = Release|BlackBerrySimulator
 		Release|Win32 = Release|Win32
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Debug|Win32.Build.0 = Debug|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.ActiveCfg = Release|Win32
 		{1032BA4B-57EB-4348-9E03-29DD63E80E4A}.Release|Win32.Build.0 = Release|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.Build.0 = Debug|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.ActiveCfg = Release|Win32
+		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.Build.0 = Release|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|Win32.Build.0 = Debug|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|Win32.ActiveCfg = Release|Win32
+		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|Win32.Build.0 = Release|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Debug|Win32.Build.0 = Debug|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.ActiveCfg = Release|Win32
 		{9A515C8B-3320-4C5C-9754-211E91206C9D}.Release|Win32.Build.0 = Release|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Debug|Win32.Build.0 = Debug|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.ActiveCfg = Release|Win32
 		{CC37B8E9-6402-4841-8D6A-5D908A5909B3}.Release|Win32.Build.0 = Release|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|Win32.ActiveCfg = Debug|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Debug|Win32.Build.0 = Debug|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.ActiveCfg = Release|Win32
 		{87388E8B-F3CF-428F-BC2C-C1886248C111}.Release|Win32.Build.0 = Release|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Debug|Win32.Build.0 = Debug|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|Win32.ActiveCfg = Release|Win32
 		{CB5ABFAA-EA69-E439-5A4D-3B9359916C71}.Release|Win32.Build.0 = Release|Win32
-		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|Win32.ActiveCfg = Debug|Win32
-		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Debug|Win32.Build.0 = Debug|Win32
-		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
-		{D672DC66-3CE0-4878-B0D2-813CA731012F}.DebugMem|Win32.Build.0 = DebugMem|Win32
-		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|Win32.ActiveCfg = Release|Win32
-		{D672DC66-3CE0-4878-B0D2-813CA731012F}.Release|Win32.Build.0 = Release|Win32
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Debug|Win32.Build.0 = Debug|Win32
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.ActiveCfg = Release|Win32
 		{C6121A62-AA46-BA6D-A1CE-8000544456AA}.Release|Win32.Build.0 = Release|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.ActiveCfg = Debug|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Debug|Win32.Build.0 = Debug|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.DebugMem|Win32.Build.0 = DebugMem|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.ActiveCfg = Release|Win32
-		{D70B295E-A2FF-2CBB-737E-3876E8AF77F6}.Release|Win32.Build.0 = Release|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.ActiveCfg = Debug|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.Build.0 = Debug|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerry.Deploy.0 = Debug|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.ActiveCfg = Debug|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.Build.0 = Debug|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|BlackBerrySimulator.Deploy.0 = Debug|BlackBerrySimulator
 		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|Win32.ActiveCfg = Debug|Win32
 		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Debug|Win32.Build.0 = Debug|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.ActiveCfg = DebugMem|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.Build.0 = DebugMem|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerry.Deploy.0 = DebugMem|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.ActiveCfg = DebugMem|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.Build.0 = DebugMem|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|BlackBerrySimulator.Deploy.0 = DebugMem|BlackBerrySimulator
 		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|Win32.ActiveCfg = DebugMem|Win32
 		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.DebugMem|Win32.Build.0 = DebugMem|Win32
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.ActiveCfg = Release|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.Build.0 = Release|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerry.Deploy.0 = Release|BlackBerry
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.ActiveCfg = Release|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.Build.0 = Release|BlackBerrySimulator
+		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|BlackBerrySimulator.Deploy.0 = Release|BlackBerrySimulator
 		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|Win32.ActiveCfg = Release|Win32
 		{1808B3EA-1ED5-1219-6D3C-9F588D2D8385}.Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection

+ 229 - 0
gameplay/gameplay.vcxproj

@@ -1,14 +1,38 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugMem|BlackBerry">
+      <Configuration>DebugMem</Configuration>
+      <Platform>BlackBerry</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugMem|BlackBerrySimulator">
+      <Configuration>DebugMem</Configuration>
+      <Platform>BlackBerrySimulator</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="DebugMem|Win32">
       <Configuration>DebugMem</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|BlackBerry">
+      <Configuration>Debug</Configuration>
+      <Platform>BlackBerry</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|BlackBerrySimulator">
+      <Configuration>Debug</Configuration>
+      <Platform>BlackBerrySimulator</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|BlackBerry">
+      <Configuration>Release</Configuration>
+      <Platform>BlackBerry</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|BlackBerrySimulator">
+      <Configuration>Release</Configuration>
+      <Platform>BlackBerrySimulator</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
@@ -608,48 +632,140 @@
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>true</UseDebugLibraries>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <UseDebugLibraries>false</UseDebugLibraries>
     <WholeProgramOptimization>true</WholeProgramOptimization>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
+    <OutDir>Device-$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'">
+    <OutDir>Simulator\</OutDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
     <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
+    <OutDir>Device-$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'">
+    <OutDir>Simulator\</OutDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <IntDir>$(Configuration)\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
+    <IntDir>Device-$(Configuration)\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'">
+    <IntDir>Simulator\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
     <IntDir>$(Configuration)\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
+    <IntDir>Device-$(Configuration)\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'">
+    <IntDir>Simulator\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <OutDir>$(Configuration)\</OutDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'">
+    <OutDir>Device-$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'">
+    <OutDir>Simulator\</OutDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <IntDir>$(Configuration)\</IntDir>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'">
+    <IntDir>Device-$(Configuration)\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'">
+    <IntDir>Simulator\</IntDir>
+    <TargetName>lib$(ProjectName)</TargetName>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <PrecompiledHeader>
@@ -667,6 +783,41 @@
       <GenerateDebugInformation>true</GenerateDebugInformation>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerry'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <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>
+      <RuntimeTypeInfo>
+      </RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|BlackBerrySimulator'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <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>
+      <RuntimeTypeInfo>
+      </RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|Win32'">
     <ClCompile>
       <PrecompiledHeader>
@@ -687,6 +838,47 @@
       </Verbose>
     </Lib>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerry'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GAMEPLAY_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Lib>
+      <Verbose>
+      </Verbose>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugMem|BlackBerrySimulator'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_ITERATOR_DEBUG_LEVEL=0;WIN32;_DEBUG;_LIB;GAMEPLAY_MEM_LEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeTypeInfo>true</RuntimeTypeInfo>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Lib>
+      <Verbose>
+      </Verbose>
+    </Lib>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <WarningLevel>Level3</WarningLevel>
@@ -705,6 +897,43 @@
       <OptimizeReferences>true</OptimizeReferences>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerry'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>-mfpu=neon %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|BlackBerrySimulator'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(ProjectDir)src;..\external-deps\lua\include;..\external-deps\bullet\include;..\external-deps\openal\include\AL;..\external-deps\alut\include\AL;..\external-deps\oggvorbis\include;..\external-deps\glew\include;..\external-deps\libpng\include;..\external-deps\zlib\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>

+ 4 - 0
gameplay/gameplay.xcodeproj/project.pbxproj

@@ -1622,6 +1622,7 @@
 		5B04C5C614BFCFE100EB0071 /* MeshBatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 4201818E14A41B18008C3F56 /* MeshBatch.h */; };
 		5B04C5CD14BFD48500EB0071 /* gameplay-main-ios.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B04C5CB14BFD48500EB0071 /* gameplay-main-ios.mm */; };
 		5B04C5CE14BFD48500EB0071 /* PlatformiOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B04C5CC14BFD48500EB0071 /* PlatformiOS.mm */; };
+		5B21E99616153890006EBEAC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B21E99516153890006EBEAC /* IOKit.framework */; };
 		5B2BC75F1512514500D176CD /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC75D1512514500D176CD /* OpenAL.framework */; };
 		5B2BC7601512514500D176CD /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC75E1512514500D176CD /* OpenGL.framework */; };
 		5B2BC7621512514D00D176CD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B2BC7611512514D00D176CD /* QuartzCore.framework */; };
@@ -2549,6 +2550,7 @@
 		5B04C5CA14BFCFE100EB0071 /* libgameplay.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgameplay.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		5B04C5CB14BFD48500EB0071 /* gameplay-main-ios.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "gameplay-main-ios.mm"; path = "src/gameplay-main-ios.mm"; sourceTree = SOURCE_ROOT; };
 		5B04C5CC14BFD48500EB0071 /* PlatformiOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PlatformiOS.mm; path = src/PlatformiOS.mm; sourceTree = SOURCE_ROOT; };
+		5B21E99516153890006EBEAC /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
 		5B2BC75D1512514500D176CD /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.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; };
@@ -2617,6 +2619,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				5B21E99616153890006EBEAC /* IOKit.framework in Frameworks */,
 				5B2BC7641512516B00D176CD /* libz.dylib in Frameworks */,
 				5B2BC7621512514D00D176CD /* QuartzCore.framework in Frameworks */,
 				5B2BC75F1512514500D176CD /* OpenAL.framework in Frameworks */,
@@ -3582,6 +3585,7 @@
 		42CCD4AF146D811D00353661 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				5B21E99516153890006EBEAC /* IOKit.framework */,
 				5B04C5FD14BFE52300EB0071 /* iOS */,
 				5B04C5FE14BFE52F00EB0071 /* MacOSX */,
 			);

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

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "5B04C52B14BFCFE100EB0071"
+               BuildableName = "libgameplay.a"
+               BlueprintName = "gameplay-ios"
+               ReferencedContainer = "container:gameplay.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

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

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "4234D99914686C52003031B3"
+               BuildableName = "libgameplay.a"
+               BlueprintName = "gameplay-macosx"
+               ReferencedContainer = "container:gameplay.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      buildConfiguration = "Debug">
+      <Testables>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Debug"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      allowLocationSimulation = "YES">
+      <AdditionalOptions>
+      </AdditionalOptions>
+   </LaunchAction>
+   <ProfileAction
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      buildConfiguration = "Release"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 16 - 0
gameplay/src/Container.cpp

@@ -581,6 +581,11 @@ bool Container::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
 
 bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
 {
+    // This event may run untrusted code by notifying listeners of events.
+    // If the user calls exit() or otherwise releases this container, we
+    // need to keep it alive until the method returns.
+    addRef();
+
     std::vector<Control*>::const_iterator it;
     for (it = _controls.begin(); it < _controls.end(); it++)
     {
@@ -595,6 +600,7 @@ bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
         {
             if (control->keyEvent(evt, key))
             {
+                release();
                 return _consumeInputEvents;
             }
             else if (evt == Keyboard::KEY_CHAR && key == Keyboard::KEY_TAB)
@@ -614,6 +620,7 @@ bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
                     if (nextControl->getFocusIndex() == focusIndex)
                     {
                         nextControl->setState(Control::FOCUS);
+                        release();
                         return _consumeInputEvents;
                     }
                 }
@@ -621,6 +628,7 @@ bool Container::keyEvent(Keyboard::KeyEvent evt, int key)
         }
     }
 
+    release();
     return false;
 }
 
@@ -1005,6 +1013,11 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         return false;
     }
 
+    // This event may run untrusted code by notifying listeners of events.
+    // If the user calls exit() or otherwise releases this container, we
+    // need to keep it alive until the method returns.
+    addRef();
+
     bool eventConsumed = false;
     const Theme::Border& border = getBorder(_state);
     const Theme::Padding& padding = getPadding();
@@ -1058,6 +1071,7 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
 
     if (!isEnabled())
     {
+        release();
         return (_consumeInputEvents | eventConsumed);
     }
     
@@ -1077,6 +1091,7 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         {
             setState(Control::NORMAL);
             _contactIndex = INVALID_CONTACT_INDEX;
+            release();
             return false;
         }
         break;
@@ -1100,6 +1115,7 @@ bool Container::pointerEvent(bool mouse, char evt, int x, int y, int data)
         }
     }
 
+    release();
     return (_consumeInputEvents | eventConsumed);
 }
 

+ 8 - 1
gameplay/src/Control.cpp

@@ -7,7 +7,7 @@ namespace gameplay
 
 Control::Control()
     : _id(""), _state(Control::NORMAL), _bounds(Rectangle::empty()), _clipBounds(Rectangle::empty()), _viewportClipBounds(Rectangle::empty()),
-    _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(true), _autoWidth(false), _autoHeight(false), _listeners(NULL),
+    _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(true), _alignment(ALIGN_TOP_LEFT), _autoWidth(false), _autoHeight(false), _listeners(NULL),
     _contactIndex(INVALID_CONTACT_INDEX), _focusIndex(0), _parent(NULL), _styleOverridden(false), _skin(NULL)
 {
     addScriptEvent("controlEvent", "<Control>[Control::Listener::EventType]");
@@ -798,6 +798,11 @@ bool Control::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
 
 void Control::notifyListeners(Listener::EventType eventType)
 {
+    // This method runs untrusted code by notifying listeners of events.
+    // If the user calls exit() or otherwise releases this control, we
+    // need to keep it alive until the method returns.
+    addRef();
+
     if (_listeners)
     {
         std::map<Listener::EventType, std::list<Listener*>*>::const_iterator itr = _listeners->find(eventType);
@@ -813,6 +818,8 @@ void Control::notifyListeners(Listener::EventType eventType)
     }
 
     fireScriptEvent<void>("controlEvent", this, eventType);
+
+    release();
 }
 
 void Control::update(const Control* container, const Vector2& offset)

+ 9 - 9
gameplay/src/Form.cpp

@@ -592,10 +592,10 @@ bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int
     // Check for a collision with each Form in __forms.
     // Pass the event on.
     bool eventConsumed = false;
-    std::vector<Form*>::const_iterator it;
-    for (it = __forms.begin(); it < __forms.end(); it++)
+    size_t size = __forms.size();
+    for (size_t i = 0; i < size; ++i)
     {
-        Form* form = *it;
+        Form* form = __forms[i];
         GP_ASSERT(form);
 
         if (form->isEnabled())
@@ -639,10 +639,10 @@ bool Form::touchEventInternal(Touch::TouchEvent evt, int x, int y, unsigned int
 
 bool Form::keyEventInternal(Keyboard::KeyEvent evt, int key)
 {
-    std::vector<Form*>::const_iterator it;
-    for (it = __forms.begin(); it < __forms.end(); it++)
+    size_t size = __forms.size();
+    for (size_t i = 0; i < size; ++i)
     {
-        Form* form = *it;
+        Form* form = __forms[i];
         GP_ASSERT(form);
         if (form->isEnabled())
         {
@@ -657,10 +657,10 @@ bool Form::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheelDelt
 {
     bool eventConsumed = false;
 
-    std::vector<Form*>::const_iterator it;
-    for (it = __forms.begin(); it < __forms.end(); it++)
+    size_t size = __forms.size();
+    for (size_t i = 0; i < size; ++i)
     {
-        Form* form = *it;
+        Form* form = __forms[i];
         GP_ASSERT(form);
 
         if (form->isEnabled())

+ 4 - 4
gameplay/src/Mesh.cpp

@@ -109,10 +109,10 @@ Mesh* Mesh::createQuadFullscreen()
 
     float vertices[] =
     {
-        x, y2,   0, 0,
-        x, y,    0, 1,
-        x2, y2,  1, 0,
-        x2, y,   1, 1
+        x, y2,   0, 1,
+        x, y,    0, 0,
+        x2, y2,  1, 1,
+        x2, y,   1, 0
     };
 
     VertexFormat::Element elements[] =

+ 823 - 33
gameplay/src/PlatformMacOSX.mm

@@ -7,14 +7,24 @@
 #include "Form.h"
 #include "ScriptController.h"
 #include <unistd.h>
+#include <IOKit/hid/IOHIDLib.h>
 #import <Cocoa/Cocoa.h>
 #import <QuartzCore/CVDisplayLink.h>
 #import <OpenGL/OpenGL.h>
 #import <mach/mach_time.h>
+#import <Foundation/Foundation.h>
+
+// These should probably be moved to a platform common file
+#define SONY_USB_VENDOR_ID          0x54c
+#define SONY_USB_PS3_PRODUCT_ID     0x268
+
 
 using namespace std;
 using namespace gameplay;
 
+@class View;
+@class OSXGamepad;
+
 // Default to 720p
 static int __width = 1280;
 static int __height = 720;
@@ -40,6 +50,29 @@ static void* __attachToWindow = NULL;
 static bool __mouseCaptured = false;
 static CGPoint __mouseCapturePoint;
 static bool __cursorVisible = true;
+static View* __view = NULL;
+
+static NSMutableDictionary *__activeGamepads = NULL;
+static NSMutableArray *__gamepads = NULL;
+static IOHIDManagerRef __hidManagerRef = NULL;
+
+// Gamepad Helper Function
+OSXGamepad *gamepadForLocationID(NSNumber *locationID);
+OSXGamepad *gamepadForLocationIDValue(unsigned int locationIDValue);
+OSXGamepad *gamepadForGameHandle(int gameHandle);
+
+
+// IOHid Helper Functions
+CFMutableDictionaryRef IOHIDCreateDeviceMatchingDictionary(UInt32 inUsagePage, UInt32 inUsage);
+CFStringRef IOHIDDeviceGetStringProperty(IOHIDDeviceRef deviceRef, CFStringRef key);
+int IOHIDDeviceGetIntProperty(IOHIDDeviceRef deviceRef, CFStringRef key);
+
+// IOHid Callbacks
+static void hidDeviceDiscoveredCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDDeviceRef inIOHIDDeviceRef);
+static void hidDeviceRemovalCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDDeviceRef inIOHIDDeviceRef);
+static void hidDeviceValueAvailableCallback(void *inContext, IOReturn inResult,  void *inSender);
+
+
 
 double getMachTimeInMilliseconds()
 {
@@ -54,7 +87,537 @@ double getMachTimeInMilliseconds()
     return ((double)mach_absolute_time() * (double)s_timebase_info.numer) / (kOneMillion * (double)s_timebase_info.denom);
 }
 
-@class View;
+
+@interface OSXGamepadAxis : NSObject
+{
+    IOHIDElementRef e;
+    CFIndex v;
+    CFIndex logMin;
+    CFIndex logMax;
+}
++ gamepadAxisWithAxisElement:(IOHIDElementRef)element;
+- initWithAxisElement:(IOHIDElementRef)element;
+- (IOHIDElementRef)element;
+- (IOHIDElementCookie)cookie;
+- (uint32_t)usage;
+- (uint32_t)usagePage;
+- (CFIndex)logicalMinimum;
+- (CFIndex)logicalMaximum;
+
+- (float)calibratedValue;
+- (CFIndex)value;
+- (void)setValue:(CFIndex)value;
+@end
+@implementation OSXGamepadAxis
++ gamepadAxisWithAxisElement:(IOHIDElementRef)element
+{
+    return [[[[self class] alloc] initWithAxisElement:element] autorelease];
+}
+- initWithAxisElement:(IOHIDElementRef)element
+{
+    if((self = [super init]))
+    {
+        e = (IOHIDElementRef)CFRetain(element);
+    }
+    return self;
+}
+- (void)dealloc
+{
+    CFRelease(e);
+    [super dealloc];
+}
+- (IOHIDElementRef)element
+{
+    return e;
+}
+- (IOHIDElementCookie)cookie
+{
+    return IOHIDElementGetCookie(e);
+}
+- (bool)isHatSwitch {
+    return (IOHIDElementGetUsage(e) == kHIDUsage_GD_Hatswitch);
+}
+- (uint32_t)usage
+{
+    return IOHIDElementGetUsage(e);
+}
+- (uint32_t)usagePage
+{
+    return IOHIDElementGetUsagePage(e);
+}
+- (CFIndex)logicalMinimum
+{
+    return IOHIDElementGetLogicalMin(e);    
+}
+- (CFIndex)logicalMaximum
+{
+    return IOHIDElementGetLogicalMax(e);
+}
+- (float)calibratedValue
+{
+    float cmax = 2.0f;
+    float cmin = 0.0f;
+    return ((((v - [self logicalMinimum]) * (cmax - cmin)) / ([self logicalMaximum] - [self logicalMinimum])) + cmin - 1.0f);    
+}
+- (CFIndex)value
+{
+    return v;
+}
+- (void)setValue:(CFIndex)value
+{
+    v = value;
+}
+@end
+
+@interface OSXGamepadButton : NSObject
+{
+    IOHIDElementRef e;
+    IOHIDElementRef te;
+    bool state;
+    int triggerValue;
+}
++ gamepadButtonWithButtonElement:(IOHIDElementRef)element;
+- initWithButtonElement:(IOHIDElementRef)element;
+- (void)setTriggerElement:(IOHIDElementRef)element;
+- (IOHIDElementRef)element;
+- (IOHIDElementCookie)cookie;
+- (IOHIDElementRef)triggerElement;
+- (IOHIDElementCookie)triggerCookie;
+
+- (bool)isTriggerButton;
+- (uint32_t)usage;
+- (uint32_t)usagePage;
+- (int)stateValue;
+- (float)calibratedStateValue;
+- (void)setStateValue:(int)value;
+- (bool)state;
+- (void)setState:(bool)state;
+@end
+@implementation OSXGamepadButton
++ gamepadButtonWithButtonElement:(IOHIDElementRef)element
+{
+    return [[[[self class] alloc] initWithButtonElement:element] autorelease];
+}
+- initWithButtonElement:(IOHIDElementRef)element
+{
+    if((self = [super init]))
+    {
+        e = (IOHIDElementRef)CFRetain(element);
+        te = NULL;
+        state = false;
+    }
+    return self;
+}
+- (void)dealloc
+{
+    CFRelease(e);
+    if(te != NULL) CFRelease(te);
+    [super dealloc];
+}
+- (void)setTriggerElement:(IOHIDElementRef)element {
+    if(te)
+    {
+        CFRelease(te);
+        te = NULL;
+    }
+    if(element)
+    {
+        te = (IOHIDElementRef)CFRetain(element);
+    }
+}
+- (IOHIDElementRef)element
+{
+    return e;
+}
+- (IOHIDElementCookie)cookie
+{
+    return IOHIDElementGetCookie(e);
+}
+- (IOHIDElementRef)triggerElement
+{
+    return te;
+}
+- (IOHIDElementCookie)triggerCookie
+{
+    return IOHIDElementGetCookie(te);
+}
+- (bool)isTriggerButton
+{
+    return (te != NULL);
+}
+- (uint32_t)usage
+{
+    return IOHIDElementGetUsage(e);
+}
+- (uint32_t)usagePage
+{
+    return IOHIDElementGetUsagePage(e);
+}
+- (void)setStateValue:(int)value {
+    triggerValue = value;
+}
+- (int)stateValue
+{
+    return triggerValue;
+}
+- (float)calibratedStateValue
+{
+    return (float)triggerValue; // TODO: Need to figure out expected range
+}
+- (bool)state
+{
+    return state;
+}
+- (void)setState:(bool)s
+{
+    state = s;
+}
+@end
+
+@interface OSXGamepad : NSObject
+{
+    IOHIDDeviceRef hidDeviceRef;
+    IOHIDQueueRef queueRef;
+    NSMutableArray *buttons;
+    NSMutableArray *triggerButtons;
+    NSMutableArray *axes;
+}
+@property (assign) IOHIDDeviceRef hidDeviceRef;
+@property (assign) IOHIDQueueRef queueRef;
+@property (retain) NSMutableArray *buttons;
+@property (retain) NSMutableArray *triggerButtons;
+@property (retain) NSMutableArray *axes;
+
+- initWithDevice:(IOHIDDeviceRef)rawDevice;
+- (IOHIDDeviceRef)rawDevice;
+- (NSNumber*)locationID;
+
+- (void)initializeGamepadElements;
+- (OSXGamepadButton*)buttonWithCookie:(IOHIDElementCookie)cookie;
+
+- (bool)startListening;
+- (void)stopListening;
+
+- (NSString *)identifierName;
+- (NSString *)productName;
+- (NSString *)manufacturerName;
+- (NSString *)serialNumber;
+- (int)vendorID;
+- (int)productID;
+
+- (NSUInteger)numberOfAxes;
+- (NSUInteger)numberOfSticks;
+- (NSUInteger)numberOfButtons;
+- (NSUInteger)numberOfTriggerButtons;
+- (OSXGamepadAxis*)axisAtIndex:(NSUInteger)index;
+- (OSXGamepadButton*)buttonAtIndex:(NSUInteger)index;
+- (OSXGamepadButton*)triggerButtonAtIndex:(NSUInteger)index;
+@end
+
+@implementation OSXGamepad
+
+@synthesize hidDeviceRef;
+@synthesize queueRef;
+@synthesize buttons;
+@synthesize triggerButtons;
+@synthesize axes;
+
+- initWithDevice:(IOHIDDeviceRef)rawDevice
+{
+    if((self = [super init]))
+    {
+        [self setButtons:[NSMutableArray array]];
+        [self setTriggerButtons:[NSMutableArray array]];
+        [self setAxes:[NSMutableArray array]];
+
+        CFRetain(rawDevice);
+        IOHIDQueueRef queue = IOHIDQueueCreate(CFAllocatorGetDefault(), rawDevice, 10, kIOHIDOptionsTypeNone);
+        [self setHidDeviceRef:rawDevice];
+        [self setQueueRef:queue];
+        
+        [self initializeGamepadElements];
+        [self startListening];
+    }
+    return self;
+}
+- (void)dealloc
+{
+    [self stopListening];
+    
+    CFRelease([self rawDevice]);
+    CFRelease([self queueRef]);
+    [self setQueueRef:NULL];
+    [self setHidDeviceRef:NULL];
+    
+    [self setButtons:NULL];
+    [self setTriggerButtons:NULL];
+    [self setAxes:NULL];
+    [super dealloc];
+}
+- (IOHIDDeviceRef)rawDevice
+{
+    return [self hidDeviceRef];
+}
+- (NSNumber*)locationID
+{
+    return (NSNumber*)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDLocationIDKey));
+}
+
+- (void)initializeGamepadElements
+{
+    CFArrayRef elements = IOHIDDeviceCopyMatchingElements([self rawDevice], NULL, kIOHIDOptionsTypeNone);
+    for(int i = 0; i < CFArrayGetCount(elements); i++)
+    {
+        IOHIDElementRef hidElement = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
+        IOHIDElementType type = IOHIDElementGetType(hidElement);
+
+        if (type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Axis)
+        {
+            uint32_t pageUsage = IOHIDElementGetUsage(hidElement);
+            IOHIDElementCookie cookie = IOHIDElementGetCookie(hidElement);
+
+            switch(pageUsage)
+            {
+                case kHIDUsage_GD_X:
+                case kHIDUsage_GD_Y:
+                case kHIDUsage_GD_Z:
+                case kHIDUsage_GD_Rx:
+                case kHIDUsage_GD_Ry:
+                case kHIDUsage_GD_Rz:
+                {
+                    OSXGamepadAxis *axis = [OSXGamepadAxis gamepadAxisWithAxisElement:hidElement];
+                    [[self axes] addObject:axis];
+                }
+                    break;
+                default:
+                    // Ignore the pointers
+                    // Note: Some of the pointers are for the 6-axis accelerometer in a PS3 controller
+                    // Note: L2/R2 triggers are at cookie 39 and 40 base 10 tied to 9 and 10 button elements
+                    break;
+            }
+
+        }
+        if(type == kIOHIDElementTypeInput_Button)
+        {
+            OSXGamepadButton *button = [OSXGamepadButton gamepadButtonWithButtonElement:hidElement];
+            [[self buttons] addObject:button];
+        }
+    }
+    // Go back and get proprietary information (e.g. triggers) and asscoaite with appropriate values
+    // Example for other trigger buttons
+    uint32_t vendorID = [self vendorID];
+    uint32_t productID = [self productID];
+    for(int i = 0; i < CFArrayGetCount(elements); i++)
+    {
+        IOHIDElementRef hidElement = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
+        IOHIDElementType type = IOHIDElementGetType(hidElement);
+        IOHIDElementCookie cookie = IOHIDElementGetCookie(hidElement);
+        
+        // Gamepad specific code
+        // Not sure if there is a better way to associate buttons and misc hid elements :/
+        if(vendorID == SONY_USB_VENDOR_ID && productID == SONY_USB_PS3_PRODUCT_ID)
+        {
+            if((unsigned long)cookie == 39)
+            {
+                OSXGamepadButton *leftTrigger = [self buttonWithCookie:(IOHIDElementCookie)9];
+                if(leftTrigger)
+                {
+                    [leftTrigger setTriggerElement:hidElement];
+                    [[self triggerButtons] addObject:leftTrigger];
+                    //[[self buttons] removeObject:leftTrigger]; Defer to gamepad team on this line..  not sure how they intend to tackle
+                }
+            }
+            if((unsigned long)cookie == 40)
+            {
+                OSXGamepadButton *rightTrigger = [self buttonWithCookie:(IOHIDElementCookie)10];
+                if(rightTrigger)
+                {
+                    [rightTrigger setTriggerElement:hidElement];
+                    [[self triggerButtons] addObject:rightTrigger];
+                    //[[self buttons] removeObject:rightTrigger];
+                }
+            }
+        }
+    }
+    
+}
+- (OSXGamepadButton*)buttonWithCookie:(IOHIDElementCookie)cookie {
+    for(OSXGamepadButton *b in [self buttons]) {
+        if([b cookie] == cookie) return b;
+    }
+    return NULL;
+}
+
+- (bool)startListening
+{
+    IOReturn kr = IOHIDDeviceOpen([self hidDeviceRef], kIOHIDOptionsTypeNone);
+    if(kr != 0) {
+        return false;
+    }
+    IOHIDDeviceScheduleWithRunLoop([self hidDeviceRef], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+    
+    IOHIDQueueStart([self queueRef]);
+    IOHIDQueueRegisterValueAvailableCallback([self queueRef], hidDeviceValueAvailableCallback, self);
+    
+    CFArrayRef elements = (CFArrayRef)[self watchedElements];
+    for(int i = 0; i < CFArrayGetCount(elements); i++)
+    {
+        IOHIDElementRef hidElement = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
+        IOHIDQueueAddElement([self queueRef], hidElement);
+    }
+    IOHIDQueueScheduleWithRunLoop([self queueRef], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+    
+    return true;
+}
+- (void)stopListening
+{
+    IOHIDQueueUnscheduleFromRunLoop([self queueRef], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+    IOHIDQueueStop([self queueRef]);
+    
+    IOHIDDeviceUnscheduleFromRunLoop([self hidDeviceRef], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+    IOHIDDeviceClose([self hidDeviceRef], kIOHIDOptionsTypeNone);
+}
+
+- (NSString *)identifierName
+{
+    NSString *idName = NULL;
+    if(idName == NULL) idName = [self productName];
+    if(idName == NULL) idName = [self manufacturerName];
+    if(idName == NULL) idName = [self serialNumber];
+    if(idName == NULL) idName = [NSString stringWithFormat:@"%d-%d", [self vendorID], [self productID]];
+    return idName;
+}
+
+- (NSString *)productName {
+    CFStringRef productName = (CFStringRef)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDProductKey));
+    if(productName == NULL || CFGetTypeID(productName) != CFStringGetTypeID()) {
+        return NULL;
+    }
+    return (NSString*)productName;
+}
+- (NSString *)manufacturerName {
+    CFStringRef manufacturerName = (CFStringRef)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDManufacturerKey));
+    if(manufacturerName == NULL || CFGetTypeID(manufacturerName) != CFStringGetTypeID()) {
+        return NULL;
+    }
+    return (NSString*)manufacturerName;
+}
+- (NSString *)serialNumber {
+    CFStringRef serialNumber = (CFStringRef)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDSerialNumberKey));
+    if(serialNumber == NULL || CFGetTypeID(serialNumber) != CFStringGetTypeID()) {
+        return NULL;
+    }
+    return (NSString*)serialNumber;
+}
+
+
+- (int)vendorID
+{
+    return IOHIDDeviceGetIntProperty([self rawDevice], CFSTR(kIOHIDVendorIDKey));
+}
+- (int)productID
+{
+    return IOHIDDeviceGetIntProperty([self rawDevice], CFSTR(kIOHIDProductIDKey));
+}
+
+
+- (NSUInteger)numberOfAxes
+{
+    return [[self axes] count];
+}
+- (NSUInteger)numberOfSticks
+{
+    return ([[self axes] count] / 2);
+}
+- (NSUInteger)numberOfButtons
+{
+    return [[self buttons] count];
+}
+- (NSUInteger)numberOfTriggerButtons
+{
+    return [[self triggerButtons] count];
+}
+
+- (OSXGamepadButton*)triggerButtonAtIndex:(NSUInteger)index
+{
+    OSXGamepadButton *b = NULL;
+    if(index < [[self triggerButtons] count])
+    {
+        b = [[self triggerButtons] objectAtIndex:index];
+    }
+    return b;
+}
+
+- (OSXGamepadAxis*)axisAtIndex:(NSUInteger)index
+{
+    OSXGamepadAxis *a = NULL;
+    if(index < [[self axes] count])
+    {
+        a = [[self axes] objectAtIndex:index];
+    }
+    return a;
+}
+- (OSXGamepadButton*)buttonAtIndex:(NSUInteger)index
+{
+    OSXGamepadButton *b = NULL;
+    if(index < [[self buttons] count])
+    {
+        b = [[self buttons] objectAtIndex:index];
+    }
+    return b;
+}
+- (NSArray*)watchedElements
+{
+    NSMutableArray *r = [NSMutableArray array];
+    for(OSXGamepadButton *b in [self buttons])
+    {
+        [r addObject:(id)[b element]];
+    }
+    for(OSXGamepadAxis *a in [self axes])
+    {
+        [r addObject:(id)[a element]];
+    }
+    return [NSArray arrayWithArray:r];
+}
+- (void)hidValueAvailable:(IOHIDValueRef)value
+{
+    IOHIDElementRef element = IOHIDValueGetElement(value);
+	IOHIDElementCookie cookie = IOHIDElementGetCookie(element);
+    
+    if(IOHIDValueGetLength(value) > 4) return; // saftey precaution for PS3 cotroller
+    CFIndex integerValue = IOHIDValueGetIntegerValue(value);
+    
+    for(OSXGamepadAxis *a in [self axes])
+    {
+        if([a cookie] == cookie)
+        {
+            [a setValue:integerValue];
+        }
+    }
+    
+    for(OSXGamepadButton *b in [self buttons])
+    {
+        if([b cookie] == cookie)
+        {
+            [b setState:(bool)integerValue];
+            break;
+        }
+    }
+    
+    for(OSXGamepadButton *b in [self triggerButtons])
+    {
+        if([b triggerCookie] == cookie)
+        {
+            [b setStateValue:integerValue];
+            break;
+        }
+    }
+
+}
+
+
+@end
+
 
 @interface View : NSOpenGLView <NSWindowDelegate>
 {
@@ -66,10 +629,8 @@ double getMachTimeInMilliseconds()
     Game* _game;
     unsigned int _gestureEvents;    
 }
-
 @end
 
-static View* __view = NULL;
 
 @implementation View
 
@@ -486,8 +1047,8 @@ int getKey(unsigned short keyCode, unsigned int modifierFlags)
             return Keyboard::KEY_F10;
         
         // MACOS reserved:
-        //return Keyboard::KEY_F11;
-        //return Keyboard::KEY_F12;
+        // return Keyboard::KEY_F11;
+        // return Keyboard::KEY_F12;
         // return Keyboard::KEY_PAUSE;
         // return Keyboard::KEY_SCROLL_LOCK;
             
@@ -680,25 +1241,6 @@ int getKey(unsigned short keyCode, unsigned int modifierFlags)
     [gameLock unlock];
 }
 
-- (void)swipeWithEvent:(NSEvent *)event
-{
-    if([self isGestureRegistered:Gesture::GESTURE_SWIPE] == false) return;
-    /**
-     * Gesture callback on Gesture::SWIPE events.
-     *
-     * @param x The x-coordinate of the start of the swipe.
-     * @param y The y-coordinate of the start of the swipe.
-     * @param direction The direction of the swipe
-     *
-     * @see Gesture::SWIPE_DIRECTION_UP
-     * @see Gesture::SWIPE_DIRECTION_DOWN
-     * @see Gesture::SWIPE_DIRECTION_LEFT
-     * @see Gesture::SWIPE_DIRECTION_RIGHT
-     */
-    //[gameLock lock];
-    //virtual void gestureSwipeEvent(int x, int y, int direction);
-    //[gameLock unlock];
-}
 
 @end
 
@@ -730,12 +1272,36 @@ extern void print(const char* format, ...)
 Platform::Platform(Game* game)
 : _game(game)
 {
+    __activeGamepads = [[NSMutableDictionary alloc] init];
+    __gamepads = [[NSMutableArray alloc] init];
+    __hidManagerRef = IOHIDManagerCreate(CFAllocatorGetDefault(), kIOHIDOptionsTypeNone);
+    IOHIDManagerRegisterDeviceMatchingCallback(__hidManagerRef, hidDeviceDiscoveredCallback, NULL);
+    IOHIDManagerRegisterDeviceRemovalCallback(__hidManagerRef, hidDeviceRemovalCallback, NULL);
+    
+    CFDictionaryRef matchingCFDictRef = IOHIDCreateDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
+    if (matchingCFDictRef) IOHIDManagerSetDeviceMatching(__hidManagerRef, matchingCFDictRef);
+    CFRelease(matchingCFDictRef);
+    
+    IOHIDManagerScheduleWithRunLoop(__hidManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+    IOReturn kr = IOHIDManagerOpen(__hidManagerRef, kIOHIDOptionsTypeNone);
+    assert(kr == 0);
 }
 
+    
 Platform::~Platform()
 {
+    IOHIDManagerUnscheduleFromRunLoop(__hidManagerRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+    IOHIDManagerClose(__hidManagerRef, kIOHIDOptionsTypeNone);
+    
+    CFRelease(__hidManagerRef);
+    __hidManagerRef = NULL;
+    [__activeGamepads release];
+    __activeGamepads = NULL;
+    [__gamepads release];
+    __gamepads = NULL;
 }
 
+    
 Platform* Platform::create(Game* game, void* attachToWindow)
 {
     __attachToWindow = attachToWindow;
@@ -999,7 +1565,11 @@ bool Platform::mouseEventInternal(Mouse::MouseEvent evt, int x, int y, int wheel
 
 bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 {
-    // TODO: Support Swipe and Tap
+    // Swipe unsupported as it is considered moving mouse cursor
+    // Two fingers is scrolling
+    // Three fingers is swipe, but is not always enabled on users system
+    // Tap not supported as it is considered a mouse click/button click
+    // on some systems making it difficult to differentiate 
     switch(evt)
     {
         case Gesture::GESTURE_PINCH:
@@ -1012,12 +1582,12 @@ bool Platform::isGestureSupported(Gesture::GestureEvent evt)
 
 void Platform::registerGesture(Gesture::GestureEvent evt)
 {
-    [__view registerGesture:evt];
+    [__view registerGesture:evt];   
 }
 
 void Platform::unregisterGesture(Gesture::GestureEvent evt)
 {
-    [__view unregisterGesture:evt];
+    [__view unregisterGesture:evt];        
 }
   
 bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
@@ -1027,63 +1597,283 @@ bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
 
 unsigned int Platform::getGamepadsConnected()
 {
-    return 0;
+    Game* game = Game::getInstance();
+    
+    if(game->isInitialized())
+    {
+        // Locate any newly connected devices
+        for(OSXGamepad* gamepad in __gamepads)
+        {
+            NSNumber* locationID = [gamepad locationID];
+            if([__activeGamepads objectForKey:locationID] == NULL)
+            {
+                unsigned int handle = game->createGamepad([[gamepad identifierName] cStringUsingEncoding:NSASCIIStringEncoding],
+                                                          [locationID unsignedIntValue],
+                                                          [gamepad numberOfButtons],
+                                                          [gamepad numberOfSticks],
+                                                          [gamepad numberOfTriggerButtons]);
+                NSNumber* handleObj = [NSNumber numberWithUnsignedInt:handle];
+                [__activeGamepads setObject:handleObj forKey:locationID];
+                game->gamepadEvent(Gamepad::CONNECTED_EVENT, game->getGamepad(handle));
+            }
+        }
+        
+        // Detect any disconnected gamepads
+        NSMutableArray* deadGamepads = [NSMutableArray array];
+        for(NSNumber* locationID in __activeGamepads)
+        {
+            OSXGamepad* gamepad = gamepadForLocationID(locationID);
+            if(gamepad == NULL)
+            {
+                NSNumber* gameHandle = [__activeGamepads objectForKey:locationID];
+                game->gamepadEvent(Gamepad::DISCONNECTED_EVENT, game->getGamepad([gameHandle unsignedIntValue]));
+                [deadGamepads addObject:locationID];
+            }
+        }
+        [__activeGamepads removeObjectsForKeys:deadGamepads];
+    }
+    return [__gamepads count];
 }
 
 bool Platform::isGamepadConnected(unsigned int gamepadHandle)
 {
-    return false;
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    return (gamepad != NULL);
 }
 
 const char* Platform::getGamepadId(unsigned int gamepadHandle)
 {
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    if(gamepad)
+    {
+        return [[gamepad productName] cStringUsingEncoding:NSASCIIStringEncoding];
+    }
     return NULL;
 }
 
 unsigned int Platform::getGamepadButtonCount(unsigned int gamepadHandle)
 {
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    if(gamepad)
+    {
+        return [gamepad numberOfButtons];
+    }
     return 0;
 }
 
 bool Platform::getGamepadButtonState(unsigned int gamepadHandle, unsigned int buttonIndex)
 {
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    OSXGamepadButton* button = [gamepad buttonAtIndex:buttonIndex];
+    if(button)
+    {
+        return [button state];
+    }
     return false;
 }
 
 unsigned int Platform::getGamepadJoystickCount(unsigned int gamepadHandle)
 {
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    if(gamepad)
+    {
+        return [gamepad numberOfSticks];
+    }
     return 0;
 }
 
 bool Platform::isGamepadJoystickActive(unsigned int gamepadHandle, unsigned int joystickIndex)
 {
-    return false;
+    return true;
 }
 
 float Platform::getGamepadJoystickAxisX(unsigned int gamepadHandle, unsigned int joystickIndex)
 {
-    return 0.0f;
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    OSXGamepadAxis* xAxis = [gamepad axisAtIndex:(joystickIndex*2)];
+    return [xAxis calibratedValue];
 }
 
 float Platform::getGamepadJoystickAxisY(unsigned int gamepadHandle, unsigned int joystickIndex)
 {
-    return 0.0f;
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    OSXGamepadAxis* yAxis = [gamepad axisAtIndex:((joystickIndex*2)+1)];
+    return [yAxis calibratedValue];
 }
 
 void Platform::getGamepadJoystickAxisValues(unsigned int gamepadHandle, unsigned int joystickIndex, Vector2* outValue)
 {
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    OSXGamepadAxis* xAxis = [gamepad axisAtIndex:(joystickIndex*2)];
+    OSXGamepadAxis* yAxis = [gamepad axisAtIndex:((joystickIndex*2)+1)];
+    if(outValue)
+    {
+        outValue->x = [xAxis calibratedValue];
+        outValue->y = [yAxis calibratedValue];
+    }
 }
 
 unsigned int Platform::getGamepadTriggerCount(unsigned int gamepadHandle)
 {
-    return 0;
+    OSXGamepad *gamepad = gamepadForLocationIDValue(gamepadHandle);
+    return [gamepad numberOfTriggerButtons];
 }
 
 float Platform::getGamepadTriggerValue(unsigned int gamepadHandle, unsigned int triggerIndex)
 {
+    OSXGamepad* gamepad = gamepadForLocationIDValue(gamepadHandle);
+    OSXGamepadButton* button = [gamepad triggerButtonAtIndex:triggerIndex];
+    if(button)
+    {
+        return [button stateValue];
+    }
     return 0.0f;
 }
 
 }
 
+
+OSXGamepad* gamepadForLocationID(NSNumber* locationID)
+{
+    OSXGamepad* fgamepad = NULL;
+    for(OSXGamepad* gamepad in __gamepads)
+    {
+        if([[gamepad locationID] isEqual:locationID])
+        {
+            fgamepad = gamepad;
+            break;
+        }
+    }
+    return fgamepad;
+}
+
+OSXGamepad* gamepadForLocationIDValue(unsigned int locationIDValue)
+{
+    return gamepadForLocationID([NSNumber numberWithUnsignedInt:locationIDValue]);
+}
+
+OSXGamepad* gamepadForGameHandle(int gameHandle)
+{
+    OSXGamepad* gamepad = NULL;
+    for(NSNumber* locationID in __activeGamepads)
+    {
+        NSNumber* handleID = [__activeGamepads objectForKey:locationID];
+        if([handleID integerValue] == gameHandle)
+        {
+            gamepad = gamepadForLocationID(locationID);
+            break;
+        }
+    }
+    return gamepad;
+}
+
+CFMutableDictionaryRef IOHIDCreateDeviceMatchingDictionary(UInt32 inUsagePage, UInt32 inUsage) 
+{
+    // create a dictionary to add usage page/usages to
+    CFMutableDictionaryRef result = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    if (result) {
+        if (inUsagePage) 
+        {
+            // Add key for device type to refine the matching dictionary.
+            CFNumberRef pageCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &inUsagePage);
+            if (pageCFNumberRef) 
+            {
+                CFDictionarySetValue(result, CFSTR( kIOHIDDeviceUsagePageKey ), pageCFNumberRef);
+                CFRelease(pageCFNumberRef);
+                
+                // note: the usage is only valid if the usage page is also defined
+                if (inUsage) 
+                {
+                    CFNumberRef usageCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &inUsage);
+                    if (usageCFNumberRef) 
+                    {
+                        CFDictionarySetValue(result, CFSTR(kIOHIDDeviceUsageKey), usageCFNumberRef);
+                        CFRelease(usageCFNumberRef);
+                    } 
+                    else 
+                    {
+                        fprintf(stderr, "%s: CFNumberCreate( usage ) failed.", __PRETTY_FUNCTION__);
+                    }
+                }
+            } 
+            else 
+            {
+                fprintf( stderr, "%s: CFNumberCreate( usage page ) failed.", __PRETTY_FUNCTION__);
+            }
+        }
+    } 
+    else 
+    {
+        fprintf( stderr, "%s: CFDictionaryCreateMutable failed.", __PRETTY_FUNCTION__);
+    }
+    return result;
+}
+
+CFStringRef IOHIDDeviceGetStringProperty(IOHIDDeviceRef deviceRef, CFStringRef key) 
+{
+	CFTypeRef typeRef = IOHIDDeviceGetProperty(deviceRef, key);
+	if (typeRef == NULL || CFGetTypeID(typeRef) != CFNumberGetTypeID()) 
+    {
+		return NULL;
+	}
+    return (CFStringRef)typeRef;
+}
+
+int IOHIDDeviceGetIntProperty(IOHIDDeviceRef deviceRef, CFStringRef key) 
+{
+	CFTypeRef typeRef = IOHIDDeviceGetProperty(deviceRef, key);
+	if (typeRef == NULL || CFGetTypeID(typeRef) != CFNumberGetTypeID()) 
+    {
+		return 0;
+	}
+    
+    int value;
+	CFNumberGetValue((CFNumberRef) typeRef, kCFNumberSInt32Type, &value);
+	return value;
+}
+
+static void hidDeviceDiscoveredCallback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inIOHIDDeviceRef) 
+{
+    CFNumberRef locID = (CFNumberRef)IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDLocationIDKey));
+    if(locID)
+    {
+        OSXGamepad* gamepad = [[OSXGamepad alloc] initWithDevice:inIOHIDDeviceRef];
+        [__gamepads addObject:gamepad];
+    }
+    
+}
+
+static void hidDeviceRemovalCallback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inIOHIDDeviceRef) 
+{
+    int removeIndex = -1;
+    NSNumber *locID = (NSNumber*)IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDLocationIDKey));
+    if(locID)
+    {
+        for(int i = 0; i < [__gamepads count]; i++)
+        {
+            OSXGamepad* gamepad = [__gamepads objectAtIndex:i];
+            if([[gamepad locationID] isEqual:locID])
+            {
+                removeIndex = i;
+                break;
+            }
+        }
+    }
+    if(removeIndex >= 0)
+    {
+        [__gamepads removeObjectAtIndex:removeIndex];
+    }
+}
+
+static void hidDeviceValueAvailableCallback(void* inContext, IOReturn inResult,  void* inSender)
+{
+    OSXGamepad* d = (OSXGamepad*)inContext;
+    do
+    {
+        IOHIDValueRef valueRef = IOHIDQueueCopyNextValueWithTimeout( ( IOHIDQueueRef ) inSender, 0. );
+        if (!valueRef) break;
+        [d hidValueAvailable:valueRef];
+        CFRelease(valueRef); // Don't forget to release our HID value reference
+    } while (1);
+}
 #endif

+ 11 - 11
gameplay/src/TextBox.cpp

@@ -4,7 +4,7 @@
 namespace gameplay
 {
 
-TextBox::TextBox() : _textIndex(0), _lastKeypress(0), _fontSize(0), _caretImage(NULL)
+TextBox::TextBox() : _lastKeypress(0), _fontSize(0), _caretImage(NULL)
 {
 }
 
@@ -250,11 +250,11 @@ bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                 {
                     case Keyboard::KEY_BACKSPACE:
                     {
-                        if (_textIndex > 0)
+                        if (textIndex > 0)
                         {
-                            --_textIndex;
-                            _text.erase(_textIndex, 1);
-                            font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, _textIndex,
+                            --textIndex;
+                            _text.erase(textIndex, 1);
+                            font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                                 textAlignment, true, rightToLeft);
 
                             _dirty = true;
@@ -272,11 +272,11 @@ bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                     default:
                     {
                         // Insert character into string.
-                        _text.insert(_textIndex, 1, (char)key);
+                        _text.insert(textIndex, 1, (char)key);
                         consume = true;
 
                         // Get new location of caret.
-                        font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, _textIndex + 1,
+                        font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex + 1,
                             textAlignment, true, rightToLeft);
 
                         if (key == ' ')
@@ -286,8 +286,8 @@ bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                                 _caretLocation.y >= _textBounds.y + _textBounds.height)
                             {
                                 // If not, undo the character insertion.
-                                _text.erase(_textIndex, 1);
-                                font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, _textIndex,
+                                _text.erase(textIndex, 1);
+                                font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                                     textAlignment, true, rightToLeft);
 
                                 // No need to check again.
@@ -302,8 +302,8 @@ bool TextBox::keyEvent(Keyboard::KeyEvent evt, int key)
                             textBounds.width >= _textBounds.width || textBounds.height >= _textBounds.height)
                         {
                             // If not, undo the character insertion.
-                            _text.erase(_textIndex, 1);
-                            font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, _textIndex,
+                            _text.erase(textIndex, 1);
+                            font->getLocationAtIndex(_text.c_str(), _textBounds, fontSize, &_caretLocation, textIndex,
                                 textAlignment, true, rightToLeft);
 
                             // TextBox is not dirty.

+ 0 - 5
gameplay/src/TextBox.h

@@ -148,11 +148,6 @@ protected:
      * The previous position of the TextBox's caret.
      */
     Vector2 _prevCaretLocation;
-
-    /**
-     * The index into the TextBox's string that the caret is.
-     */
-    unsigned int _textIndex;
     
     /**
      * The last character that was entered into the TextBox.