Browse Source

Fixed OS X and iOS platforms for Leap integration.

MichPerry-GG 11 years ago
parent
commit
ac921c6080

+ 82 - 12
engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj

@@ -48,6 +48,10 @@
 		8609FE361655716E004662ED /* osxPopupMenu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8609FE351655716E004662ED /* osxPopupMenu.mm */; };
 		8609FE361655716E004662ED /* osxPopupMenu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8609FE351655716E004662ED /* osxPopupMenu.mm */; };
 		8609FE38165572EC004662ED /* osxFont.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8609FE37165572EC004662ED /* osxFont.mm */; };
 		8609FE38165572EC004662ED /* osxFont.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8609FE37165572EC004662ED /* osxFont.mm */; };
 		861CD8D01678F6C200DAE1A0 /* fileDialog.cc in Sources */ = {isa = PBXBuildFile; fileRef = 861CD8CF1678F6C200DAE1A0 /* fileDialog.cc */; };
 		861CD8D01678F6C200DAE1A0 /* fileDialog.cc in Sources */ = {isa = PBXBuildFile; fileRef = 861CD8CF1678F6C200DAE1A0 /* fileDialog.cc */; };
+		862BBACD18872BB400E3233A /* libLeap.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 867492F4188727FF00CF0136 /* libLeap.dylib */; };
+		8645C96C1887231C004ED987 /* mPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8645C96B1887231C004ED987 /* mPoint.cpp */; };
+		8645C97418872339004ED987 /* leapMotionManager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8645C96F18872339004ED987 /* leapMotionManager.cc */; };
+		8645C97518872339004ED987 /* leapMotionUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8645C97218872339004ED987 /* leapMotionUtil.cpp */; };
 		8652C279165586520052D0CB /* osxAudio.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8652C278165586520052D0CB /* osxAudio.mm */; };
 		8652C279165586520052D0CB /* osxAudio.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8652C278165586520052D0CB /* osxAudio.mm */; };
 		8652F2A016C146CF00639EFE /* torque2d.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8652F29F16C146CF00639EFE /* torque2d.icns */; };
 		8652F2A016C146CF00639EFE /* torque2d.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8652F29F16C146CF00639EFE /* torque2d.icns */; };
 		8658B174165A7BFB0087ABC1 /* osxCPU.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8658B171165A7BFB0087ABC1 /* osxCPU.mm */; };
 		8658B174165A7BFB0087ABC1 /* osxCPU.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8658B171165A7BFB0087ABC1 /* osxCPU.mm */; };
@@ -176,6 +180,7 @@
 		866381DC165556AD00C8C551 /* osxMath.mm in Sources */ = {isa = PBXBuildFile; fileRef = 866381DB165556AD00C8C551 /* osxMath.mm */; };
 		866381DC165556AD00C8C551 /* osxMath.mm in Sources */ = {isa = PBXBuildFile; fileRef = 866381DB165556AD00C8C551 /* osxMath.mm */; };
 		866381E51655615200C8C551 /* osxInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 866381E41655615200C8C551 /* osxInput.mm */; };
 		866381E51655615200C8C551 /* osxInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 866381E41655615200C8C551 /* osxInput.mm */; };
 		866381E91655674B00C8C551 /* osxTime.mm in Sources */ = {isa = PBXBuildFile; fileRef = 866381E81655674B00C8C551 /* osxTime.mm */; };
 		866381E91655674B00C8C551 /* osxTime.mm in Sources */ = {isa = PBXBuildFile; fileRef = 866381E81655674B00C8C551 /* osxTime.mm */; };
+		867492F5188727FF00CF0136 /* libLeap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 867492F4188727FF00CF0136 /* libLeap.dylib */; };
 		86854E341663AAE6009FAFB2 /* osxOpenGLDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86854E331663AAE6009FAFB2 /* osxOpenGLDevice.mm */; };
 		86854E341663AAE6009FAFB2 /* osxOpenGLDevice.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86854E331663AAE6009FAFB2 /* osxOpenGLDevice.mm */; };
 		8694ADC81656B06B0080ABAC /* osxEvents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8694ADC51656B06B0080ABAC /* osxEvents.mm */; };
 		8694ADC81656B06B0080ABAC /* osxEvents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8694ADC51656B06B0080ABAC /* osxEvents.mm */; };
 		8694ADC91656B06B0080ABAC /* osxWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8694ADC61656B06B0080ABAC /* osxWindow.mm */; };
 		8694ADC91656B06B0080ABAC /* osxWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8694ADC61656B06B0080ABAC /* osxWindow.mm */; };
@@ -453,6 +458,19 @@
 		B350D172174EF91900033EBB /* audio_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D171174EF91900033EBB /* audio_ScriptBinding.cc */; };
 		B350D172174EF91900033EBB /* audio_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D171174EF91900033EBB /* audio_ScriptBinding.cc */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
+/* Begin PBXCopyFilesBuildPhase section */
+		8645C978188723B7004ED987 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 6;
+			files = (
+				862BBACD18872BB400E3233A /* libLeap.dylib in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
 		04CC626B1795512500F9C119 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = ../../../../../../../System/Library/Frameworks/AVFoundation.framework; sourceTree = "<group>"; };
 		04CC626B1795512500F9C119 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = ../../../../../../../System/Library/Frameworks/AVFoundation.framework; sourceTree = "<group>"; };
 		2797C9E117F4E12500625B51 /* eaxtypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eaxtypes.h; sourceTree = "<group>"; };
 		2797C9E117F4E12500625B51 /* eaxtypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = eaxtypes.h; sourceTree = "<group>"; };
@@ -564,6 +582,13 @@
 		8609FE37165572EC004662ED /* osxFont.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 1; path = osxFont.mm; sourceTree = "<group>"; };
 		8609FE37165572EC004662ED /* osxFont.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 1; path = osxFont.mm; sourceTree = "<group>"; };
 		861CD8CE1678F6C200DAE1A0 /* fileDialog_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fileDialog_ScriptBinding.h; sourceTree = "<group>"; };
 		861CD8CE1678F6C200DAE1A0 /* fileDialog_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fileDialog_ScriptBinding.h; sourceTree = "<group>"; };
 		861CD8CF1678F6C200DAE1A0 /* fileDialog.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fileDialog.cc; sourceTree = "<group>"; };
 		861CD8CF1678F6C200DAE1A0 /* fileDialog.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fileDialog.cc; sourceTree = "<group>"; };
+		8645C96B1887231C004ED987 /* mPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mPoint.cpp; sourceTree = "<group>"; };
+		8645C96E18872339004ED987 /* leapMotionConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = leapMotionConstants.h; sourceTree = "<group>"; };
+		8645C96F18872339004ED987 /* leapMotionManager.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = leapMotionManager.cc; sourceTree = "<group>"; };
+		8645C97018872339004ED987 /* leapMotionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = leapMotionManager.h; sourceTree = "<group>"; };
+		8645C97118872339004ED987 /* LeapMotionManager_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LeapMotionManager_ScriptBinding.h; sourceTree = "<group>"; };
+		8645C97218872339004ED987 /* leapMotionUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = leapMotionUtil.cpp; sourceTree = "<group>"; };
+		8645C97318872339004ED987 /* leapMotionUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = leapMotionUtil.h; sourceTree = "<group>"; };
 		864ECFEA1652795700012416 /* platform_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_ScriptBinding.h; sourceTree = "<group>"; };
 		864ECFEA1652795700012416 /* platform_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platform_ScriptBinding.h; sourceTree = "<group>"; };
 		864ECFED165279E100012416 /* networkProcessList.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = networkProcessList.cc; sourceTree = "<group>"; };
 		864ECFED165279E100012416 /* networkProcessList.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = networkProcessList.cc; sourceTree = "<group>"; };
 		864ECFEE165279E100012416 /* networkProcessList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = networkProcessList.h; sourceTree = "<group>"; };
 		864ECFEE165279E100012416 /* networkProcessList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = networkProcessList.h; sourceTree = "<group>"; };
@@ -744,6 +769,7 @@
 		866381DB165556AD00C8C551 /* osxMath.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxMath.mm; sourceTree = "<group>"; };
 		866381DB165556AD00C8C551 /* osxMath.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxMath.mm; sourceTree = "<group>"; };
 		866381E41655615200C8C551 /* osxInput.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxInput.mm; sourceTree = "<group>"; };
 		866381E41655615200C8C551 /* osxInput.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxInput.mm; sourceTree = "<group>"; };
 		866381E81655674B00C8C551 /* osxTime.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxTime.mm; sourceTree = "<group>"; };
 		866381E81655674B00C8C551 /* osxTime.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxTime.mm; sourceTree = "<group>"; };
+		867492F4188727FF00CF0136 /* libLeap.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libLeap.dylib; path = "../../lib/LeapSDK/lib/libc++/libLeap.dylib"; sourceTree = "<group>"; };
 		86854E321663AAE6009FAFB2 /* osxOpenGLDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osxOpenGLDevice.h; sourceTree = "<group>"; };
 		86854E321663AAE6009FAFB2 /* osxOpenGLDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osxOpenGLDevice.h; sourceTree = "<group>"; };
 		86854E331663AAE6009FAFB2 /* osxOpenGLDevice.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxOpenGLDevice.mm; sourceTree = "<group>"; };
 		86854E331663AAE6009FAFB2 /* osxOpenGLDevice.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxOpenGLDevice.mm; sourceTree = "<group>"; };
 		8694ADC41656B06B0080ABAC /* osxEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osxEvents.h; sourceTree = "<group>"; };
 		8694ADC41656B06B0080ABAC /* osxEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osxEvents.h; sourceTree = "<group>"; };
@@ -1437,6 +1463,7 @@
 			isa = PBXFrameworksBuildPhase;
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				867492F5188727FF00CF0136 /* libLeap.dylib in Frameworks */,
 				865A20CA16515B1E00527C44 /* AppKit.framework in Frameworks */,
 				865A20CA16515B1E00527C44 /* AppKit.framework in Frameworks */,
 				865A20CC16515B1E00527C44 /* Cocoa.framework in Frameworks */,
 				865A20CC16515B1E00527C44 /* Cocoa.framework in Frameworks */,
 				865A20CD16515B1E00527C44 /* CoreData.framework in Frameworks */,
 				865A20CD16515B1E00527C44 /* CoreData.framework in Frameworks */,
@@ -1586,6 +1613,19 @@
 			name = composites;
 			name = composites;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		8645C96D18872339004ED987 /* leapMotion */ = {
+			isa = PBXGroup;
+			children = (
+				8645C96E18872339004ED987 /* leapMotionConstants.h */,
+				8645C96F18872339004ED987 /* leapMotionManager.cc */,
+				8645C97018872339004ED987 /* leapMotionManager.h */,
+				8645C97118872339004ED987 /* LeapMotionManager_ScriptBinding.h */,
+				8645C97218872339004ED987 /* leapMotionUtil.cpp */,
+				8645C97318872339004ED987 /* leapMotionUtil.h */,
+			);
+			path = leapMotion;
+			sourceTree = "<group>";
+		};
 		865A20BD1651589F00527C44 /* Resources */ = {
 		865A20BD1651589F00527C44 /* Resources */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -1924,6 +1964,7 @@
 		869FF8BB1651518C002FE082 /* Frameworks */ = {
 		869FF8BB1651518C002FE082 /* Frameworks */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				867492F4188727FF00CF0136 /* libLeap.dylib */,
 				865A20C916515AEF00527C44 /* System */,
 				865A20C916515AEF00527C44 /* System */,
 				869FF8BE1651518C002FE082 /* Other Frameworks */,
 				869FF8BE1651518C002FE082 /* Other Frameworks */,
 			);
 			);
@@ -2600,6 +2641,7 @@
 		86BC805816518D4600D96ADF /* input */ = {
 		86BC805816518D4600D96ADF /* input */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				8645C96D18872339004ED987 /* leapMotion */,
 				B350D153174EF5F200033EBB /* actionMap_ScriptBinding.h */,
 				B350D153174EF5F200033EBB /* actionMap_ScriptBinding.h */,
 				86BC805916518D4600D96ADF /* actionMap.cc */,
 				86BC805916518D4600D96ADF /* actionMap.cc */,
 				86BC805A16518D4600D96ADF /* actionMap.h */,
 				86BC805A16518D4600D96ADF /* actionMap.h */,
@@ -2685,6 +2727,7 @@
 		86BC809116518D4600D96ADF /* math */ = {
 		86BC809116518D4600D96ADF /* math */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				8645C96B1887231C004ED987 /* mPoint.cpp */,
 				B350D12B174ED1FE00033EBB /* box_ScriptBinding.h */,
 				B350D12B174ED1FE00033EBB /* box_ScriptBinding.h */,
 				B350D12C174ED1FE00033EBB /* math_ScriptBinding.cc */,
 				B350D12C174ED1FE00033EBB /* math_ScriptBinding.cc */,
 				B350D12D174ED1FE00033EBB /* matrix_ScriptBinding.h */,
 				B350D12D174ED1FE00033EBB /* matrix_ScriptBinding.h */,
@@ -3036,6 +3079,7 @@
 				869FF8B61651518C002FE082 /* Resources */,
 				869FF8B61651518C002FE082 /* Resources */,
 				869FF8B41651518C002FE082 /* Sources */,
 				869FF8B41651518C002FE082 /* Sources */,
 				869FF8B51651518C002FE082 /* Frameworks */,
 				869FF8B51651518C002FE082 /* Frameworks */,
+				8645C978188723B7004ED987 /* CopyFiles */,
 			);
 			);
 			buildRules = (
 			buildRules = (
 			);
 			);
@@ -3189,6 +3233,7 @@
 				86D77052165687220046D71F /* zipArchive.cc in Sources */,
 				86D77052165687220046D71F /* zipArchive.cc in Sources */,
 				86D77053165687220046D71F /* zipCryptStream.cc in Sources */,
 				86D77053165687220046D71F /* zipCryptStream.cc in Sources */,
 				86D77054165687220046D71F /* zipObject.cc in Sources */,
 				86D77054165687220046D71F /* zipObject.cc in Sources */,
+				8645C97418872339004ED987 /* leapMotionManager.cc in Sources */,
 				86D77055165687220046D71F /* zipSubStream.cc in Sources */,
 				86D77055165687220046D71F /* zipSubStream.cc in Sources */,
 				86D77056165687220046D71F /* zipTempStream.cc in Sources */,
 				86D77056165687220046D71F /* zipTempStream.cc in Sources */,
 				86D76FAF165687060046D71F /* crc.cc in Sources */,
 				86D76FAF165687060046D71F /* crc.cc in Sources */,
@@ -3281,6 +3326,7 @@
 				86D77022165687060046D71F /* guiColorPicker.cc in Sources */,
 				86D77022165687060046D71F /* guiColorPicker.cc in Sources */,
 				86D77023165687060046D71F /* guiConsole.cc in Sources */,
 				86D77023165687060046D71F /* guiConsole.cc in Sources */,
 				86D77024165687060046D71F /* guiConsoleEditCtrl.cc in Sources */,
 				86D77024165687060046D71F /* guiConsoleEditCtrl.cc in Sources */,
+				8645C97518872339004ED987 /* leapMotionUtil.cpp in Sources */,
 				86D77025165687060046D71F /* guiConsoleTextCtrl.cc in Sources */,
 				86D77025165687060046D71F /* guiConsoleTextCtrl.cc in Sources */,
 				86D77026165687060046D71F /* guiControl.cc in Sources */,
 				86D77026165687060046D71F /* guiControl.cc in Sources */,
 				86D77027165687060046D71F /* guiDefaultControlRender.cc in Sources */,
 				86D77027165687060046D71F /* guiDefaultControlRender.cc in Sources */,
@@ -3371,6 +3417,7 @@
 				865A228E165187B600527C44 /* b2ContactManager.cpp in Sources */,
 				865A228E165187B600527C44 /* b2ContactManager.cpp in Sources */,
 				865A228F165187B600527C44 /* b2Fixture.cpp in Sources */,
 				865A228F165187B600527C44 /* b2Fixture.cpp in Sources */,
 				865A2290165187B600527C44 /* b2Island.cpp in Sources */,
 				865A2290165187B600527C44 /* b2Island.cpp in Sources */,
+				8645C96C1887231C004ED987 /* mPoint.cpp in Sources */,
 				865A2291165187B600527C44 /* b2World.cpp in Sources */,
 				865A2291165187B600527C44 /* b2World.cpp in Sources */,
 				865A2292165187B600527C44 /* b2WorldCallbacks.cpp in Sources */,
 				865A2292165187B600527C44 /* b2WorldCallbacks.cpp in Sources */,
 				865A2293165187B600527C44 /* b2ChainAndCircleContact.cpp in Sources */,
 				865A2293165187B600527C44 /* b2ChainAndCircleContact.cpp in Sources */,
@@ -3572,7 +3619,7 @@
 		865A20AF165152EA00527C44 /* Shipping */ = {
 		865A20AF165152EA00527C44 /* Shipping */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_CXX_LIBRARY = "libc++";
 				COMBINE_HIDPI_IMAGES = YES;
 				COMBINE_HIDPI_IMAGES = YES;
 				CONFIGURATION_BUILD_DIR = ../../..;
 				CONFIGURATION_BUILD_DIR = ../../..;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
@@ -3592,13 +3639,16 @@
 					../../source/persistence/rapidjson/include,
 					../../source/persistence/rapidjson/include,
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/QD.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/QD.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/OpenGL.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/OpenGL.framework/Headers",
+					../../lib/LeapSDK/include,
 				);
 				);
 				INFOPLIST_FILE = "Torque2D/Torque2D-Info.plist";
 				INFOPLIST_FILE = "Torque2D/Torque2D-Info.plist";
-				LIBRARY_SEARCH_PATHS = "$(inherited)";
-				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"../../lib/LeapSDK/lib/libc++",
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				OTHER_LDFLAGS = /usr/lib/libz.dylib;
 				OTHER_LDFLAGS = /usr/lib/libz.dylib;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				VALID_ARCHS = i386;
 				WRAPPER_EXTENSION = app;
 				WRAPPER_EXTENSION = app;
 			};
 			};
 			name = Shipping;
 			name = Shipping;
@@ -3673,7 +3723,7 @@
 		869FF8D71651518C002FE082 /* Debug */ = {
 		869FF8D71651518C002FE082 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_CXX_LIBRARY = "libc++";
 				COMBINE_HIDPI_IMAGES = YES;
 				COMBINE_HIDPI_IMAGES = YES;
 				CONFIGURATION_BUILD_DIR = ../../..;
 				CONFIGURATION_BUILD_DIR = ../../..;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
@@ -3695,13 +3745,16 @@
 					../../source/testing/googleTest/include,
 					../../source/testing/googleTest/include,
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/QD.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/QD.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/OpenGL.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/OpenGL.framework/Headers",
+					../../lib/LeapSDK/include,
 				);
 				);
 				INFOPLIST_FILE = "Torque2D/Torque2D-Info.plist";
 				INFOPLIST_FILE = "Torque2D/Torque2D-Info.plist";
-				LIBRARY_SEARCH_PATHS = "$(inherited)";
-				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"../../lib/LeapSDK/lib/libc++",
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				OTHER_LDFLAGS = /usr/lib/libz.dylib;
 				OTHER_LDFLAGS = /usr/lib/libz.dylib;
 				PRODUCT_NAME = "$(TARGET_NAME)_DEBUG";
 				PRODUCT_NAME = "$(TARGET_NAME)_DEBUG";
-				VALID_ARCHS = i386;
 				WRAPPER_EXTENSION = app;
 				WRAPPER_EXTENSION = app;
 			};
 			};
 			name = Debug;
 			name = Debug;
@@ -3709,7 +3762,7 @@
 		869FF8D81651518C002FE082 /* Release */ = {
 		869FF8D81651518C002FE082 /* Release */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				CLANG_CXX_LIBRARY = "libc++";
 				COMBINE_HIDPI_IMAGES = YES;
 				COMBINE_HIDPI_IMAGES = YES;
 				CONFIGURATION_BUILD_DIR = ../../..;
 				CONFIGURATION_BUILD_DIR = ../../..;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
@@ -3732,13 +3785,30 @@
 					../../source/testing/googleTest/include,
 					../../source/testing/googleTest/include,
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/QD.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/QD.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/OpenGL.framework/Headers",
 					"$(SYSTEM_LIBRARY_DIR)/Frameworks/OpenGL.framework/Headers",
+					../../lib/LeapSDK/include,
+				);
+				"HEADER_SEARCH_PATHS[arch=*]" = (
+					../../source,
+					../../lib,
+					../../lib/vorbis/include,
+					../../lib/lpng,
+					../../lib/ljpeg,
+					../../lib/lungif,
+					../../source/persistence/rapidjson/include,
+					../../source/testing/googleTest,
+					../../source/testing/googleTest/include,
+					"$(SYSTEM_LIBRARY_DIR)/Frameworks/ApplicationServices.framework/Versions/Current/Frameworks/QD.framework/Headers",
+					"$(SYSTEM_LIBRARY_DIR)/Frameworks/OpenGL.framework/Headers",
+					../../lib/LeapSDK/include,
 				);
 				);
 				INFOPLIST_FILE = "Torque2D/Torque2D-Info.plist";
 				INFOPLIST_FILE = "Torque2D/Torque2D-Info.plist";
-				LIBRARY_SEARCH_PATHS = "$(inherited)";
-				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				LIBRARY_SEARCH_PATHS = (
+					"$(inherited)",
+					"../../lib/LeapSDK/lib/libc++",
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.7;
 				OTHER_LDFLAGS = /usr/lib/libz.dylib;
 				OTHER_LDFLAGS = /usr/lib/libz.dylib;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PRODUCT_NAME = "$(TARGET_NAME)";
-				VALID_ARCHS = i386;
 				WRAPPER_EXTENSION = app;
 				WRAPPER_EXTENSION = app;
 			};
 			};
 			name = Release;
 			name = Release;

+ 4 - 0
engine/compilers/Xcode_iOS/Torque2D.xcodeproj/project.pbxproj

@@ -453,6 +453,7 @@
 		867BB28116AECA110033868F /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 867BB25316AECA110033868F /* jquant2.c */; };
 		867BB28116AECA110033868F /* jquant2.c in Sources */ = {isa = PBXBuildFile; fileRef = 867BB25316AECA110033868F /* jquant2.c */; };
 		867BB28216AECA110033868F /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 867BB25416AECA110033868F /* jutils.c */; };
 		867BB28216AECA110033868F /* jutils.c in Sources */ = {isa = PBXBuildFile; fileRef = 867BB25416AECA110033868F /* jutils.c */; };
 		867BB44416AED2850033868F /* iOSGL2ES.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BB44316AED2840033868F /* iOSGL2ES.mm */; };
 		867BB44416AED2850033868F /* iOSGL2ES.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BB44316AED2840033868F /* iOSGL2ES.mm */; };
+		8698388618872BF500D370A0 /* mPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8698388518872BF500D370A0 /* mPoint.cpp */; };
 		869A879216C15A3A00AE96AE /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 869A879116C15A3A00AE96AE /* Default-Portrait~ipad.png */; };
 		869A879216C15A3A00AE96AE /* Default-Portrait~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 869A879116C15A3A00AE96AE /* Default-Portrait~ipad.png */; };
 		869A879416C15A4300AE96AE /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 869A879316C15A4300AE96AE /* Default-Portrait@2x~ipad.png */; };
 		869A879416C15A4300AE96AE /* Default-Portrait@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 869A879316C15A4300AE96AE /* Default-Portrait@2x~ipad.png */; };
 		869A879616C15A4900AE96AE /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 869A879516C15A4900AE96AE /* Default-Landscape~ipad.png */; };
 		869A879616C15A4900AE96AE /* Default-Landscape~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 869A879516C15A4900AE96AE /* Default-Landscape~ipad.png */; };
@@ -1413,6 +1414,7 @@
 		867BB25416AECA110033868F /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../../lib/ljpeg/jutils.c; sourceTree = "<group>"; };
 		867BB25416AECA110033868F /* jutils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jutils.c; path = ../../lib/ljpeg/jutils.c; sourceTree = "<group>"; };
 		867BB44216AED2840033868F /* iOSGL2ES.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSGL2ES.h; sourceTree = "<group>"; };
 		867BB44216AED2840033868F /* iOSGL2ES.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSGL2ES.h; sourceTree = "<group>"; };
 		867BB44316AED2840033868F /* iOSGL2ES.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSGL2ES.mm; sourceTree = "<group>"; };
 		867BB44316AED2840033868F /* iOSGL2ES.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSGL2ES.mm; sourceTree = "<group>"; };
+		8698388518872BF500D370A0 /* mPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mPoint.cpp; sourceTree = "<group>"; };
 		869A879116C15A3A00AE96AE /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; };
 		869A879116C15A3A00AE96AE /* Default-Portrait~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait~ipad.png"; sourceTree = "<group>"; };
 		869A879316C15A4300AE96AE /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = "<group>"; };
 		869A879316C15A4300AE96AE /* Default-Portrait@2x~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait@2x~ipad.png"; sourceTree = "<group>"; };
 		869A879516C15A4900AE96AE /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; };
 		869A879516C15A4900AE96AE /* Default-Landscape~ipad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape~ipad.png"; sourceTree = "<group>"; };
@@ -2433,6 +2435,7 @@
 		867BAEF316AEC9050033868F /* math */ = {
 		867BAEF316AEC9050033868F /* math */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				8698388518872BF500D370A0 /* mPoint.cpp */,
 				B350D19E174F063200033EBB /* box_ScriptBinding.h */,
 				B350D19E174F063200033EBB /* box_ScriptBinding.h */,
 				B350D19F174F063200033EBB /* math_ScriptBinding.cc */,
 				B350D19F174F063200033EBB /* math_ScriptBinding.cc */,
 				B350D1A0174F063200033EBB /* matrix_ScriptBinding.h */,
 				B350D1A0174F063200033EBB /* matrix_ScriptBinding.h */,
@@ -3424,6 +3427,7 @@
 				867BB0A516AEC9050033868F /* resourceDictionary.cc in Sources */,
 				867BB0A516AEC9050033868F /* resourceDictionary.cc in Sources */,
 				867BB0A616AEC9050033868F /* resourceManager.cc in Sources */,
 				867BB0A616AEC9050033868F /* resourceManager.cc in Sources */,
 				867BB0A716AEC9050033868F /* streamObject.cc in Sources */,
 				867BB0A716AEC9050033868F /* streamObject.cc in Sources */,
+				8698388618872BF500D370A0 /* mPoint.cpp in Sources */,
 				867BB0A816AEC9050033868F /* centralDir.cc in Sources */,
 				867BB0A816AEC9050033868F /* centralDir.cc in Sources */,
 				867BB0A916AEC9050033868F /* compressor.cc in Sources */,
 				867BB0A916AEC9050033868F /* compressor.cc in Sources */,
 				867BB0AA16AEC9050033868F /* deflate.cc in Sources */,
 				867BB0AA16AEC9050033868F /* deflate.cc in Sources */,

BIN
engine/lib/LeapSDK/lib/libLeap.dylib


+ 2294 - 2294
engine/lib/LeapSDK/lib/libc++/libLeap.dylib

@@ -1,2294 +1,2294 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#include "input/actionMap.h"
-#include "platform/event.h"
-#include "console/console.h"
-#include "platform/platform.h"
-#include "platform/platformInput.h"
-#include "platform/platformAssert.h"
-#include "io/fileStream.h"
-#include "io/resource/resourceManager.h"
-
-// Script bindings.
-#include "actionMap_ScriptBinding.h"
-
-#define CONST_E 2.7182818284590452353602874f
-
-IMPLEMENT_CONOBJECT(ActionMap);
-
-// This is used for determing keys that have ascii codes for the foreign keyboards. IsAlpha doesn't work on foreign keys.
-#define dIsDecentChar(c) (((char(0xa0) <= (c)) && ((c) <= char(0xff))) || (( char(0x21) <= (c)) && ((c) <= char(0x7e))) || (( char(0x91) <= (c)) && ((c) <= char(0x92))))
-
-struct CodeMapping
-{
-   const char* pDescription;
-   U8  type;
-   U32 code;
-};
-
-struct AsciiMapping
-{
-   const char* pDescription;
-   U16         asciiCode;
-};
-
-extern CodeMapping gVirtualMap[];
-extern AsciiMapping gAsciiMap[];
-
-//------------------------------------------------------------------------------
-//-------------------------------------- Action maps
-//
-Vector<ActionMap::BreakEntry> ActionMap::smBreakTable(__FILE__, __LINE__);
-
-
-//------------------------------------------------------------------------------
-ActionMap::ActionMap()
-{
-   VECTOR_SET_ASSOCIATION(mDeviceMaps);
-}
-
-//------------------------------------------------------------------------------
-ActionMap::~ActionMap()
-{
-   for (U32 i = 0; i < (U32)mDeviceMaps.size(); i++)
-      delete mDeviceMaps[i];
-   mDeviceMaps.clear();
-}
-
-//------------------------------------------------------------------------------
-ActionMap::DeviceMap::~DeviceMap()
-{
-   for(U32 i = 0; i < (U32)nodeMap.size(); i++)
-   {
-      dFree(nodeMap[i].makeConsoleCommand);
-      dFree(nodeMap[i].breakConsoleCommand);
-   }
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::onAdd()
-{
-   if (Parent::onAdd() == false)
-      return false;
-
-   Sim::getActionMapGroup()->addObject(this);
-
-   return true;
-}
-
-//--------------------------------------------------------------------------
-void ActionMap::dumpActionMap(const char* fileName, const bool append) const
-{
-   if (fileName != NULL) {
-      // Dump the deletion, and creation script commands, followed by all the binds
-      //  to a script.
-
-      FileStream iostrm;
-      if ( !ResourceManager->openFileForWrite( iostrm, fileName, append ? FileStream::WriteAppend : FileStream::Write ) )
-      {
-         Con::errorf( "Unable to open file '%s' for writing.", fileName );
-         return;
-      }
-
-      char lineBuffer[1024];
-      if ( append )
-         iostrm.setPosition( iostrm.getStreamSize() );
-      else
-      {
-         // IMPORTANT -- do NOT change the following line, it identifies the file as an input map file
-         dStrcpy( lineBuffer, "// Torque Input Map File\n" );
-         iostrm.write( dStrlen( lineBuffer ), lineBuffer );
-      }
-
-      dSprintf(lineBuffer, 1023, "if (isObject(%s)) %s.delete();\n"
-                                 "new ActionMap(%s);\n", getName(), getName(), getName());
-      iostrm.write(dStrlen(lineBuffer), lineBuffer);
-
-      // Dump all the binds to the console...
-      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
-         const DeviceMap* pDevMap = mDeviceMaps[i];
-
-         char devbuffer[32];
-         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);
-
-         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
-            const Node& rNode = pDevMap->nodeMap[j];
-
-            const char* pModifierString = getModifierString(rNode.modifiers);
-
-            char objectbuffer[64];
-            if (getKeyString(rNode.action, objectbuffer) == false)
-               continue;
-
-            const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind";
-
-            dSprintf(lineBuffer, 1023, "%s.%s(%s, \"%s%s\"",
-                                        getName(),
-                                        command,
-                                        devbuffer,
-                                        pModifierString, objectbuffer);
-
-            if (rNode.flags & (Node::HasScale|Node::HasDeadZone|Node::Ranged|Node::Inverted)) {
-               char buff[10];
-               U32 curr = 0;
-               buff[curr++] = ',';
-               buff[curr++] = ' ';
-               if (rNode.flags & Node::HasScale)
-                  buff[curr++] = 'S';
-               if (rNode.flags & Node::Ranged)
-                  buff[curr++] = 'R';
-               if (rNode.flags & Node::HasDeadZone)
-                  buff[curr++] = 'D';
-               if (rNode.flags & Node::Inverted)
-                  buff[curr++] = 'I';
-               buff[curr] = '\0';
-
-               dStrcat(lineBuffer, buff);
-            }
-
-            if (rNode.flags & Node::HasDeadZone) {
-               char buff[64];
-               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
-               dStrcat(lineBuffer, buff);
-            }
-
-            if (rNode.flags & Node::HasScale) {
-               char buff[64];
-               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
-               dStrcat(lineBuffer, buff);
-            }
-
-            if (rNode.flags & Node::BindCmd) {
-               if (rNode.makeConsoleCommand) {
-                  dStrcat(lineBuffer, ", \"");
-                  U32 pos = dStrlen(lineBuffer);
-                  expandEscape(lineBuffer + pos, rNode.makeConsoleCommand);
-                  dStrcat(lineBuffer, "\"");
-               } else {
-                  dStrcat(lineBuffer, ", \"\"");
-               }
-               if (rNode.breakConsoleCommand) {
-                  dStrcat(lineBuffer, ", \"");
-                  U32 pos = dStrlen(lineBuffer);
-                  expandEscape(lineBuffer + pos, rNode.breakConsoleCommand);
-                  dStrcat(lineBuffer, "\"");
-               }
-               else
-                  dStrcat(lineBuffer, ", \"\"");
-            } else {
-               dStrcat(lineBuffer, ", ");
-               dStrcat(lineBuffer, rNode.consoleFunction);
-            }
-
-            dStrcat(lineBuffer, ");\n");
-            iostrm.write(dStrlen(lineBuffer), lineBuffer);
-         }
-      }
-
-      iostrm.close();
-   }
-   else {
-      // Dump all the binds to the console...
-      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
-         const DeviceMap* pDevMap = mDeviceMaps[i];
-
-         char devbuffer[32];
-         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);
-
-         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
-            const Node& rNode = pDevMap->nodeMap[j];
-
-            const char* pModifierString = getModifierString(rNode.modifiers);
-
-            char keybuffer[64];
-            if (getKeyString(rNode.action, keybuffer) == false)
-               continue;
-
-            const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind";
-
-            char finalBuffer[1024];
-            dSprintf(finalBuffer, 1023, "%s.%s(%s, \"%s%s\"",
-                                        getName(),
-                                        command,
-                                        devbuffer,
-                                        pModifierString, keybuffer);
-
-            if (rNode.flags & (Node::HasScale|Node::HasDeadZone|Node::Ranged|Node::Inverted)) {
-               char buff[10];
-               U32 curr = 0;
-               buff[curr++] = ',';
-               buff[curr++] = ' ';
-               if (rNode.flags & Node::HasScale)
-                  buff[curr++] = 'S';
-               if (rNode.flags & Node::Ranged)
-                  buff[curr++] = 'R';
-               if (rNode.flags & Node::HasDeadZone)
-                  buff[curr++] = 'D';
-               if (rNode.flags & Node::Inverted)
-                  buff[curr++] = 'I';
-               buff[curr] = '\0';
-
-               dStrcat(finalBuffer, buff);
-            }
-
-            if (rNode.flags & Node::HasDeadZone) {
-               char buff[64];
-               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
-               dStrcat(finalBuffer, buff);
-            }
-
-            if (rNode.flags & Node::HasScale) {
-               char buff[64];
-               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
-               dStrcat(finalBuffer, buff);
-            }
-
-            if (rNode.flags & Node::BindCmd) {
-               if (rNode.makeConsoleCommand) {
-                  dStrcat(finalBuffer, ", \"");
-                  dStrcat(finalBuffer, rNode.makeConsoleCommand);
-                  dStrcat(finalBuffer, "\"");
-               } else {
-                  dStrcat(finalBuffer, ", \"\"");
-               }
-               if (rNode.breakConsoleCommand) {
-                  dStrcat(finalBuffer, ", \"");
-                  dStrcat(finalBuffer, rNode.breakConsoleCommand);
-                  dStrcat(finalBuffer, "\"");
-               }
-               else
-                  dStrcat(finalBuffer, ", \"\"");
-            } else {
-               dStrcat(finalBuffer, ", ");
-               dStrcat(finalBuffer, rNode.consoleFunction);
-            }
-
-            dStrcat(finalBuffer, ");");
-            Con::printf(finalBuffer);
-         }
-      }
-   }
-}
-
-//--------------------------------------------------------------------------
-bool ActionMap::createEventDescriptor(const char* pEventString, EventDescriptor* pDescriptor)
-{
-   char copyBuffer[256];
-   dStrcpy(copyBuffer, pEventString);
-
-   // Do we have modifiers?
-   char* pSpace = dStrchr(copyBuffer, ' ');
-   char* pObjectString;
-   if (pSpace != NULL) {
-      // Yes.  Parse them out...
-      //
-      pDescriptor->flags = 0;
-      pObjectString      = pSpace + 1;
-      pSpace[0]          = '\0';
-
-      char* pModifier = dStrtok(copyBuffer, "-");
-      while (pModifier != NULL) {
-         if (dStricmp(pModifier, "shift") == 0) {
-            pDescriptor->flags |= SI_SHIFT;
-         } else if (dStricmp(pModifier, "ctrl") == 0) {
-            pDescriptor->flags |= SI_CTRL;
-         } else if (dStricmp(pModifier, "alt") == 0) {
-            pDescriptor->flags |= SI_ALT;
-         } else if (dStricmp(pModifier, "cmd") == 0) {
-            pDescriptor->flags |= SI_ALT;
-         } else if (dStricmp(pModifier, "opt") == 0) {
-            pDescriptor->flags |= SI_MAC_OPT;
-         }
-
-         pModifier = dStrtok(NULL, "-");
-      }
-   } else {
-      // No.
-      pDescriptor->flags = 0;
-      pObjectString      = copyBuffer;
-   }
-
-   // Now we need to map the key string to the proper KEY code from event.h
-   //
-   AssertFatal(dStrlen(pObjectString) != 0, "Error, no key was specified!");
-
-   if (dStrlen(pObjectString) == 1)
-   {
-      if (dIsDecentChar(*pObjectString)) // includes foreign chars
-      {
-         U16 asciiCode = (*pObjectString);
-         // clear out the FF in upper 8bits for foreign keys??
-         asciiCode &= 0xFF;
-         U16 keyCode = Input::getKeyCode(asciiCode);
-         if ( keyCode >= KEY_0 )
-         {
-            pDescriptor->eventType = SI_KEY;
-            pDescriptor->eventCode = keyCode;
-            return true;
-         }
-         else if (dIsalpha(*pObjectString) == true)
-         {
-            pDescriptor->eventType = SI_KEY;
-            pDescriptor->eventCode = KEY_A+dTolower(*pObjectString)-'a';
-            return true;
-         }
-         else if (dIsdigit(*pObjectString) == true)
-         {
-            pDescriptor->eventType = SI_KEY;
-            pDescriptor->eventCode = KEY_0+(*pObjectString)-'0';
-            return true;
-         }
-      }
-      return false;
-   }
-   else
-   {
-      pDescriptor->eventCode = 0;
-      // Gotta search through the Ascii table...
-      for (U16 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++)
-      {
-         if (dStricmp(pObjectString, gAsciiMap[i].pDescription) == 0)
-         {
-            U16 asciiCode = gAsciiMap[i].asciiCode;
-            U16 keyCode   = Input::getKeyCode(asciiCode);
-            if ( keyCode >= KEY_0 )
-            {
-               pDescriptor->eventType = SI_KEY;
-               pDescriptor->eventCode = keyCode;
-               return(true);
-
-            }
-            else
-            {
-               break;
-            }
-         }
-      }
-      // Didn't find an ascii match. Check the virtual map table
-      for (U32 j = 0; gVirtualMap[j].code != 0xFFFFFFFF; j++)
-      {
-         if (dStricmp(pObjectString, gVirtualMap[j].pDescription) == 0)
-         {
-            pDescriptor->eventType = gVirtualMap[j].type;
-            pDescriptor->eventCode = gVirtualMap[j].code;
-            return true;
-         }
-      }
-   }
-   return false;
-}
-
-//------------------------------------------------------------------------------
-ActionMap::Node* ActionMap::getNode(const U32 inDeviceType, const U32 inDeviceInst,
-                   const U32 inModifiers,  const U32 inAction,SimObject* object /*= NULL*/)
-{
-   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
-   //
-   DeviceMap* pDeviceMap = NULL;
-   U32 i;
-   for (i = 0; i < (U32)mDeviceMaps.size(); i++) 
-   {
-      if (mDeviceMaps[i]->deviceType == inDeviceType &&
-          mDeviceMaps[i]->deviceInst == inDeviceInst) {
-         pDeviceMap = mDeviceMaps[i];
-         break;
-      }
-   }
-   if (pDeviceMap == NULL) 
-   {
-      mDeviceMaps.increment();
-      mDeviceMaps.last() = new DeviceMap;
-      pDeviceMap = mDeviceMaps.last();
-
-      pDeviceMap->deviceInst = inDeviceInst;
-      pDeviceMap->deviceType = inDeviceType;
-   }
-
-   for (i = 0; i < (U32)pDeviceMap->nodeMap.size(); i++) 
-   {
-      if (pDeviceMap->nodeMap[i].modifiers == inModifiers &&
-          pDeviceMap->nodeMap[i].action    == inAction &&
-          ( (object != NULL) ? object == pDeviceMap->nodeMap[i].object : true )) // Check for an object match if the object exists 
-      {
-         return &pDeviceMap->nodeMap[i];
-      }
-   }
-
-   // If we're here, the node doesn't exist.  create it.
-   pDeviceMap->nodeMap.increment();
-
-   Node* pRetNode = &pDeviceMap->nodeMap.last();
-   pRetNode->modifiers = inModifiers;
-   pRetNode->action    = inAction;
-
-   pRetNode->flags         = 0;
-   pRetNode->deadZoneBegin = 0.0;
-   pRetNode->deadZoneEnd   = 0.0;
-   pRetNode->scaleFactor   = 1.0;
-
-   pRetNode->consoleFunction = NULL;
-   pRetNode->makeConsoleCommand = NULL;
-   pRetNode->breakConsoleCommand = NULL;
-
-   //[neob, 5/7/2007 - #2975]
-   pRetNode->object = 0;
-
-   return pRetNode;
-}
-
-//------------------------------------------------------------------------------
-void ActionMap::removeNode(const U32 inDeviceType, const U32 inDeviceInst, const U32 inModifiers, const U32 inAction, SimObject* object /*= NULL*/)
-{
-   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
-   //
-   DeviceMap* pDeviceMap = NULL;
-   U32 i;
-   for (i = 0; i < (U32)mDeviceMaps.size(); i++) {
-      if (mDeviceMaps[i]->deviceType == inDeviceType &&
-          mDeviceMaps[i]->deviceInst == inDeviceInst) {
-         pDeviceMap = mDeviceMaps[i];
-         break;
-      }
-   }
-
-   if (pDeviceMap == NULL)
-      return;
-
-   U32 realMods = inModifiers;
-   if (realMods & SI_SHIFT)
-      realMods |= SI_SHIFT;
-   if (realMods & SI_CTRL)
-      realMods |= SI_CTRL;
-   if (realMods & SI_ALT)
-      realMods |= SI_ALT;
-   if (realMods & SI_MAC_OPT)
-      realMods |= SI_MAC_OPT;
-
-   for (i = 0; i < (U32)pDeviceMap->nodeMap.size(); i++) {
-      if (pDeviceMap->nodeMap[i].modifiers == realMods &&
-          pDeviceMap->nodeMap[i].action    == inAction &&
-          ( (object != NULL) ? object == pDeviceMap->nodeMap[i].object : true )) 
-      {
-          dFree(pDeviceMap->nodeMap[i].makeConsoleCommand);
-          dFree(pDeviceMap->nodeMap[i].breakConsoleCommand);
-          pDeviceMap->nodeMap.erase(i);
-      }
-   }
-}
-
-//------------------------------------------------------------------------------
-const ActionMap::Node* ActionMap::findNode(const U32 inDeviceType, const U32 inDeviceInst,
-                    const U32 inModifiers,  const U32 inAction)
-{
-   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
-   //
-   DeviceMap* pDeviceMap = NULL;
-   U32 i;
-   for (i = 0; i < (U32)mDeviceMaps.size(); i++)
-   {
-      if (mDeviceMaps[i]->deviceType == inDeviceType && mDeviceMaps[i]->deviceInst == inDeviceInst)
-      {
-         pDeviceMap = mDeviceMaps[i];
-         break;
-      }
-   }
-
-   if (pDeviceMap == NULL)
-      return NULL;
-
-   U32 realMods = inModifiers;
-   if (realMods & SI_SHIFT)
-      realMods |= SI_SHIFT;
-   if (realMods & SI_CTRL)
-      realMods |= SI_CTRL;
-   if (realMods & SI_ALT)
-      realMods |= SI_ALT;
-   if (realMods & SI_MAC_OPT)
-      realMods |= SI_MAC_OPT;
-
-   for (i = 0; i < (U32)pDeviceMap->nodeMap.size(); i++)
-   {
-      if (pDeviceMap->nodeMap[i].action == KEY_ANYKEY && pDeviceMap->nodeMap[i].modifiers == realMods && dIsDecentChar(inAction))
-         return &pDeviceMap->nodeMap[i];
-      else if (pDeviceMap->nodeMap[i].modifiers == realMods && pDeviceMap->nodeMap[i].action    == inAction)
-         return &pDeviceMap->nodeMap[i];
-   }
-
-   return NULL;
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::findBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
-{
-   devMapIndex = 0;
-   nodeIndex = 0;
-   return nextBoundNode( function, devMapIndex, nodeIndex );
-}
-
-bool ActionMap::nextBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
-{
-   // Loop through all of the existing nodes to find the one mapped to the
-   // given function:
-   for ( U32 i = devMapIndex; i < (U32)mDeviceMaps.size(); i++ )
-   {
-      const DeviceMap* dvcMap = mDeviceMaps[i];
-
-      for ( U32 j = nodeIndex; j < (U32)dvcMap->nodeMap.size(); j++ )
-      {
-         const Node* node = &dvcMap->nodeMap[j];
-         if ( !( node->flags & Node::BindCmd ) && ( dStricmp( function, node->consoleFunction ) == 0 ) )
-         {
-            devMapIndex = i;
-            nodeIndex = j;
-            return( true );
-         }
-      }
-
-      nodeIndex = 0;
-   }
-
-   return( false );
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::processUnbind(const char *device, const char *action, SimObject* object /*= NULL*/)
-{
-   U32 deviceType;
-   U32 deviceInst;
-
-   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
-      return false;
-   EventDescriptor eventDescriptor;
-   if (!createEventDescriptor(action, &eventDescriptor))
-      return false;
-
-   removeNode(deviceType, deviceInst, eventDescriptor.flags,eventDescriptor.eventCode, object);
-   return true;
-}
-
-//------------------------------------------------------------------------------
-// This function is for the use of the control remapper.
-// It will only check against the console function (since all remappable commands are
-// bound using bind and not bindCmd).
-//
-const char* ActionMap::getBinding( const char* command )
-{
-   char* returnString = Con::getReturnBuffer( 1024 );
-   returnString[0] = 0;
-
-   char buffer[256];
-   char deviceBuffer[32];
-   char keyBuffer[64];
- 
-   U32 devMapIndex = 0, nodeIndex = 0;
-   while ( nextBoundNode( command, devMapIndex, nodeIndex ) )
-   {
-      const DeviceMap* deviceMap = mDeviceMaps[devMapIndex];
-
-      if ( getDeviceName( deviceMap->deviceType, deviceMap->deviceInst, deviceBuffer ) )
-      {
-         const Node* node = &deviceMap->nodeMap[nodeIndex];
-         const char* modifierString = getModifierString( node->modifiers );
-
-         if ( getKeyString( node->action, keyBuffer ) )
-         {
-            dSprintf( buffer, sizeof( buffer ), "%s\t%s%s", deviceBuffer, modifierString, keyBuffer );
-            if ( returnString[0] )
-               dStrcat( returnString, "\t" );
-            dStrcat( returnString, buffer );
-         }
-      }
-
-      ++nodeIndex;
-   }
-
-   return returnString;
-}
-
-//------------------------------------------------------------------------------
-// This function is for the use of the control remapper.
-// The intent of this function is to determine if the given event descriptor is already
-// bound in this action map.  If so, this function returns the command it is bound to.
-// If not, it returns NULL.
-//
-const char* ActionMap::getCommand( const char* device, const char* action )
-{
-    U32 deviceType;
-    U32 deviceInst;
-    if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
-    {
-        EventDescriptor eventDescriptor;
-        if ( createEventDescriptor( action, &eventDescriptor ) )
-        {
-            const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
-            if ( mapNode )
-            {
-                if ( mapNode->flags & Node::BindCmd )
-                {
-                    S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2;
-                    char* returnString = Con::getReturnBuffer( bufferLen );
-                    dSprintf( returnString, bufferLen, "%s\t%s",
-                            ( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ),
-                            ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) );					
-                    return( returnString );
-                }					
-                else
-                    return( mapNode->consoleFunction );					
-            }
-        }
-    }
-
-    return( "" );
-}
-
-//------------------------------------------------------------------------------
-// This function returns whether or not the mapping specified is inverted.
-// Obviously, this should only be used for axes.
-bool ActionMap::isInverted( const char* device, const char* action )
-{
-    U32 deviceType;
-    U32 deviceInst;
-    if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
-    {
-        EventDescriptor eventDescriptor;
-        if ( createEventDescriptor( action, &eventDescriptor ) )
-        {
-            const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
-            if ( mapNode )
-                return( mapNode->flags & Node::Inverted );
-        }
-    }
-
-    Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
-    return( false );
-}
-
-//------------------------------------------------------------------------------
-F32 ActionMap::getScale( const char* device, const char* action )
-{
-    U32 deviceType;
-    U32 deviceInst;
-    if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
-    {
-        EventDescriptor eventDescriptor;
-        if ( createEventDescriptor( action, &eventDescriptor ) )
-        {
-            const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
-            if ( mapNode )
-            {
-               if ( mapNode->flags & Node::HasScale )
-                   return( mapNode->scaleFactor );
-            else
-               return( 1.0f );
-         }
-        }
-    }
-
-    Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
-    return( 1.0f );
-}
-
-//------------------------------------------------------------------------------
-const char* ActionMap::getDeadZone( const char* device, const char* action )
-{
-    U32 deviceType;
-    U32 deviceInst;
-    if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
-    {
-        EventDescriptor eventDescriptor;
-        if ( createEventDescriptor( action, &eventDescriptor ) )
-        {
-            const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
-            if ( mapNode )
-            {
-               if ( mapNode->flags & Node::HasDeadZone )
-               {
-                   char buf[64];
-                   dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd );
-                   char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 );
-                   dStrcpy( returnString, buf );
-                   return( returnString );
-                }
-                else
-                   return( "0 0" );				   		
-            }
-        }
-    }
-
-    Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
-    return( "" );
-}
-
-//------------------------------------------------------------------------------
-const char* ActionMap::buildActionString( const InputEvent* event )
-{
-    const char* modifierString = getModifierString( event->modifier );
-
-    char objectBuffer[64];
-    if ( !getKeyString( event->objInst, objectBuffer ) )
-        return( "" );
-
-    U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2;	
-    char* returnString = Con::getReturnBuffer( returnLen );
-    dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer );
-    return( returnString );
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::getDeviceTypeAndInstance(const char *pDeviceName, U32 &deviceType, U32 &deviceInstance)
-{
-   U32 offset = 0;
-    
-   if (dStrnicmp(pDeviceName, "keyboard", dStrlen("keyboard")) == 0)
-   {
-      deviceType = KeyboardDeviceType;
-      offset = dStrlen("keyboard");
-   } 
-   else if (dStrnicmp(pDeviceName, "mouse", dStrlen("mouse")) == 0) 
-   {
-      deviceType = MouseDeviceType;
-      offset = dStrlen("mouse");
-   } 
-   else if (dStrnicmp(pDeviceName, "joystick", dStrlen("joystick")) == 0) 
-   {
-      deviceType = JoystickDeviceType;
-      offset = dStrlen("joystick");
-   } 
-   else if (dStrnicmp(pDeviceName, "accelerometer", dStrlen("accelerometer")) == 0) 
-   {
-      deviceType = AccelerometerDeviceType;
-      offset = dStrlen("accelerometer");
-   }
-   else if (dStrnicmp(pDeviceName, "gyroscope", dStrlen("gyroscope")) == 0)
-   {
-       deviceType = GyroscopeDeviceType;
-       offset = dStrlen("gyroscope");
-   }
-   else if (dStrnicmp(pDeviceName, "touchdevice", dStrlen("touchdevice")) == 0)
-   {
-       deviceType = ScreenTouchDeviceType;
-       offset = dStrlen("touchdevice");
-   }
-    else if (dStrnicmp(pDeviceName, "gamepad", dStrlen("gamepad")) == 0)
-   {
-      deviceType = GamepadDeviceType;
-      offset     = dStrlen("gamepad");
-   }
-   else if (dStrnicmp(pDeviceName, "leapdevice", dStrlen("leapdevice")) == 0)
-   {
-       deviceType = LeapMotionDeviceType;
-       offset = dStrlen("leapdevice");
-   }
-   else
-      return false;
-    
-   if (dStrlen(pDeviceName) > offset) 
-   {
-      const char* pInst = pDeviceName + offset;
-      S32 instNum = dAtoi(pInst);
-      
-      if (instNum < 0)
-         deviceInstance = 0;
-      else
-         deviceInstance = instNum;
-   } 
-   else 
-       deviceInstance = 0;
-    
-   return true;
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::getDeviceName(const U32 deviceType, const U32 deviceInstance, char* buffer)
-{
-   switch (deviceType)
-   {
-     case KeyboardDeviceType:
-      dStrcpy(buffer, "keyboard");
-      break;
-
-     case MouseDeviceType:
-      dSprintf(buffer, 16, "mouse%d", deviceInstance);
-      break;
-
-     case JoystickDeviceType:
-      dSprintf(buffer, 16, "joystick%d", deviceInstance);
-      break;
-    
-     case AccelerometerDeviceType:
-     dStrcpy(buffer, "accelerometer");
-     break;
-    
-     case GyroscopeDeviceType:
-     dStrcpy(buffer, "gyroscope");
-     break;
-     
-     case ScreenTouchDeviceType:
-     dStrcpy(buffer, "touchdevice");
-     break;
-
-	  case GamepadDeviceType:
-      dSprintf(buffer, 16, "gamepad%d", deviceInstance);
-      break;
-
-     case LeapMotionDeviceType:
-      dStrcpy(buffer, "leapdevice");
-      break;
-
-     default:
-      Con::errorf( "ActionMap::getDeviceName: unknown device type specified, %d (inst: %d)", deviceType, deviceInstance);
-      return false;
-   }
-
-   return true;
-}
-
-//------------------------------------------------------------------------------
-const char* ActionMap::getModifierString(const U32 modifiers)
-{
-    U32 realModifiers = modifiers;
-    if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT )
-        realModifiers |= SI_SHIFT;
-    if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL )
-        realModifiers |= SI_CTRL;
-    if ( modifiers & SI_LALT || modifiers & SI_RALT )
-        realModifiers |= SI_ALT;
-    if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT )
-        realModifiers |= SI_MAC_OPT;
-
-   switch (realModifiers & (SI_SHIFT|SI_CTRL|SI_ALT|SI_MAC_OPT)) {
-#if defined(TORQUE_OS_OSX)
-      // optional code, to output alt as cmd on mac.
-      // interpreter sees them as the same...
-     case (SI_SHIFT|SI_CTRL|SI_ALT):
-      return "cmd-shift-ctrl ";
-
-     case (SI_SHIFT|SI_ALT):
-      return "cmd-shift ";
-
-     case (SI_CTRL|SI_ALT):
-      return "cmd-ctrl ";
-
-     case (SI_ALT):
-      return "cmd ";
-#else
-     case (SI_SHIFT|SI_CTRL|SI_ALT):
-      return "shift-ctrl-alt ";
-
-     case (SI_SHIFT|SI_ALT):
-      return "shift-alt ";
-
-     case (SI_CTRL|SI_ALT):
-      return "ctrl-alt ";
-
-     case (SI_ALT):
-      return "alt ";
-#endif
-     case (SI_SHIFT|SI_CTRL):
-      return "shift-ctrl ";
-
-     case (SI_SHIFT):
-      return "shift ";
-
-     case (SI_CTRL):
-      return "ctrl ";
-
-// plus new mac cases:
-     case (SI_ALT|SI_SHIFT|SI_CTRL|SI_MAC_OPT):
-      return "cmd-shift-ctrl-opt ";
-
-     case (SI_ALT|SI_SHIFT|SI_MAC_OPT):
-      return "cmd-shift-opt ";
-
-     case (SI_ALT|SI_CTRL|SI_MAC_OPT):
-      return "cmd-ctrl-opt ";
-
-     case (SI_ALT|SI_MAC_OPT):
-      return "cmd-opt ";
-
-     case (SI_SHIFT|SI_CTRL|SI_MAC_OPT):
-      return "shift-ctrl-opt ";
-
-     case (SI_SHIFT|SI_MAC_OPT):
-      return "shift-opt ";
-
-     case (SI_CTRL|SI_MAC_OPT):
-      return "ctrl-opt ";
-
-     case (SI_MAC_OPT):
-      return "opt ";
-      
-     case 0:
-      return "";
-
-     default:
-      AssertFatal(false, "Error, should never reach the default case in getModifierString");
-      return "";
-   }
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::getKeyString(const U32 action, char* buffer)
-{
-   U16 asciiCode = Input::getAscii(action, STATE_LOWER);
-
-//   if (action >= KEY_A && action <= KEY_Z) {
-//      buffer[0] = char(action - KEY_A + 'a');
-//      buffer[1] = '\0';
-//      return true;
-//   } else if (action >= KEY_0 && action <= KEY_9) {
-//      buffer[0] = char(action - KEY_0 + '0');
-//      buffer[1] = '\0';
-   if ( (asciiCode != 0) && dIsDecentChar((char)asciiCode))
-   {
-      for (U32 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++) {
-         if (gAsciiMap[i].asciiCode == asciiCode)
-         {
-            dStrcpy(buffer, gAsciiMap[i].pDescription);
-            return true;
-         }
-      }
-      // Must not have found a string for that ascii code just record the char
-      buffer[0] = char(asciiCode);
-      buffer[1] = '\0';
-      return true;
-   }
-   else
-   {
-      if (action >= KEY_A && action <= KEY_Z)
-      {
-         buffer[0] = char(action - KEY_A + 'a');
-         buffer[1] = '\0';
-         return true;
-      }
-      else if (action >= KEY_0 && action <= KEY_9) {
-         buffer[0] = char(action - KEY_0 + '0');
-         buffer[1] = '\0';
-         return true;
-      }
-      for (U32 i = 0; gVirtualMap[i].code != 0xFFFFFFFF; i++) {
-         if (gVirtualMap[i].code == action) {
-            dStrcpy(buffer, gVirtualMap[i].pDescription);
-            return true;
-         }
-      }
-   }
-
-   Con::errorf( "ActionMap::getKeyString: no string for action %d", action );
-   return false;
-}
-
-//--------------------------------------------------------------------------
-bool ActionMap::processBindCmd(const char *device, const char *action, const char *makeCmd, const char *breakCmd)
-{
-   U32 deviceType;
-   U32 deviceInst;
-
-   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
-   {
-      Con::printf("processBindCmd: unknown device: %s", device);
-      return false;
-   }
-
-   // Ok, we now have the deviceType and instance.  Create an event descriptor
-   //  for the bind...
-   //
-   EventDescriptor eventDescriptor;
-   if (createEventDescriptor(action, &eventDescriptor) == false) {
-      Con::printf("Could not create a description for binding: %s", action);
-      return false;
-   }
-
-   // SI_POV == SI_MOVE, and the POV works fine with bindCmd, so we have to add these manually.
-   if( ( eventDescriptor.eventCode == SI_XAXIS )    ||
-       ( eventDescriptor.eventCode == SI_YAXIS )    ||
-       ( eventDescriptor.eventCode == SI_ZAXIS )    ||
-       ( eventDescriptor.eventCode == SI_RXAXIS )   ||
-       ( eventDescriptor.eventCode == SI_RYAXIS )   ||
-       ( eventDescriptor.eventCode == SI_RZAXIS )   ||
-       ( eventDescriptor.eventCode == SI_SLIDER )   ||
-       ( eventDescriptor.eventCode == SI_XPOV )     ||
-       ( eventDescriptor.eventCode == SI_YPOV )     ||
-       ( eventDescriptor.eventCode == SI_XPOV2 )    ||
-       ( eventDescriptor.eventCode == SI_YPOV2 )    ||
-       ( eventDescriptor.eventCode == SI_ACCELX )   ||
-       ( eventDescriptor.eventCode == SI_ACCELY )   ||
-       ( eventDescriptor.eventCode == SI_ACCELZ )   ||
-       ( eventDescriptor.eventCode == SI_GRAVX )    ||
-       ( eventDescriptor.eventCode == SI_GRAVY )    ||
-       ( eventDescriptor.eventCode == SI_GRAVZ )    ||
-       ( eventDescriptor.eventCode == SI_GYROX )    ||
-       ( eventDescriptor.eventCode == SI_GYROY )    ||
-       ( eventDescriptor.eventCode == SI_GYROZ )    ||
-       ( eventDescriptor.eventCode == SI_YAW )      ||
-       ( eventDescriptor.eventCode == SI_PITCH )    ||
-       ( eventDescriptor.eventCode == SI_ROLL ) )	
-   {
-      Con::warnf( "ActionMap::processBindCmd - Cannot use 'bindCmd' with a move event type. Use 'bind' instead." );
-      return false;
-   }
-
-   // Create the full bind entry, and place it in the map
-   //
-   // DMMTODO
-   Node* pBindNode = getNode(deviceType, deviceInst,
-                             eventDescriptor.flags,
-                             eventDescriptor.eventCode);
-
-   pBindNode->flags           = Node::BindCmd;
-   pBindNode->deadZoneBegin   = 0;
-   pBindNode->deadZoneEnd     = 0;
-   pBindNode->scaleFactor     = 1;
-   if(makeCmd[0])
-      pBindNode->makeConsoleCommand = dStrdup(makeCmd);
-   else
-      pBindNode->makeConsoleCommand = dStrdup("");
-
-   if(breakCmd[0])
-      pBindNode->breakConsoleCommand = dStrdup(breakCmd);
-   else
-      pBindNode->breakConsoleCommand = dStrdup("");
-   return true;
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::processBind(const U32 argc, const char** argv, SimObject* object)
-{
-   // Ok, the bind will come in the following format:
-   //  [device] [key or button] <[param spec] [param] ...> [fnName]
-   //
-   const char* pDeviceName = argv[0];
-   const char* pEvent      = argv[1];
-   const char* pFnName     = argv[argc - 1];
-
-   // Determine the device
-   U32 deviceType;
-   U32 deviceInst;
-
-   if(!getDeviceTypeAndInstance(argv[0], deviceType, deviceInst))
-   {
-      Con::printf("processBind: unknown device: %s", pDeviceName);
-      return false;
-   }
-
-   // Ok, we now have the deviceType and instance.  Create an event descriptor
-   //  for the bind...
-   //
-   EventDescriptor eventDescriptor;
-   if (createEventDescriptor(pEvent, &eventDescriptor) == false) {
-      Con::printf("Could not create a description for binding: %s", pEvent);
-      return false;
-   }
-
-   // Event has now been described, and device determined.  we need now to extract
-   //  any modifiers that the action map will apply to incoming events before
-   //  calling the bound function...
-   //
-   // DMMTODO
-   U32 assignedFlags = 0;
-   F32 deadZoneBegin = 0.0f;
-   F32 deadZoneEnd   = 0.0f;
-   F32 scaleFactor   = 1.0f;
-
-   if (argc != 3) {
-      // We have the following: "[DSIR]" [deadZone] [scale]
-      //
-      const char* pSpec = argv[2];
-
-      for (U32 i = 0; pSpec[i] != '\0'; i++) {
-         switch (pSpec[i]) {
-           case 'r': case 'R':
-            assignedFlags |= Node::HasScale;
-            break;
-           case 's': case 'S':
-            assignedFlags |= Node::HasScale;
-            break;
-           case 'd': case 'D':
-            assignedFlags |= Node::HasDeadZone;
-            break;
-           case 'i': case 'I':
-            assignedFlags |= Node::Inverted;
-            break;
-			case 'n': case 'N':
-            assignedFlags |= Node::NonLinear;
-            break;
-
-           default:
-            AssertFatal(false, avar("Misunderstood specifier in bind (spec string: %s)",
-                                    pSpec));
-         }
-      }
-
-      // Ok, we have the flags.  Scan the dead zone and scale, if any.
-      //
-      U32 curArg = 3;
-      if (assignedFlags & Node::HasDeadZone) {
-         dSscanf(argv[curArg], "%g %g", &deadZoneBegin, &deadZoneEnd);
-         curArg++;
-      }
-      if (assignedFlags & Node::HasScale) {
-         scaleFactor = dAtof(argv[curArg]);
-         curArg++;
-      }
-
-      if (curArg != (argc - 1)) {
-         AssertFatal(curArg == (argc - 1), "error in bind spec somewhere...");
-         Con::printf("Improperly specified bind for key: %s", argv[2]);
-         return false;
-      }
-   }
-
-   // Ensure that the console function is properly specified?
-   //
-   // DMMTODO
-
-   // Create the full bind entry, and place it in the map
-   //
-   // DMMTODO
-   Node* pBindNode = getNode(deviceType, deviceInst,
-                             eventDescriptor.flags,
-                             eventDescriptor.eventCode, object);
-
-   pBindNode->flags           = assignedFlags;
-   pBindNode->deadZoneBegin   = deadZoneBegin;
-   pBindNode->deadZoneEnd     = deadZoneEnd;
-   pBindNode->scaleFactor     = scaleFactor;
-   pBindNode->object          = object;
-   pBindNode->consoleFunction = StringTable->insert(pFnName);
-
-   return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ActionMap::processLeap(const InputEvent* pEvent)
-{
-    static const char *argv[5];
-    char buffer[64];
-
-    const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objType );
-
-    if (pNode == NULL)
-    {
-        // Check to see if we clear the modifiers, do we find an action?
-        if (pEvent->modifier != 0)
-            pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objInst);
-
-        if (pNode == NULL)
-            return false;
-    }
-
-    // "Do nothing" bind:
-    if ( !pNode->consoleFunction[0] )
-        return( true );
-
-    argv[0] = pNode->consoleFunction;
-
-    float values[3];
-    values[0] = pEvent->fValues[0];
-    values[1] = pEvent->fValues[1];
-    values[2] = pEvent->fValues[2];
-
-    if ( pNode->flags & Node::HasDeadZone )
-    {
-        if ( pEvent->fValues[0] >= pNode->deadZoneBegin && pEvent->fValues[0] <= pNode->deadZoneEnd )
-            values[0] = 0.0f;
-        if ( pEvent->fValues[1] >= pNode->deadZoneBegin && pEvent->fValues[1] <= pNode->deadZoneEnd )
-            values[1] = 0.0f;
-        if ( pEvent->fValues[2] >= pNode->deadZoneBegin && pEvent->fValues[2] <= pNode->deadZoneEnd )
-            values[2] = 0.0f;
-
-        // All values are all null, so don't bother executing the function
-        if (!values[0] && !values[1] && !values[2])
-            return true;
-    }
-
-    switch(pEvent->objType)
-    {
-        case LM_HANDPOS:
-
-            // ID
-            argv[1] = Con::getIntArg(pEvent->iValue);
-
-            // Position
-            dSprintf(buffer, sizeof(buffer), "%f %f %f", values[0], values[1], values[2]);
-
-            argv[2] = buffer;
-
-            if (pNode->object)
-                Con::executef(pNode->object, 3, argv[0], argv[1], argv[2]);
-            else
-                Con::execute(3, argv);
-            break;
-
-        case LM_HANDROT:
-            
-            // ID
-            argv[1] = Con::getIntArg(pEvent->iValue);
-
-            // Rotation
-            dSprintf(buffer, sizeof(buffer), "%f %f %f", values[0], values[1], values[2]);
-
-            argv[2] = buffer;
-
-            if (pNode->object)
-                Con::executef(pNode->object, 3, argv[0], argv[1], argv[2]);
-            else
-                Con::execute(3, argv);
-            break;
-
-        case LM_FINGERPOS:
-            
-            // IDs
-            argv[1] = pEvent->fingerIDs;
-
-            // X-coordinates
-            argv[2] = pEvent->fingersX;
-
-            // Y-coordinates
-            argv[3] = pEvent->fingersY;
-
-            // Z-coordinates
-            argv[4] = pEvent->fingersZ;
-
-            if (pNode->object)
-                Con::executef(pNode->object, 5, argv[0], argv[1], argv[2], argv[3], argv[4]);
-            else
-                Con::execute(5, argv);
-            break;
-
-        case LM_HANDAXIS:
-        default:
-            return false;
-    }
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ActionMap::processGesture(const InputEvent* pEvent)
-{
-    static const char *argv[6];
-    char buffer[64];
-
-    const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objType );
-
-    if (pNode == NULL) 
-    {
-        // Check to see if we clear the modifiers, do we find an action?
-        if (pEvent->modifier != 0)
-            pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objInst);
-           
-        if (pNode == NULL)
-            return false;
-    }
-
-    // "Do nothing" bind:
-    if ( !pNode->consoleFunction[0] )
-        return( true );
-
-    // Function
-    argv[0] = pNode->consoleFunction;
-    
-    switch(pEvent->objType)
-    {
-        case SI_CIRCLE_GESTURE:
-
-            // ID
-            argv[1] = Con::getIntArg(pEvent->iValue);
-
-            // Progress
-            argv[2] = Con::getFloatArg(pEvent->fValues[0]);
-
-            // Radius
-            argv[3] = Con::getFloatArg(pEvent->fValues[1]);
-
-            // Direction (1 clockwise, 0 counter-clockwise)
-            argv[4] = Con::getFloatArg(pEvent->fValues[2]);
-
-            // State
-            argv[5] = Con::getFloatArg(pEvent->fValues[3]);
-
-            if (pNode->object)
-                Con::executef(pNode->object, 6, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
-            else
-                Con::execute(6, argv);
-            break;
-
-        case SI_SWIPE_GESTURE:
-
-            // ID
-            argv[1] = Con::getIntArg(pEvent->iValue);
-
-            // State
-            argv[2] = Con::getFloatArg(pEvent->fValues[0]);
-
-            // Direction
-            dSprintf(buffer, sizeof(buffer), "%f %f %f", pEvent->fValues[1], pEvent->fValues[2], pEvent->fValues[3]);
-
-            argv[3] = buffer;
-            // Speed
-            argv[4] = Con::getFloatArg(pEvent->fValues[4]);
-
-            if (pNode->object)
-                Con::executef(pNode->object, 5, argv[0], argv[1], argv[2], argv[3], argv[4]);
-            else
-                Con::execute(5, argv);
-            break;
-
-        case SI_KEYTAP_GESTURE:
-        case SI_SCREENTAP_GESTURE:
-
-            // ID
-            argv[1] = Con::getIntArg(pEvent->iValue);
-        
-            // Position
-            dSprintf(buffer, sizeof(buffer), "%f %f %f", pEvent->fValues[0], pEvent->fValues[1], pEvent->fValues[2]);
-
-            argv[2] = buffer;
-
-            // Direction
-            dSprintf(buffer, sizeof(buffer), "%f %f %f", pEvent->fValues[3], pEvent->fValues[4], pEvent->fValues[5]);
-
-            argv[3] = buffer;
-
-            if (pNode->object)
-                Con::executef(pNode->object, 4, argv[0], argv[1], argv[2], argv[3]);
-            else
-                Con::execute(5, argv);
-
-            break;
-
-        case SI_PINCH_GESTURE:
-        case SI_SCALE_GESTURE:
-        default:
-            return true;
-    }
-       
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ActionMap::processTouch(const InputEvent* pEvent)
-{
-    static const char *argv[4];
-    const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objInst);
-       
-    if (pNode == NULL) 
-    {
-        // Check to see if we clear the modifiers, do we find an action?
-        if (pEvent->modifier != 0)
-            pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objInst);
-           
-        if (pNode == NULL)
-            return false;
-    }
-       
-    // "Do nothing" bind:
-    if ( !pNode->consoleFunction[0] )
-        return( true );
-       
-    // Ok, we're all set up, call the function.
-    argv[0] = pNode->consoleFunction;
-    argv[1] = pEvent->fingerIDs;
-    argv[2] = pEvent->fingersX;
-    argv[3] = pEvent->fingersY;
-       
-    if (pNode->object)
-        Con::executef(pNode->object, 4, argv[0], argv[1], argv[2], argv[3]);
-    else
-        Con::execute(4, argv);
-       
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ActionMap::processButton(const InputEvent* pEvent)
-{
-    static const char *argv[2];
-    const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objInst);
-
-    if (pNode == NULL) 
-    {
-        // Check to see if we clear the modifiers, do we find an action?
-        if (pEvent->modifier != 0)
-            pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objInst);
-
-        if (pNode == NULL)
-            return false;
-    }
-
-    // Whadda ya know, we have this bound.  Set up, and call the console
-    //  function associated with it...
-    //
-    F32 value = pEvent->fValues[0];
-       
-    if (pNode->flags & Node::Ranged)
-    {
-        value = (value * 2.0f) - 1.0f;
-         
-        if (pNode->flags & Node::Inverted)
-            value *= -1.0f;
-    }
-    else
-    {
-        if (pNode->flags & Node::Inverted)
-            value = 1.0f - value;
-    }
-
-    if (pNode->flags & Node::HasScale)
-        value *= pNode->scaleFactor;
-
-    if (pNode->flags & Node::HasDeadZone)
-    {
-        if (value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd)
-            value = 0.0f;
-        else			
-        {
-            if( value > 0 )
-                value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
-            else
-                value = ( value + pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
-        }
-    }
-
-    if( pNode->flags & Node::NonLinear )
-        value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
-
-    // Ok, we're all set up, call the function.
-    if(pNode->flags & Node::BindCmd)
-    {
-        // it's a bind command
-        if(pNode->makeConsoleCommand)
-            Con::evaluate(pNode->makeConsoleCommand);
-    }
-    else if ( pNode->consoleFunction[0] )
-    {
-        argv[0] = pNode->consoleFunction;
-        argv[1] = Con::getFloatArg(value);
-        
-        if (pNode->object)
-            Con::executef(pNode->object, 2, argv[0], argv[1]);
-        else
-            Con::execute(2, argv);
-    }
-
-    // [neo, 5/13/2007 - #3109]
-    // The execs/evaluate above could have called reentrant script code which made calls to
-    // bindCmd() etc, channging the node map underneath us. If enough nodes were added then
-    // the node map vector would realloc, with the result that pNode would then be pointing 
-    // at garbage and cause a crash when passed to enterBreakEvent() below. So we just look
-    // it up again to be safe. This is not needed in the other cases below as we return right
-    // after the execs and don't use pNode again.
-    pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objInst );
-
-    if( pNode == NULL )
-        return true; // We already called any bound methods/functions so our job is done
-
-    //
-    // And enter the break into the table if this is a make event...
-    enterBreakEvent(pEvent, pNode);
-
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ActionMap::processMove(const InputEvent* pEvent)
-{
-    static const char *argv[2];
-
-    if (pEvent->deviceType == MouseDeviceType)
-    {
-        const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objType);
-
-        if (pNode == NULL)
-        {
-            // Check to see if we clear the modifiers, do we find an action?
-            if (pEvent->modifier != 0)
-                pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objType);
-
-            if (pNode == NULL)
-                return false;
-        }
-
-        // "Do nothing" bind:
-        if ( !pNode->consoleFunction[0] )
-            return( true );
-
-        // Whadda ya know, we have this bound.  Set up, and call the console
-        //  function associated with it.  Mouse events ignore range and dead
-        //  zone params.
-        //
-        F32 value = pEvent->fValues[0];
-         
-        if (pNode->flags & Node::Inverted)
-            value *= -1.0f;
-        if (pNode->flags & Node::HasScale)
-            value *= pNode->scaleFactor;
-
-        // Ok, we're all set up, call the function.
-        argv[0] = pNode->consoleFunction;
-        argv[1] = Con::getFloatArg(value);
-          
-        if (pNode->object)
-            Con::executef(pNode->object, 2, argv[0], argv[1]);
-        else
-            Con::execute(2, argv);
-
-            return true;
-    } 
-    else if ( (pEvent->objType == XI_POS || pEvent->objType == XI_FLOAT || pEvent->objType == XI_ROT || pEvent->objType == XI_INT) )
-    {
-        const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst, pEvent->modifier,   pEvent->objInst);
-
-        if( pNode == NULL )
-            return false;
-
-        // Ok, we're all set up, call the function.
-        argv[0] = pNode->consoleFunction;
-        S32 argc = 1;
-
-        if (pEvent->objType == XI_INT)
-        {
-            // Handle the integer as some sort of motion such as a
-            // single component to an absolute position
-            argv[1] = Con::getIntArg( pEvent->iValue );
-            argc += 1;
-        }
-        else if (pEvent->objType == XI_FLOAT)
-        {
-            // Handle float as some sort of motion such as a
-            // single component to an absolute position
-            argv[1] = Con::getFloatArg( pEvent->fValues[0] );
-            argc += 1;
-        }
-        else if (pEvent->objType == XI_POS)
-        {
-            // Handle Point3F type position
-            argv[1] = Con::getFloatArg( pEvent->fValues[0] );
-            argv[2] = Con::getFloatArg( pEvent->fValues[1] );
-            argv[3] = Con::getFloatArg( pEvent->fValues[2] );
-
-            argc += 3;
-        }
-
-        if (pNode->object)
-        {
-            Con::execute(pNode->object, argc, argv);
-        }
-        else
-        {
-            Con::execute(argc, argv);
-        }
-
-        return true;
-    }
-    else if ( pEvent->deviceType == JoystickDeviceType || pEvent->deviceType == GamepadDeviceType )
-    {
-        // Joystick events...
-        const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier,   pEvent->objInst );
-
-        if( pNode == NULL )
-            return false;
-
-        // "Do nothing" bind:
-        if ( !pNode->consoleFunction[0] )
-            return( true );
-
-        // Whadda ya know, we have this bound.  Set up, and call the console
-        //  function associated with it.  Joystick move events are the same as mouse
-        //  move events except that they don't ignore dead zone.
-        //
-        F32 value = pEvent->fValues[0];
-        if ( pNode->flags & Node::Inverted )
-            value *= -1.0f;
-
-        if ( pNode->flags & Node::HasScale )
-            value *= pNode->scaleFactor;
-
-        if ( pNode->flags & Node::HasDeadZone )
-        {
-            if ( value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd )
-            {
-                value = 0.0f;
-            }
-            else
-            {
-                if( value > 0 )
-                    value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
-                else
-                    value = ( value + pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
-            }
-        }
-
-        if( pNode->flags & Node::NonLinear )
-            value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
-
-        // Ok, we're all set up, call the function.
-        argv[0] = pNode->consoleFunction;
-        argv[1] = Con::getFloatArg( value );
-            
-        if (pNode->object)
-            Con::executef(pNode->object, S32(argv[0]), argv[1]);
-        else
-            Con::execute(2, argv);
-
-        return true;
-    }
-
-    return false;
-}
-
-//------------------------------------------------------------------------------
-
-bool ActionMap::processMotion(const InputEvent* pEvent)
-{
-    static const char *argv[2];
-
-    // iOS Accelerometer, Gyroscope and DeviceMotion processing
-    // Currently, this is identical to the joystick handling.
-       
-    // This was copied over into its own section because this will
-    // give us a dedicated section to tweak processing based on iOS specific
-    // devices. No point in trying to mangle joystick code any further
-    const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier,   pEvent->objType );
-       
-    if ( pNode == NULL )
-    {
-        // Check to see if we clear the modifiers, do we find an action?
-        if (pEvent->modifier != 0)
-            pNode = findNode( pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objType );
-           
-        if ( pNode == NULL )
-            return false;
-    }
-       
-    // "Do nothing" bind:
-    if ( !pNode->consoleFunction[0] )
-        return( true );
-       
-    F32 value = pEvent->fValues[0];
-       
-    if ( pNode->flags & Node::Inverted )
-        value *= -1.0f;
-       
-    if ( pNode->flags & Node::HasScale )
-        value *= pNode->scaleFactor;
-       
-    if ( pNode->flags & Node::HasDeadZone )
-    {
-        if ( value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd )
-            value = 0.0f;
-    }
-       
-    // Ok, we're all set up, call the function.
-    argv[0] = pNode->consoleFunction;
-    argv[1] = Con::getFloatArg( value );
-       
-    if (pNode->object)
-        Con::executef(pNode->object, 2, argv[0], argv[1]);
-    else
-        Con::execute(2, argv);
-       
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ActionMap::processXInput(const InputEvent* pEvent)
-{
-    static const char *argv[2];
-
-    if ((pEvent->objType == XI_FLOAT || pEvent->objType == XI_INT))
-    {
-        const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objType );
-
-        if (pNode == NULL )
-            return false;
-
-        // Ok, we're all set up, call the function.
-        argv[0] = pNode->consoleFunction;
-        S32 argc = 1;
-
-        if (pEvent->objType == XI_INT)
-        {
-            // Handle the integer as some sort of motion such as a
-            // single component to an absolute position
-            argv[1] = Con::getIntArg( pEvent->iValue );
-            argc += 1;
-        }
-        else if (pEvent->objType == XI_FLOAT)
-        {
-            // Handle float as some sort of motion such as a
-            // single component to an absolute position
-            argv[1] = Con::getFloatArg( pEvent->fValues[0] );
-            argc += 1;
-        }
-
-        if (pNode->object)
-        {
-            Con::execute(pNode->object, argc, argv);
-        }
-        else
-        {
-            Con::execute(argc, argv);
-        }
-    }
-    
-    return true;
-}
-
-//------------------------------------------------------------------------------
-
-bool ActionMap::processAction(const InputEvent* pEvent)
-{
-    switch(pEvent->action)
-    {
-    case SI_LEAP:
-        return processLeap(pEvent);
-        break;
-    case SI_GESTURE:
-        return processGesture(pEvent);
-        break;
-    case SI_TOUCH:
-        return processTouch(pEvent);
-        break;
-    case SI_MAKE:
-        return processButton(pEvent);
-        break;
-    case SI_MOVE:
-        return processMove(pEvent);
-        break;
-    case SI_MOTION:
-        return processMotion(pEvent);
-        break;
-    case SI_BREAK:
-        return checkBreakTable(pEvent);
-        break;
-    case SI_VALUE:
-        return processXInput(pEvent);
-    }
-
-    return false;
-}
-
-//------------------------------------------------------------------------------
-void ActionMap::enterBreakEvent(const InputEvent* pEvent, const Node* pNode)
-{
-   // There aren't likely to be many breaks outstanding at any one given time,
-   //  so a simple linear search is probably sufficient.  Note that the break table
-   //  is static to the class, all breaks are directed to the action map that received
-   //  the make.
-   //
-   S32 entry = -1;
-   for (U32 i = 0; i < (U32)smBreakTable.size(); i++) {
-      if (smBreakTable[i].deviceType == U32(pEvent->deviceType) &&
-          smBreakTable[i].deviceInst == U32(pEvent->deviceInst) &&
-          smBreakTable[i].objInst    == U32(pEvent->objInst)) {
-         // Match.
-         entry = i;
-         break;
-      }
-   }
-   if (entry == -1) {
-      smBreakTable.increment();
-      entry = smBreakTable.size() - 1;
-
-      smBreakTable[entry].deviceType = pEvent->deviceType;
-      smBreakTable[entry].deviceInst = pEvent->deviceInst;
-      smBreakTable[entry].objInst    = pEvent->objInst;
-   }
-
-   // Ok, we now have the entry, and know that the device desc. and the objInst match.
-   //  Copy out the node information...
-   //
-   smBreakTable[entry].object = pNode->object;
-   // [neo, 5/7/2007 - #2975]
-   // object above can be deleted in between a make/break and so object will point
-   // to turfed memory and crash. To keep things simple we just store id as well so
-   // we can look it up to validate object ref.
-   smBreakTable[entry].objectId = pNode->object ? pNode->object->getId() : 0;
-
-   smBreakTable[entry].consoleFunction = pNode->consoleFunction;
-
-   if(pNode->breakConsoleCommand)
-      smBreakTable[entry].breakConsoleCommand = dStrdup(pNode->breakConsoleCommand);
-   else
-      smBreakTable[entry].breakConsoleCommand = NULL;
-
-   smBreakTable[entry].flags         = pNode->flags;
-   smBreakTable[entry].deadZoneBegin = pNode->deadZoneBegin;
-   smBreakTable[entry].deadZoneEnd   = pNode->deadZoneEnd;
-   smBreakTable[entry].scaleFactor   = pNode->scaleFactor;
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::checkBreakTable(const InputEvent* pEvent)
-{
-   for (U32 i = 0; i < (U32)smBreakTable.size(); i++) {
-      if (smBreakTable[i].deviceType == U32(pEvent->deviceType) &&
-          smBreakTable[i].deviceInst == U32(pEvent->deviceInst) &&
-          smBreakTable[i].objInst    == U32(pEvent->objInst)) {
-         // Match.  Issue the break event...
-         //
-         F32 value = pEvent->fValues[0];
-         if (smBreakTable[i].flags & Node::Ranged) {
-            value = (value * 2.0f) - 1.0f;
-            if (smBreakTable[i].flags & Node::Inverted)
-               value *= -1.0f;
-         } else {
-            if (smBreakTable[i].flags & Node::Inverted)
-               value = 1.0f - value;
-         }
-
-         if (smBreakTable[i].flags & Node::HasScale)
-            value *= smBreakTable[i].scaleFactor;
-
-         if (smBreakTable[i].flags & Node::HasDeadZone)
-            if (value >= smBreakTable[i].deadZoneBegin &&
-                value <= smBreakTable[i].deadZoneEnd)
-               value = 0.0f;
-
-         // Ok, we're all set up, call the function.
-         if(smBreakTable[i].consoleFunction)
-         {
-            if ( smBreakTable[i].consoleFunction[0] )
-            {
-               static const char *argv[2];
-               argv[0] = smBreakTable[i].consoleFunction;
-               argv[1] = Con::getFloatArg(value);
-                              
-               if( smBreakTable[i].object )
-               {
-                  // [neo, 5/7/2007 - #2975]
-                  // object above can be deleted in between a make/break and so object will point
-                  // to turfed memory and crash. To keep things simple we just store id as well so
-                  // we can look it up to validate object ref.
-                  if( smBreakTable[i].objectId > 0 && Sim::findObject( smBreakTable[i].objectId ) )
-                     Con::executef(smBreakTable[i].object, 2, argv[0], argv[1]);
-               }
-               else
-                  Con::execute(2, argv);
-            }
-         }
-         else if(smBreakTable[i].breakConsoleCommand)
-         {
-            Con::evaluate(smBreakTable[i].breakConsoleCommand);
-            dFree(smBreakTable[i].breakConsoleCommand);
-         }
-         smBreakTable.erase(i);
-         return true;
-      }
-   }
-
-   return false;
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::handleEvent(const InputEvent* pEvent)
-{
-   // Interate through the ActionMapSet until we get a map that
-   //  handles the event or we run out of maps...
-   //
-   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
-   AssertFatal(pActionMapSet && pActionMapSet->size() != 0,
-               "error, no ActiveMapSet or no global action map...");
-
-   for (SimSet::iterator itr = pActionMapSet->end() - 1;
-        itr > pActionMapSet->begin(); itr--) {
-      ActionMap* pMap = static_cast<ActionMap*>(*itr);
-      if (pMap->processAction(pEvent) == true)
-         return true;
-   }
-
-   return false;
-}
-
-//------------------------------------------------------------------------------
-bool ActionMap::handleEventGlobal(const InputEvent* pEvent)
-{
-   // Interate through the ActionMapSet until we get a map that
-   //  handles the event or we run out of maps...
-   //
-   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
-   AssertFatal(pActionMapSet && pActionMapSet->size() != 0,
-               "error, no ActiveMapSet or no global action map...");
-
-   return ((ActionMap*)pActionMapSet->first())->processAction(pEvent);
-}
-
-//------------------------------------------------------------------------------
-//-------------------------------------- Key code to string mapping
-//                                        TODO: Add most obvious aliases...
-//
-CodeMapping gVirtualMap[] =
-{
-   //-------------------------------------- KEYBOARD EVENTS
-   //
-   { "backspace",     SI_KEY,    KEY_BACKSPACE   },
-   { "tab",           SI_KEY,    KEY_TAB         },
-
-   { "return",        SI_KEY,    KEY_RETURN      },
-   { "enter",         SI_KEY,    KEY_RETURN      },
-
-   { "shift",         SI_KEY,    KEY_SHIFT       },
-   { "ctrl",          SI_KEY,    KEY_CONTROL     },
-   { "alt",           SI_KEY,    KEY_ALT         },
-   { "pause",         SI_KEY,    KEY_PAUSE       },
-   { "capslock",      SI_KEY,    KEY_CAPSLOCK    },
-
-   { "escape",        SI_KEY,    KEY_ESCAPE      },
-
-   { "space",         SI_KEY,    KEY_SPACE       },
-   { "pagedown",      SI_KEY,    KEY_PAGE_DOWN   },
-   { "pageup",        SI_KEY,    KEY_PAGE_UP     },
-   { "end",           SI_KEY,    KEY_END         },
-   { "home",          SI_KEY,    KEY_HOME        },
-   { "left",          SI_KEY,    KEY_LEFT        },
-   { "up",            SI_KEY,    KEY_UP          },
-   { "right",         SI_KEY,    KEY_RIGHT       },
-   { "down",          SI_KEY,    KEY_DOWN        },
-   { "print",         SI_KEY,    KEY_PRINT       },
-   { "insert",        SI_KEY,    KEY_INSERT      },
-   { "delete",        SI_KEY,    KEY_DELETE      },
-   { "help",          SI_KEY,    KEY_HELP        },
-
-   { "win_lwindow",   SI_KEY,    KEY_WIN_LWINDOW },
-   { "win_rwindow",   SI_KEY,    KEY_WIN_RWINDOW },
-   { "win_apps",      SI_KEY,    KEY_WIN_APPS    },
-
-   { "cmd",           SI_KEY,    KEY_ALT         },
-   { "opt",           SI_KEY,    KEY_MAC_OPT     },
-   { "lopt",          SI_KEY,    KEY_MAC_LOPT    },
-   { "ropt",          SI_KEY,    KEY_MAC_ROPT    },
-
-   { "numpad0",       SI_KEY,    KEY_NUMPAD0     },
-   { "numpad1",       SI_KEY,    KEY_NUMPAD1     },
-   { "numpad2",       SI_KEY,    KEY_NUMPAD2     },
-   { "numpad3",       SI_KEY,    KEY_NUMPAD3     },
-   { "numpad4",       SI_KEY,    KEY_NUMPAD4     },
-   { "numpad5",       SI_KEY,    KEY_NUMPAD5     },
-   { "numpad6",       SI_KEY,    KEY_NUMPAD6     },
-   { "numpad7",       SI_KEY,    KEY_NUMPAD7     },
-   { "numpad8",       SI_KEY,    KEY_NUMPAD8     },
-   { "numpad9",       SI_KEY,    KEY_NUMPAD9     },
-   { "numpadmult",    SI_KEY,    KEY_MULTIPLY    },
-   { "numpadadd",     SI_KEY,    KEY_ADD         },
-   { "numpadsep",     SI_KEY,    KEY_SEPARATOR   },
-   { "numpadminus",   SI_KEY,    KEY_SUBTRACT    },
-   { "numpaddecimal", SI_KEY,    KEY_DECIMAL     },
-   { "numpaddivide",  SI_KEY,    KEY_DIVIDE      },
-   { "numpadenter",   SI_KEY,    KEY_NUMPADENTER },
-
-   { "f1",            SI_KEY,    KEY_F1          },
-   { "f2",            SI_KEY,    KEY_F2          },
-   { "f3",            SI_KEY,    KEY_F3          },
-   { "f4",            SI_KEY,    KEY_F4          },
-   { "f5",            SI_KEY,    KEY_F5          },
-   { "f6",            SI_KEY,    KEY_F6          },
-   { "f7",            SI_KEY,    KEY_F7          },
-   { "f8",            SI_KEY,    KEY_F8          },
-   { "f9",            SI_KEY,    KEY_F9          },
-   { "f10",           SI_KEY,    KEY_F10         },
-   { "f11",           SI_KEY,    KEY_F11         },
-   { "f12",           SI_KEY,    KEY_F12         },
-   { "f13",           SI_KEY,    KEY_F13         },
-   { "f14",           SI_KEY,    KEY_F14         },
-   { "f15",           SI_KEY,    KEY_F15         },
-   { "f16",           SI_KEY,    KEY_F16         },
-   { "f17",           SI_KEY,    KEY_F17         },
-   { "f18",           SI_KEY,    KEY_F18         },
-   { "f19",           SI_KEY,    KEY_F19         },
-   { "f20",           SI_KEY,    KEY_F20         },
-   { "f21",           SI_KEY,    KEY_F21         },
-   { "f22",           SI_KEY,    KEY_F22         },
-   { "f23",           SI_KEY,    KEY_F23         },
-   { "f24",           SI_KEY,    KEY_F24         },
-
-   { "numlock",       SI_KEY,    KEY_NUMLOCK     },
-   { "scrolllock",    SI_KEY,    KEY_SCROLLLOCK  },
-
-   { "lshift",        SI_KEY,    KEY_LSHIFT      },
-   { "rshift",        SI_KEY,    KEY_RSHIFT      },
-   { "lcontrol",      SI_KEY,    KEY_LCONTROL    },
-   { "rcontrol",      SI_KEY,    KEY_RCONTROL    },
-   { "lalt",          SI_KEY,    KEY_LALT        },
-   { "ralt",          SI_KEY,    KEY_RALT        },
-   { "tilde",         SI_KEY,    KEY_TILDE       },
-
-   { "minus",         SI_KEY,    KEY_MINUS       },
-   { "equals",        SI_KEY,    KEY_EQUALS      },
-   { "lbracket",      SI_KEY,    KEY_LBRACKET    },
-   { "rbracket",      SI_KEY,    KEY_RBRACKET    },
-   { "backslash",     SI_KEY,    KEY_BACKSLASH   },
-   { "semicolon",     SI_KEY,    KEY_SEMICOLON   },
-   { "apostrophe",    SI_KEY,    KEY_APOSTROPHE  },
-   { "comma",         SI_KEY,    KEY_COMMA       },
-   { "period",        SI_KEY,    KEY_PERIOD      },
-   { "slash",         SI_KEY,    KEY_SLASH       },
-   { "lessthan",      SI_KEY,    KEY_OEM_102     },
-
-   //-------------------------------------- BUTTON EVENTS
-   // Joystick/Mouse buttons
-   { "button0",       SI_BUTTON, KEY_BUTTON0    },
-   { "button1",       SI_BUTTON, KEY_BUTTON1    },
-   { "button2",       SI_BUTTON, KEY_BUTTON2    },
-   { "button3",       SI_BUTTON, KEY_BUTTON3    },
-   { "button4",       SI_BUTTON, KEY_BUTTON4    },
-   { "button5",       SI_BUTTON, KEY_BUTTON5    },
-   { "button6",       SI_BUTTON, KEY_BUTTON6    },
-   { "button7",       SI_BUTTON, KEY_BUTTON7    },
-   { "button8",       SI_BUTTON, KEY_BUTTON8    },
-   { "button9",       SI_BUTTON, KEY_BUTTON9    },
-   { "button10",      SI_BUTTON, KEY_BUTTON10   },
-   { "button11",      SI_BUTTON, KEY_BUTTON11   },
-   { "button12",      SI_BUTTON, KEY_BUTTON12   },
-   { "button13",      SI_BUTTON, KEY_BUTTON13   },
-   { "button14",      SI_BUTTON, KEY_BUTTON14   },
-   { "button15",      SI_BUTTON, KEY_BUTTON15   },
-   { "button16",      SI_BUTTON, KEY_BUTTON16   },
-   { "button17",      SI_BUTTON, KEY_BUTTON17   },
-   { "button18",      SI_BUTTON, KEY_BUTTON18   },
-   { "button19",      SI_BUTTON, KEY_BUTTON19   },
-   { "button20",      SI_BUTTON, KEY_BUTTON20   },
-   { "button21",      SI_BUTTON, KEY_BUTTON21   },
-   { "button22",      SI_BUTTON, KEY_BUTTON22   },
-   { "button23",      SI_BUTTON, KEY_BUTTON23   },
-   { "button24",      SI_BUTTON, KEY_BUTTON24   },
-   { "button25",      SI_BUTTON, KEY_BUTTON25   },
-   { "button26",      SI_BUTTON, KEY_BUTTON26   },
-   { "button27",      SI_BUTTON, KEY_BUTTON27   },
-   { "button28",      SI_BUTTON, KEY_BUTTON28   },
-   { "button29",      SI_BUTTON, KEY_BUTTON29   },
-   { "button30",      SI_BUTTON, KEY_BUTTON30   },
-   { "button31",      SI_BUTTON, KEY_BUTTON31   },
-
-   //-------------------------------------- MOVE EVENTS
-   // Mouse/Joystick axes:
-   { "xaxis",         SI_MOVE,   SI_XAXIS       },
-   { "yaxis",         SI_MOVE,   SI_YAXIS       },
-   { "zaxis",         SI_MOVE,   SI_ZAXIS       },
-   { "rxaxis",        SI_MOVE,   SI_RXAXIS      },
-   { "ryaxis",        SI_MOVE,   SI_RYAXIS      },
-   { "rzaxis",        SI_MOVE,   SI_RZAXIS      },
-   { "slider",        SI_MOVE,   SI_SLIDER      },
-
-   //-------------------------------------- POV EVENTS
-   // Joystick POV:
-   { "xpov",          SI_POV,    SI_XPOV         },
-   { "ypov",          SI_POV,    SI_YPOV         },
-   { "upov",          SI_POV,    SI_UPOV         },
-   { "dpov",          SI_POV,    SI_DPOV         },
-   { "lpov",          SI_POV,    SI_LPOV         },
-   { "rpov",          SI_POV,    SI_RPOV         },
-   { "xpov2",         SI_POV,    SI_XPOV2        },
-   { "ypov2",         SI_POV,    SI_YPOV2        },
-   { "upov2",         SI_POV,    SI_UPOV2        },
-   { "dpov2",         SI_POV,    SI_DPOV2        },
-   { "lpov2",         SI_POV,    SI_LPOV2        },
-   { "rpov2",         SI_POV,    SI_RPOV2        },
-
-   #if defined( TORQUE_OS_WIN32 ) || defined( TORQUE_OS_XENON )
-   //-------------------------------------- XINPUT EVENTS
-   // Controller connect / disconnect:
-   { "connect",       XI_BUTTON, XI_CONNECT     },
-   
-   // L & R Thumbsticks:
-   { "thumblx",       XI_AXIS,   XI_THUMBLX     },
-   { "thumbly",       XI_AXIS,   XI_THUMBLY     },
-   { "thumbrx",       XI_AXIS,   XI_THUMBRX     },
-   { "thumbry",       XI_AXIS,   XI_THUMBRY     },
-
-   // L & R Triggers:
-   { "triggerl",      XI_AXIS,   XI_LEFT_TRIGGER  },
-   { "triggerr",      XI_AXIS,   XI_RIGHT_TRIGGER },
-
-   // DPAD Buttons:
-   { "dpadu",         XI_BUTTON, SI_UPOV     },
-   { "dpadd",         XI_BUTTON, SI_DPOV   },
-   { "dpadl",         XI_BUTTON, SI_LPOV   },
-   { "dpadr",         XI_BUTTON, SI_RPOV  },
-
-   // START & BACK Buttons:
-   { "btn_start",     XI_BUTTON, XI_START       },
-   { "btn_back",      XI_BUTTON, XI_BACK        },
-
-   // L & R Thumbstick Buttons:
-   { "btn_lt",        XI_BUTTON, XI_LEFT_THUMB  },
-   { "btn_rt",        XI_BUTTON, XI_RIGHT_THUMB },
-
-   // L & R Shoulder Buttons:
-   { "btn_l",         XI_BUTTON, XI_LEFT_SHOULDER  },
-   { "btn_r",         XI_BUTTON, XI_RIGHT_SHOULDER },
-
-   // Primary buttons:
-   { "btn_a",         XI_BUTTON, XI_A           },
-   { "btn_b",         XI_BUTTON, XI_B           },
-   { "btn_x",         XI_BUTTON, XI_X           },
-   { "btn_y",         XI_BUTTON, XI_Y           },
-#endif
-
-
-   //-------------------------------------- MOTION EVENTS
-   // Accelerometer/Gyroscope axes:
-   { "accelx",        SI_MOTION,    SI_ACCELX    },
-   { "accely",        SI_MOTION,    SI_ACCELY    },
-   { "accelz",        SI_MOTION,    SI_ACCELZ    },
-   { "gravityx",      SI_MOTION,    SI_GRAVX     },
-   { "gravityy",      SI_MOTION,    SI_GRAVY     },
-   { "gravityz",      SI_MOTION,    SI_GRAVZ     },
-   { "gyrox",         SI_MOTION,    SI_GYROX     },
-   { "gyroy",         SI_MOTION,    SI_GYROY     },
-   { "gyroz",         SI_MOTION,    SI_GYROZ     },
-   { "yaw",           SI_MOTION,    SI_YAW       },
-   { "pitch",         SI_MOTION,    SI_PITCH     },
-   { "roll",          SI_MOTION,    SI_ROLL      },
-
-   //-------------------------------------- TOUCH EVENTS
-   // Touch events:
-   { "touchdown",     SI_TOUCH,    SI_TOUCHDOWN  },
-   { "touchup",       SI_TOUCH,    SI_TOUCHUP    },
-   { "touchmove",     SI_TOUCH,    SI_TOUCHMOVE  },
-
-   //-------------------------------------- GESTURE EVENTS
-   // Preset gesture events:
-   { "circleGesture",      SI_GESTURE,  SI_CIRCLE_GESTURE    },
-   { "swipeGesture",       SI_GESTURE,  SI_SWIPE_GESTURE     },
-   { "screenTapGesture",   SI_GESTURE,  SI_SCREENTAP_GESTURE },
-   { "keyTapGesture",      SI_GESTURE,  SI_KEYTAP_GESTURE    },
-   { "pinchGesture",       SI_GESTURE,  SI_PINCH_GESTURE     },
-   { "scaleGesture",       SI_GESTURE,  SI_SCALE_GESTURE     },
-
-   //-------------------------------------- GESTURE EVENTS
-   // Preset gesture events:
-   { "leapHandAxis",    SI_LEAP,     LM_HANDAXIS    },
-   { "leapHandPos",     SI_LEAP,     LM_HANDPOS     },
-   { "leapHandRot",     SI_LEAP,     LM_HANDROT     },
-   { "leapFingerPos",   SI_LEAP,     LM_FINGERPOS   },
-   
-   //-------------------------------------- MISCELLANEOUS EVENTS
-   //
-   { "anykey",        SI_KEY,      KEY_ANYKEY },
-   { "nomatch",       SI_UNKNOWN,  0xFFFFFFFF }
-};
-
-AsciiMapping gAsciiMap[] =
-{
-   //--- KEYBOARD EVENTS
-   //
-   { "space",           0x0020 },
-   //{ "exclamation",     0x0021 },
-   { "doublequote",     0x0022 },
-   //{ "pound",           0x0023 },
-   //{ "ampersand",       0x0026 },
-   { "apostrophe",      0x0027 },
-   //{ "lparen",          0x0028 },
-   //{ "rparen",          0x0029 },
-   { "comma",           0x002c },
-   { "minus",           0x002d },
-   { "period",          0x002e },
-   //{ "slash",           0x002f },
-   //{ "colon",           0x003a },
-   //{ "semicolon",       0x003b },
-   //{ "lessthan",        0x003c },
-   //{ "equals",          0x003d },
-   //{ "morethan",        0x003e },
-   //{ "lbracket",        0x005b },
-   { "backslash",       0x005c },
-   //{ "rbracket",        0x005d },
-   //{ "circumflex",      0x005e },
-   //{ "underscore",      0x005f },
-   { "grave",           0x0060 },
-   //{ "tilde",           0x007e },
-   //{ "vertbar",         0x007c },
-   //{ "exclamdown",      0x00a1 },
-   //{ "cent",            0x00a2 },
-   //{ "sterling",        0x00a3 },
-   //{ "currency",        0x00a4 },
-   //{ "brokenbar",       0x00a6 },
-   //{ "ring",            0x00b0 },
-   //{ "plusminus",       0x00b1 },
-   { "super2",          0x00b2 },
-   { "super3",          0x00b3 },
-   { "acute",           0x00b4 },
-   //{ "mu",              0x00b5 },
-   //{ "ordmasculine",    0x00ba },
-   //{ "questiondown",    0x00bf },
-   //{ "gemandbls",       0x00df },
-   //{ "agrave",          0x00e0 },
-   //{ "aacute",          0x00e1 },
-   //{ "acircumflex",     0x00e2 },
-   //{ "atilde",          0x00e3 },
-   //{ "adieresis",       0x00e4 },
-   //{ "aring",           0x00e5 },
-   //{ "ae",              0x00e6 },
-   //{ "ccedille",        0x00e7 },
-   //{ "egrave",          0x00e8 },
-   //{ "eacute",          0x00e9 },
-   //{ "ecircumflex",     0x00ea },
-   //{ "edieresis",       0x00eb },
-   //{ "igrave",          0x00ec },
-   //{ "iacute",          0x00ed },
-   //{ "icircumflex",     0x00ee },
-   //{ "idieresis",       0x00ef },
-   //{ "ntilde",          0x00f1 },
-   //{ "ograve",          0x00f2 },
-   //{ "oacute",          0x00f3 },
-   //{ "ocircumflex",     0x00f4 },
-   //{ "otilde",          0x00f5 },
-   //{ "odieresis",       0x00f6 },
-   //{ "divide",          0x00f7 },
-   //{ "oslash",          0x00f8 },
-   //{ "ugrave",          0x00f9 },
-   //{ "uacute",          0x00fa },
-   //{ "ucircumflex",     0x00fb },
-   //{ "udieresis",       0x00fc },
-   //{ "ygrave",          0x00fd },
-   //{ "thorn",           0x00fe },
-   //{ "ydieresis",       0x00ff },
-   { "nomatch",         0xFFFF }
-};
-
-
-////Device Event Types
-//#define SI_UNKNOWN   0x01
-//#define SI_BUTTON    0x02
-//#define SI_POV       0x03
-//#define SI_XPOV      0x04
-//#define SI_YPOV      0x05
-//#define SI_UPOV      0x06
-//#define SI_DPOV      0x07
-//#define SI_LPOV      0x08
-//#define SI_RPOV      0x09
-//#define SI_KEY       0x0A
-//#define SI_XAXIS     0x0B
-//#define SI_YAXIS     0x0C
-//#define SI_ZAXIS     0x0D
-//#define SI_RXAXIS    0x0E
-//#define SI_RYAXIS    0x0F
-//#define SI_RZAXIS    0x10
-//#define SI_SLIDER    0x11
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "input/actionMap.h"
+#include "platform/event.h"
+#include "console/console.h"
+#include "platform/platform.h"
+#include "platform/platformInput.h"
+#include "platform/platformAssert.h"
+#include "io/fileStream.h"
+#include "io/resource/resourceManager.h"
+
+// Script bindings.
+#include "actionMap_ScriptBinding.h"
+
+#define CONST_E 2.7182818284590452353602874f
+
+IMPLEMENT_CONOBJECT(ActionMap);
+
+// This is used for determing keys that have ascii codes for the foreign keyboards. IsAlpha doesn't work on foreign keys.
+#define dIsDecentChar(c) (((char(0xa0) <= (c)) && ((c) <= char(0xff))) || (( char(0x21) <= (c)) && ((c) <= char(0x7e))) || (( char(0x91) <= (c)) && ((c) <= char(0x92))))
+
+struct CodeMapping
+{
+   const char* pDescription;
+   U8  type;
+   U32 code;
+};
+
+struct AsciiMapping
+{
+   const char* pDescription;
+   U16         asciiCode;
+};
+
+extern CodeMapping gVirtualMap[];
+extern AsciiMapping gAsciiMap[];
+
+//------------------------------------------------------------------------------
+//-------------------------------------- Action maps
+//
+Vector<ActionMap::BreakEntry> ActionMap::smBreakTable(__FILE__, __LINE__);
+
+
+//------------------------------------------------------------------------------
+ActionMap::ActionMap()
+{
+   VECTOR_SET_ASSOCIATION(mDeviceMaps);
+}
+
+//------------------------------------------------------------------------------
+ActionMap::~ActionMap()
+{
+   for (U32 i = 0; i < (U32)mDeviceMaps.size(); i++)
+      delete mDeviceMaps[i];
+   mDeviceMaps.clear();
+}
+
+//------------------------------------------------------------------------------
+ActionMap::DeviceMap::~DeviceMap()
+{
+   for(U32 i = 0; i < (U32)nodeMap.size(); i++)
+   {
+      dFree(nodeMap[i].makeConsoleCommand);
+      dFree(nodeMap[i].breakConsoleCommand);
+   }
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::onAdd()
+{
+   if (Parent::onAdd() == false)
+      return false;
+
+   Sim::getActionMapGroup()->addObject(this);
+
+   return true;
+}
+
+//--------------------------------------------------------------------------
+void ActionMap::dumpActionMap(const char* fileName, const bool append) const
+{
+   if (fileName != NULL) {
+      // Dump the deletion, and creation script commands, followed by all the binds
+      //  to a script.
+
+      FileStream iostrm;
+      if ( !ResourceManager->openFileForWrite( iostrm, fileName, append ? FileStream::WriteAppend : FileStream::Write ) )
+      {
+         Con::errorf( "Unable to open file '%s' for writing.", fileName );
+         return;
+      }
+
+      char lineBuffer[1024];
+      if ( append )
+         iostrm.setPosition( iostrm.getStreamSize() );
+      else
+      {
+         // IMPORTANT -- do NOT change the following line, it identifies the file as an input map file
+         dStrcpy( lineBuffer, "// Torque Input Map File\n" );
+         iostrm.write( dStrlen( lineBuffer ), lineBuffer );
+      }
+
+      dSprintf(lineBuffer, 1023, "if (isObject(%s)) %s.delete();\n"
+                                 "new ActionMap(%s);\n", getName(), getName(), getName());
+      iostrm.write(dStrlen(lineBuffer), lineBuffer);
+
+      // Dump all the binds to the console...
+      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
+         const DeviceMap* pDevMap = mDeviceMaps[i];
+
+         char devbuffer[32];
+         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);
+
+         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
+            const Node& rNode = pDevMap->nodeMap[j];
+
+            const char* pModifierString = getModifierString(rNode.modifiers);
+
+            char objectbuffer[64];
+            if (getKeyString(rNode.action, objectbuffer) == false)
+               continue;
+
+            const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind";
+
+            dSprintf(lineBuffer, 1023, "%s.%s(%s, \"%s%s\"",
+                                        getName(),
+                                        command,
+                                        devbuffer,
+                                        pModifierString, objectbuffer);
+
+            if (rNode.flags & (Node::HasScale|Node::HasDeadZone|Node::Ranged|Node::Inverted)) {
+               char buff[10];
+               U32 curr = 0;
+               buff[curr++] = ',';
+               buff[curr++] = ' ';
+               if (rNode.flags & Node::HasScale)
+                  buff[curr++] = 'S';
+               if (rNode.flags & Node::Ranged)
+                  buff[curr++] = 'R';
+               if (rNode.flags & Node::HasDeadZone)
+                  buff[curr++] = 'D';
+               if (rNode.flags & Node::Inverted)
+                  buff[curr++] = 'I';
+               buff[curr] = '\0';
+
+               dStrcat(lineBuffer, buff);
+            }
+
+            if (rNode.flags & Node::HasDeadZone) {
+               char buff[64];
+               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
+               dStrcat(lineBuffer, buff);
+            }
+
+            if (rNode.flags & Node::HasScale) {
+               char buff[64];
+               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
+               dStrcat(lineBuffer, buff);
+            }
+
+            if (rNode.flags & Node::BindCmd) {
+               if (rNode.makeConsoleCommand) {
+                  dStrcat(lineBuffer, ", \"");
+                  U32 pos = dStrlen(lineBuffer);
+                  expandEscape(lineBuffer + pos, rNode.makeConsoleCommand);
+                  dStrcat(lineBuffer, "\"");
+               } else {
+                  dStrcat(lineBuffer, ", \"\"");
+               }
+               if (rNode.breakConsoleCommand) {
+                  dStrcat(lineBuffer, ", \"");
+                  U32 pos = dStrlen(lineBuffer);
+                  expandEscape(lineBuffer + pos, rNode.breakConsoleCommand);
+                  dStrcat(lineBuffer, "\"");
+               }
+               else
+                  dStrcat(lineBuffer, ", \"\"");
+            } else {
+               dStrcat(lineBuffer, ", ");
+               dStrcat(lineBuffer, rNode.consoleFunction);
+            }
+
+            dStrcat(lineBuffer, ");\n");
+            iostrm.write(dStrlen(lineBuffer), lineBuffer);
+         }
+      }
+
+      iostrm.close();
+   }
+   else {
+      // Dump all the binds to the console...
+      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
+         const DeviceMap* pDevMap = mDeviceMaps[i];
+
+         char devbuffer[32];
+         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);
+
+         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
+            const Node& rNode = pDevMap->nodeMap[j];
+
+            const char* pModifierString = getModifierString(rNode.modifiers);
+
+            char keybuffer[64];
+            if (getKeyString(rNode.action, keybuffer) == false)
+               continue;
+
+            const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind";
+
+            char finalBuffer[1024];
+            dSprintf(finalBuffer, 1023, "%s.%s(%s, \"%s%s\"",
+                                        getName(),
+                                        command,
+                                        devbuffer,
+                                        pModifierString, keybuffer);
+
+            if (rNode.flags & (Node::HasScale|Node::HasDeadZone|Node::Ranged|Node::Inverted)) {
+               char buff[10];
+               U32 curr = 0;
+               buff[curr++] = ',';
+               buff[curr++] = ' ';
+               if (rNode.flags & Node::HasScale)
+                  buff[curr++] = 'S';
+               if (rNode.flags & Node::Ranged)
+                  buff[curr++] = 'R';
+               if (rNode.flags & Node::HasDeadZone)
+                  buff[curr++] = 'D';
+               if (rNode.flags & Node::Inverted)
+                  buff[curr++] = 'I';
+               buff[curr] = '\0';
+
+               dStrcat(finalBuffer, buff);
+            }
+
+            if (rNode.flags & Node::HasDeadZone) {
+               char buff[64];
+               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
+               dStrcat(finalBuffer, buff);
+            }
+
+            if (rNode.flags & Node::HasScale) {
+               char buff[64];
+               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
+               dStrcat(finalBuffer, buff);
+            }
+
+            if (rNode.flags & Node::BindCmd) {
+               if (rNode.makeConsoleCommand) {
+                  dStrcat(finalBuffer, ", \"");
+                  dStrcat(finalBuffer, rNode.makeConsoleCommand);
+                  dStrcat(finalBuffer, "\"");
+               } else {
+                  dStrcat(finalBuffer, ", \"\"");
+               }
+               if (rNode.breakConsoleCommand) {
+                  dStrcat(finalBuffer, ", \"");
+                  dStrcat(finalBuffer, rNode.breakConsoleCommand);
+                  dStrcat(finalBuffer, "\"");
+               }
+               else
+                  dStrcat(finalBuffer, ", \"\"");
+            } else {
+               dStrcat(finalBuffer, ", ");
+               dStrcat(finalBuffer, rNode.consoleFunction);
+            }
+
+            dStrcat(finalBuffer, ");");
+            Con::printf(finalBuffer);
+         }
+      }
+   }
+}
+
+//--------------------------------------------------------------------------
+bool ActionMap::createEventDescriptor(const char* pEventString, EventDescriptor* pDescriptor)
+{
+   char copyBuffer[256];
+   dStrcpy(copyBuffer, pEventString);
+
+   // Do we have modifiers?
+   char* pSpace = dStrchr(copyBuffer, ' ');
+   char* pObjectString;
+   if (pSpace != NULL) {
+      // Yes.  Parse them out...
+      //
+      pDescriptor->flags = 0;
+      pObjectString      = pSpace + 1;
+      pSpace[0]          = '\0';
+
+      char* pModifier = dStrtok(copyBuffer, "-");
+      while (pModifier != NULL) {
+         if (dStricmp(pModifier, "shift") == 0) {
+            pDescriptor->flags |= SI_SHIFT;
+         } else if (dStricmp(pModifier, "ctrl") == 0) {
+            pDescriptor->flags |= SI_CTRL;
+         } else if (dStricmp(pModifier, "alt") == 0) {
+            pDescriptor->flags |= SI_ALT;
+         } else if (dStricmp(pModifier, "cmd") == 0) {
+            pDescriptor->flags |= SI_ALT;
+         } else if (dStricmp(pModifier, "opt") == 0) {
+            pDescriptor->flags |= SI_MAC_OPT;
+         }
+
+         pModifier = dStrtok(NULL, "-");
+      }
+   } else {
+      // No.
+      pDescriptor->flags = 0;
+      pObjectString      = copyBuffer;
+   }
+
+   // Now we need to map the key string to the proper KEY code from event.h
+   //
+   AssertFatal(dStrlen(pObjectString) != 0, "Error, no key was specified!");
+
+   if (dStrlen(pObjectString) == 1)
+   {
+      if (dIsDecentChar(*pObjectString)) // includes foreign chars
+      {
+         U16 asciiCode = (*pObjectString);
+         // clear out the FF in upper 8bits for foreign keys??
+         asciiCode &= 0xFF;
+         U16 keyCode = Input::getKeyCode(asciiCode);
+         if ( keyCode >= KEY_0 )
+         {
+            pDescriptor->eventType = SI_KEY;
+            pDescriptor->eventCode = keyCode;
+            return true;
+         }
+         else if (dIsalpha(*pObjectString) == true)
+         {
+            pDescriptor->eventType = SI_KEY;
+            pDescriptor->eventCode = KEY_A+dTolower(*pObjectString)-'a';
+            return true;
+         }
+         else if (dIsdigit(*pObjectString) == true)
+         {
+            pDescriptor->eventType = SI_KEY;
+            pDescriptor->eventCode = KEY_0+(*pObjectString)-'0';
+            return true;
+         }
+      }
+      return false;
+   }
+   else
+   {
+      pDescriptor->eventCode = 0;
+      // Gotta search through the Ascii table...
+      for (U16 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++)
+      {
+         if (dStricmp(pObjectString, gAsciiMap[i].pDescription) == 0)
+         {
+            U16 asciiCode = gAsciiMap[i].asciiCode;
+            U16 keyCode   = Input::getKeyCode(asciiCode);
+            if ( keyCode >= KEY_0 )
+            {
+               pDescriptor->eventType = SI_KEY;
+               pDescriptor->eventCode = keyCode;
+               return(true);
+
+            }
+            else
+            {
+               break;
+            }
+         }
+      }
+      // Didn't find an ascii match. Check the virtual map table
+      for (U32 j = 0; gVirtualMap[j].code != 0xFFFFFFFF; j++)
+      {
+         if (dStricmp(pObjectString, gVirtualMap[j].pDescription) == 0)
+         {
+            pDescriptor->eventType = gVirtualMap[j].type;
+            pDescriptor->eventCode = gVirtualMap[j].code;
+            return true;
+         }
+      }
+   }
+   return false;
+}
+
+//------------------------------------------------------------------------------
+ActionMap::Node* ActionMap::getNode(const U32 inDeviceType, const U32 inDeviceInst,
+                   const U32 inModifiers,  const U32 inAction,SimObject* object /*= NULL*/)
+{
+   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
+   //
+   DeviceMap* pDeviceMap = NULL;
+   U32 i;
+   for (i = 0; i < (U32)mDeviceMaps.size(); i++) 
+   {
+      if (mDeviceMaps[i]->deviceType == inDeviceType &&
+          mDeviceMaps[i]->deviceInst == inDeviceInst) {
+         pDeviceMap = mDeviceMaps[i];
+         break;
+      }
+   }
+   if (pDeviceMap == NULL) 
+   {
+      mDeviceMaps.increment();
+      mDeviceMaps.last() = new DeviceMap;
+      pDeviceMap = mDeviceMaps.last();
+
+      pDeviceMap->deviceInst = inDeviceInst;
+      pDeviceMap->deviceType = inDeviceType;
+   }
+
+   for (i = 0; i < (U32)pDeviceMap->nodeMap.size(); i++) 
+   {
+      if (pDeviceMap->nodeMap[i].modifiers == inModifiers &&
+          pDeviceMap->nodeMap[i].action    == inAction &&
+          ( (object != NULL) ? object == pDeviceMap->nodeMap[i].object : true )) // Check for an object match if the object exists 
+      {
+         return &pDeviceMap->nodeMap[i];
+      }
+   }
+
+   // If we're here, the node doesn't exist.  create it.
+   pDeviceMap->nodeMap.increment();
+
+   Node* pRetNode = &pDeviceMap->nodeMap.last();
+   pRetNode->modifiers = inModifiers;
+   pRetNode->action    = inAction;
+
+   pRetNode->flags         = 0;
+   pRetNode->deadZoneBegin = 0.0;
+   pRetNode->deadZoneEnd   = 0.0;
+   pRetNode->scaleFactor   = 1.0;
+
+   pRetNode->consoleFunction = NULL;
+   pRetNode->makeConsoleCommand = NULL;
+   pRetNode->breakConsoleCommand = NULL;
+
+   //[neob, 5/7/2007 - #2975]
+   pRetNode->object = 0;
+
+   return pRetNode;
+}
+
+//------------------------------------------------------------------------------
+void ActionMap::removeNode(const U32 inDeviceType, const U32 inDeviceInst, const U32 inModifiers, const U32 inAction, SimObject* object /*= NULL*/)
+{
+   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
+   //
+   DeviceMap* pDeviceMap = NULL;
+   U32 i;
+   for (i = 0; i < (U32)mDeviceMaps.size(); i++) {
+      if (mDeviceMaps[i]->deviceType == inDeviceType &&
+          mDeviceMaps[i]->deviceInst == inDeviceInst) {
+         pDeviceMap = mDeviceMaps[i];
+         break;
+      }
+   }
+
+   if (pDeviceMap == NULL)
+      return;
+
+   U32 realMods = inModifiers;
+   if (realMods & SI_SHIFT)
+      realMods |= SI_SHIFT;
+   if (realMods & SI_CTRL)
+      realMods |= SI_CTRL;
+   if (realMods & SI_ALT)
+      realMods |= SI_ALT;
+   if (realMods & SI_MAC_OPT)
+      realMods |= SI_MAC_OPT;
+
+   for (i = 0; i < (U32)pDeviceMap->nodeMap.size(); i++) {
+      if (pDeviceMap->nodeMap[i].modifiers == realMods &&
+          pDeviceMap->nodeMap[i].action    == inAction &&
+          ( (object != NULL) ? object == pDeviceMap->nodeMap[i].object : true )) 
+      {
+          dFree(pDeviceMap->nodeMap[i].makeConsoleCommand);
+          dFree(pDeviceMap->nodeMap[i].breakConsoleCommand);
+          pDeviceMap->nodeMap.erase(i);
+      }
+   }
+}
+
+//------------------------------------------------------------------------------
+const ActionMap::Node* ActionMap::findNode(const U32 inDeviceType, const U32 inDeviceInst,
+                    const U32 inModifiers,  const U32 inAction)
+{
+   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
+   //
+   DeviceMap* pDeviceMap = NULL;
+   U32 i;
+   for (i = 0; i < (U32)mDeviceMaps.size(); i++)
+   {
+      if (mDeviceMaps[i]->deviceType == inDeviceType && mDeviceMaps[i]->deviceInst == inDeviceInst)
+      {
+         pDeviceMap = mDeviceMaps[i];
+         break;
+      }
+   }
+
+   if (pDeviceMap == NULL)
+      return NULL;
+
+   U32 realMods = inModifiers;
+   if (realMods & SI_SHIFT)
+      realMods |= SI_SHIFT;
+   if (realMods & SI_CTRL)
+      realMods |= SI_CTRL;
+   if (realMods & SI_ALT)
+      realMods |= SI_ALT;
+   if (realMods & SI_MAC_OPT)
+      realMods |= SI_MAC_OPT;
+
+   for (i = 0; i < (U32)pDeviceMap->nodeMap.size(); i++)
+   {
+      if (pDeviceMap->nodeMap[i].action == KEY_ANYKEY && pDeviceMap->nodeMap[i].modifiers == realMods && dIsDecentChar(inAction))
+         return &pDeviceMap->nodeMap[i];
+      else if (pDeviceMap->nodeMap[i].modifiers == realMods && pDeviceMap->nodeMap[i].action    == inAction)
+         return &pDeviceMap->nodeMap[i];
+   }
+
+   return NULL;
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::findBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
+{
+   devMapIndex = 0;
+   nodeIndex = 0;
+   return nextBoundNode( function, devMapIndex, nodeIndex );
+}
+
+bool ActionMap::nextBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
+{
+   // Loop through all of the existing nodes to find the one mapped to the
+   // given function:
+   for ( U32 i = devMapIndex; i < (U32)mDeviceMaps.size(); i++ )
+   {
+      const DeviceMap* dvcMap = mDeviceMaps[i];
+
+      for ( U32 j = nodeIndex; j < (U32)dvcMap->nodeMap.size(); j++ )
+      {
+         const Node* node = &dvcMap->nodeMap[j];
+         if ( !( node->flags & Node::BindCmd ) && ( dStricmp( function, node->consoleFunction ) == 0 ) )
+         {
+            devMapIndex = i;
+            nodeIndex = j;
+            return( true );
+         }
+      }
+
+      nodeIndex = 0;
+   }
+
+   return( false );
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::processUnbind(const char *device, const char *action, SimObject* object /*= NULL*/)
+{
+   U32 deviceType;
+   U32 deviceInst;
+
+   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
+      return false;
+   EventDescriptor eventDescriptor;
+   if (!createEventDescriptor(action, &eventDescriptor))
+      return false;
+
+   removeNode(deviceType, deviceInst, eventDescriptor.flags,eventDescriptor.eventCode, object);
+   return true;
+}
+
+//------------------------------------------------------------------------------
+// This function is for the use of the control remapper.
+// It will only check against the console function (since all remappable commands are
+// bound using bind and not bindCmd).
+//
+const char* ActionMap::getBinding( const char* command )
+{
+   char* returnString = Con::getReturnBuffer( 1024 );
+   returnString[0] = 0;
+
+   char buffer[256];
+   char deviceBuffer[32];
+   char keyBuffer[64];
+ 
+   U32 devMapIndex = 0, nodeIndex = 0;
+   while ( nextBoundNode( command, devMapIndex, nodeIndex ) )
+   {
+      const DeviceMap* deviceMap = mDeviceMaps[devMapIndex];
+
+      if ( getDeviceName( deviceMap->deviceType, deviceMap->deviceInst, deviceBuffer ) )
+      {
+         const Node* node = &deviceMap->nodeMap[nodeIndex];
+         const char* modifierString = getModifierString( node->modifiers );
+
+         if ( getKeyString( node->action, keyBuffer ) )
+         {
+            dSprintf( buffer, sizeof( buffer ), "%s\t%s%s", deviceBuffer, modifierString, keyBuffer );
+            if ( returnString[0] )
+               dStrcat( returnString, "\t" );
+            dStrcat( returnString, buffer );
+         }
+      }
+
+      ++nodeIndex;
+   }
+
+   return returnString;
+}
+
+//------------------------------------------------------------------------------
+// This function is for the use of the control remapper.
+// The intent of this function is to determine if the given event descriptor is already
+// bound in this action map.  If so, this function returns the command it is bound to.
+// If not, it returns NULL.
+//
+const char* ActionMap::getCommand( const char* device, const char* action )
+{
+    U32 deviceType;
+    U32 deviceInst;
+    if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
+    {
+        EventDescriptor eventDescriptor;
+        if ( createEventDescriptor( action, &eventDescriptor ) )
+        {
+            const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
+            if ( mapNode )
+            {
+                if ( mapNode->flags & Node::BindCmd )
+                {
+                    S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2;
+                    char* returnString = Con::getReturnBuffer( bufferLen );
+                    dSprintf( returnString, bufferLen, "%s\t%s",
+                            ( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ),
+                            ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) );					
+                    return( returnString );
+                }					
+                else
+                    return( mapNode->consoleFunction );					
+            }
+        }
+    }
+
+    return( "" );
+}
+
+//------------------------------------------------------------------------------
+// This function returns whether or not the mapping specified is inverted.
+// Obviously, this should only be used for axes.
+bool ActionMap::isInverted( const char* device, const char* action )
+{
+    U32 deviceType;
+    U32 deviceInst;
+    if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
+    {
+        EventDescriptor eventDescriptor;
+        if ( createEventDescriptor( action, &eventDescriptor ) )
+        {
+            const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
+            if ( mapNode )
+                return( mapNode->flags & Node::Inverted );
+        }
+    }
+
+    Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
+    return( false );
+}
+
+//------------------------------------------------------------------------------
+F32 ActionMap::getScale( const char* device, const char* action )
+{
+    U32 deviceType;
+    U32 deviceInst;
+    if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
+    {
+        EventDescriptor eventDescriptor;
+        if ( createEventDescriptor( action, &eventDescriptor ) )
+        {
+            const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
+            if ( mapNode )
+            {
+               if ( mapNode->flags & Node::HasScale )
+                   return( mapNode->scaleFactor );
+            else
+               return( 1.0f );
+         }
+        }
+    }
+
+    Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
+    return( 1.0f );
+}
+
+//------------------------------------------------------------------------------
+const char* ActionMap::getDeadZone( const char* device, const char* action )
+{
+    U32 deviceType;
+    U32 deviceInst;
+    if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
+    {
+        EventDescriptor eventDescriptor;
+        if ( createEventDescriptor( action, &eventDescriptor ) )
+        {
+            const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
+            if ( mapNode )
+            {
+               if ( mapNode->flags & Node::HasDeadZone )
+               {
+                   char buf[64];
+                   dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd );
+                   char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 );
+                   dStrcpy( returnString, buf );
+                   return( returnString );
+                }
+                else
+                   return( "0 0" );				   		
+            }
+        }
+    }
+
+    Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
+    return( "" );
+}
+
+//------------------------------------------------------------------------------
+const char* ActionMap::buildActionString( const InputEvent* event )
+{
+    const char* modifierString = getModifierString( event->modifier );
+
+    char objectBuffer[64];
+    if ( !getKeyString( event->objInst, objectBuffer ) )
+        return( "" );
+
+    U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2;	
+    char* returnString = Con::getReturnBuffer( returnLen );
+    dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer );
+    return( returnString );
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::getDeviceTypeAndInstance(const char *pDeviceName, U32 &deviceType, U32 &deviceInstance)
+{
+   U32 offset = 0;
+    
+   if (dStrnicmp(pDeviceName, "keyboard", dStrlen("keyboard")) == 0)
+   {
+      deviceType = KeyboardDeviceType;
+      offset = dStrlen("keyboard");
+   } 
+   else if (dStrnicmp(pDeviceName, "mouse", dStrlen("mouse")) == 0) 
+   {
+      deviceType = MouseDeviceType;
+      offset = dStrlen("mouse");
+   } 
+   else if (dStrnicmp(pDeviceName, "joystick", dStrlen("joystick")) == 0) 
+   {
+      deviceType = JoystickDeviceType;
+      offset = dStrlen("joystick");
+   } 
+   else if (dStrnicmp(pDeviceName, "accelerometer", dStrlen("accelerometer")) == 0) 
+   {
+      deviceType = AccelerometerDeviceType;
+      offset = dStrlen("accelerometer");
+   }
+   else if (dStrnicmp(pDeviceName, "gyroscope", dStrlen("gyroscope")) == 0)
+   {
+       deviceType = GyroscopeDeviceType;
+       offset = dStrlen("gyroscope");
+   }
+   else if (dStrnicmp(pDeviceName, "touchdevice", dStrlen("touchdevice")) == 0)
+   {
+       deviceType = ScreenTouchDeviceType;
+       offset = dStrlen("touchdevice");
+   }
+    else if (dStrnicmp(pDeviceName, "gamepad", dStrlen("gamepad")) == 0)
+   {
+      deviceType = GamepadDeviceType;
+      offset     = dStrlen("gamepad");
+   }
+   else if (dStrnicmp(pDeviceName, "leapdevice", dStrlen("leapdevice")) == 0)
+   {
+       deviceType = LeapMotionDeviceType;
+       offset = dStrlen("leapdevice");
+   }
+   else
+      return false;
+    
+   if (dStrlen(pDeviceName) > offset) 
+   {
+      const char* pInst = pDeviceName + offset;
+      S32 instNum = dAtoi(pInst);
+      
+      if (instNum < 0)
+         deviceInstance = 0;
+      else
+         deviceInstance = instNum;
+   } 
+   else 
+       deviceInstance = 0;
+    
+   return true;
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::getDeviceName(const U32 deviceType, const U32 deviceInstance, char* buffer)
+{
+   switch (deviceType)
+   {
+     case KeyboardDeviceType:
+      dStrcpy(buffer, "keyboard");
+      break;
+
+     case MouseDeviceType:
+      dSprintf(buffer, 16, "mouse%d", deviceInstance);
+      break;
+
+     case JoystickDeviceType:
+      dSprintf(buffer, 16, "joystick%d", deviceInstance);
+      break;
+    
+     case AccelerometerDeviceType:
+     dStrcpy(buffer, "accelerometer");
+     break;
+    
+     case GyroscopeDeviceType:
+     dStrcpy(buffer, "gyroscope");
+     break;
+     
+     case ScreenTouchDeviceType:
+     dStrcpy(buffer, "touchdevice");
+     break;
+
+	  case GamepadDeviceType:
+      dSprintf(buffer, 16, "gamepad%d", deviceInstance);
+      break;
+
+     case LeapMotionDeviceType:
+      dStrcpy(buffer, "leapdevice");
+      break;
+
+     default:
+      Con::errorf( "ActionMap::getDeviceName: unknown device type specified, %d (inst: %d)", deviceType, deviceInstance);
+      return false;
+   }
+
+   return true;
+}
+
+//------------------------------------------------------------------------------
+const char* ActionMap::getModifierString(const U32 modifiers)
+{
+    U32 realModifiers = modifiers;
+    if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT )
+        realModifiers |= SI_SHIFT;
+    if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL )
+        realModifiers |= SI_CTRL;
+    if ( modifiers & SI_LALT || modifiers & SI_RALT )
+        realModifiers |= SI_ALT;
+    if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT )
+        realModifiers |= SI_MAC_OPT;
+
+   switch (realModifiers & (SI_SHIFT|SI_CTRL|SI_ALT|SI_MAC_OPT)) {
+#if defined(TORQUE_OS_OSX)
+      // optional code, to output alt as cmd on mac.
+      // interpreter sees them as the same...
+     case (SI_SHIFT|SI_CTRL|SI_ALT):
+      return "cmd-shift-ctrl ";
+
+     case (SI_SHIFT|SI_ALT):
+      return "cmd-shift ";
+
+     case (SI_CTRL|SI_ALT):
+      return "cmd-ctrl ";
+
+     case (SI_ALT):
+      return "cmd ";
+#else
+     case (SI_SHIFT|SI_CTRL|SI_ALT):
+      return "shift-ctrl-alt ";
+
+     case (SI_SHIFT|SI_ALT):
+      return "shift-alt ";
+
+     case (SI_CTRL|SI_ALT):
+      return "ctrl-alt ";
+
+     case (SI_ALT):
+      return "alt ";
+#endif
+     case (SI_SHIFT|SI_CTRL):
+      return "shift-ctrl ";
+
+     case (SI_SHIFT):
+      return "shift ";
+
+     case (SI_CTRL):
+      return "ctrl ";
+
+// plus new mac cases:
+     case (SI_ALT|SI_SHIFT|SI_CTRL|SI_MAC_OPT):
+      return "cmd-shift-ctrl-opt ";
+
+     case (SI_ALT|SI_SHIFT|SI_MAC_OPT):
+      return "cmd-shift-opt ";
+
+     case (SI_ALT|SI_CTRL|SI_MAC_OPT):
+      return "cmd-ctrl-opt ";
+
+     case (SI_ALT|SI_MAC_OPT):
+      return "cmd-opt ";
+
+     case (SI_SHIFT|SI_CTRL|SI_MAC_OPT):
+      return "shift-ctrl-opt ";
+
+     case (SI_SHIFT|SI_MAC_OPT):
+      return "shift-opt ";
+
+     case (SI_CTRL|SI_MAC_OPT):
+      return "ctrl-opt ";
+
+     case (SI_MAC_OPT):
+      return "opt ";
+      
+     case 0:
+      return "";
+
+     default:
+      AssertFatal(false, "Error, should never reach the default case in getModifierString");
+      return "";
+   }
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::getKeyString(const U32 action, char* buffer)
+{
+   U16 asciiCode = Input::getAscii(action, STATE_LOWER);
+
+//   if (action >= KEY_A && action <= KEY_Z) {
+//      buffer[0] = char(action - KEY_A + 'a');
+//      buffer[1] = '\0';
+//      return true;
+//   } else if (action >= KEY_0 && action <= KEY_9) {
+//      buffer[0] = char(action - KEY_0 + '0');
+//      buffer[1] = '\0';
+   if ( (asciiCode != 0) && dIsDecentChar((char)asciiCode))
+   {
+      for (U32 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++) {
+         if (gAsciiMap[i].asciiCode == asciiCode)
+         {
+            dStrcpy(buffer, gAsciiMap[i].pDescription);
+            return true;
+         }
+      }
+      // Must not have found a string for that ascii code just record the char
+      buffer[0] = char(asciiCode);
+      buffer[1] = '\0';
+      return true;
+   }
+   else
+   {
+      if (action >= KEY_A && action <= KEY_Z)
+      {
+         buffer[0] = char(action - KEY_A + 'a');
+         buffer[1] = '\0';
+         return true;
+      }
+      else if (action >= KEY_0 && action <= KEY_9) {
+         buffer[0] = char(action - KEY_0 + '0');
+         buffer[1] = '\0';
+         return true;
+      }
+      for (U32 i = 0; gVirtualMap[i].code != 0xFFFFFFFF; i++) {
+         if (gVirtualMap[i].code == action) {
+            dStrcpy(buffer, gVirtualMap[i].pDescription);
+            return true;
+         }
+      }
+   }
+
+   Con::errorf( "ActionMap::getKeyString: no string for action %d", action );
+   return false;
+}
+
+//--------------------------------------------------------------------------
+bool ActionMap::processBindCmd(const char *device, const char *action, const char *makeCmd, const char *breakCmd)
+{
+   U32 deviceType;
+   U32 deviceInst;
+
+   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
+   {
+      Con::printf("processBindCmd: unknown device: %s", device);
+      return false;
+   }
+
+   // Ok, we now have the deviceType and instance.  Create an event descriptor
+   //  for the bind...
+   //
+   EventDescriptor eventDescriptor;
+   if (createEventDescriptor(action, &eventDescriptor) == false) {
+      Con::printf("Could not create a description for binding: %s", action);
+      return false;
+   }
+
+   // SI_POV == SI_MOVE, and the POV works fine with bindCmd, so we have to add these manually.
+   if( ( eventDescriptor.eventCode == SI_XAXIS )    ||
+       ( eventDescriptor.eventCode == SI_YAXIS )    ||
+       ( eventDescriptor.eventCode == SI_ZAXIS )    ||
+       ( eventDescriptor.eventCode == SI_RXAXIS )   ||
+       ( eventDescriptor.eventCode == SI_RYAXIS )   ||
+       ( eventDescriptor.eventCode == SI_RZAXIS )   ||
+       ( eventDescriptor.eventCode == SI_SLIDER )   ||
+       ( eventDescriptor.eventCode == SI_XPOV )     ||
+       ( eventDescriptor.eventCode == SI_YPOV )     ||
+       ( eventDescriptor.eventCode == SI_XPOV2 )    ||
+       ( eventDescriptor.eventCode == SI_YPOV2 )    ||
+       ( eventDescriptor.eventCode == SI_ACCELX )   ||
+       ( eventDescriptor.eventCode == SI_ACCELY )   ||
+       ( eventDescriptor.eventCode == SI_ACCELZ )   ||
+       ( eventDescriptor.eventCode == SI_GRAVX )    ||
+       ( eventDescriptor.eventCode == SI_GRAVY )    ||
+       ( eventDescriptor.eventCode == SI_GRAVZ )    ||
+       ( eventDescriptor.eventCode == SI_GYROX )    ||
+       ( eventDescriptor.eventCode == SI_GYROY )    ||
+       ( eventDescriptor.eventCode == SI_GYROZ )    ||
+       ( eventDescriptor.eventCode == SI_YAW )      ||
+       ( eventDescriptor.eventCode == SI_PITCH )    ||
+       ( eventDescriptor.eventCode == SI_ROLL ) )	
+   {
+      Con::warnf( "ActionMap::processBindCmd - Cannot use 'bindCmd' with a move event type. Use 'bind' instead." );
+      return false;
+   }
+
+   // Create the full bind entry, and place it in the map
+   //
+   // DMMTODO
+   Node* pBindNode = getNode(deviceType, deviceInst,
+                             eventDescriptor.flags,
+                             eventDescriptor.eventCode);
+
+   pBindNode->flags           = Node::BindCmd;
+   pBindNode->deadZoneBegin   = 0;
+   pBindNode->deadZoneEnd     = 0;
+   pBindNode->scaleFactor     = 1;
+   if(makeCmd[0])
+      pBindNode->makeConsoleCommand = dStrdup(makeCmd);
+   else
+      pBindNode->makeConsoleCommand = dStrdup("");
+
+   if(breakCmd[0])
+      pBindNode->breakConsoleCommand = dStrdup(breakCmd);
+   else
+      pBindNode->breakConsoleCommand = dStrdup("");
+   return true;
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::processBind(const U32 argc, const char** argv, SimObject* object)
+{
+   // Ok, the bind will come in the following format:
+   //  [device] [key or button] <[param spec] [param] ...> [fnName]
+   //
+   const char* pDeviceName = argv[0];
+   const char* pEvent      = argv[1];
+   const char* pFnName     = argv[argc - 1];
+
+   // Determine the device
+   U32 deviceType;
+   U32 deviceInst;
+
+   if(!getDeviceTypeAndInstance(argv[0], deviceType, deviceInst))
+   {
+      Con::printf("processBind: unknown device: %s", pDeviceName);
+      return false;
+   }
+
+   // Ok, we now have the deviceType and instance.  Create an event descriptor
+   //  for the bind...
+   //
+   EventDescriptor eventDescriptor;
+   if (createEventDescriptor(pEvent, &eventDescriptor) == false) {
+      Con::printf("Could not create a description for binding: %s", pEvent);
+      return false;
+   }
+
+   // Event has now been described, and device determined.  we need now to extract
+   //  any modifiers that the action map will apply to incoming events before
+   //  calling the bound function...
+   //
+   // DMMTODO
+   U32 assignedFlags = 0;
+   F32 deadZoneBegin = 0.0f;
+   F32 deadZoneEnd   = 0.0f;
+   F32 scaleFactor   = 1.0f;
+
+   if (argc != 3) {
+      // We have the following: "[DSIR]" [deadZone] [scale]
+      //
+      const char* pSpec = argv[2];
+
+      for (U32 i = 0; pSpec[i] != '\0'; i++) {
+         switch (pSpec[i]) {
+           case 'r': case 'R':
+            assignedFlags |= Node::HasScale;
+            break;
+           case 's': case 'S':
+            assignedFlags |= Node::HasScale;
+            break;
+           case 'd': case 'D':
+            assignedFlags |= Node::HasDeadZone;
+            break;
+           case 'i': case 'I':
+            assignedFlags |= Node::Inverted;
+            break;
+			case 'n': case 'N':
+            assignedFlags |= Node::NonLinear;
+            break;
+
+           default:
+            AssertFatal(false, avar("Misunderstood specifier in bind (spec string: %s)",
+                                    pSpec));
+         }
+      }
+
+      // Ok, we have the flags.  Scan the dead zone and scale, if any.
+      //
+      U32 curArg = 3;
+      if (assignedFlags & Node::HasDeadZone) {
+         dSscanf(argv[curArg], "%g %g", &deadZoneBegin, &deadZoneEnd);
+         curArg++;
+      }
+      if (assignedFlags & Node::HasScale) {
+         scaleFactor = dAtof(argv[curArg]);
+         curArg++;
+      }
+
+      if (curArg != (argc - 1)) {
+         AssertFatal(curArg == (argc - 1), "error in bind spec somewhere...");
+         Con::printf("Improperly specified bind for key: %s", argv[2]);
+         return false;
+      }
+   }
+
+   // Ensure that the console function is properly specified?
+   //
+   // DMMTODO
+
+   // Create the full bind entry, and place it in the map
+   //
+   // DMMTODO
+   Node* pBindNode = getNode(deviceType, deviceInst,
+                             eventDescriptor.flags,
+                             eventDescriptor.eventCode, object);
+
+   pBindNode->flags           = assignedFlags;
+   pBindNode->deadZoneBegin   = deadZoneBegin;
+   pBindNode->deadZoneEnd     = deadZoneEnd;
+   pBindNode->scaleFactor     = scaleFactor;
+   pBindNode->object          = object;
+   pBindNode->consoleFunction = StringTable->insert(pFnName);
+
+   return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ActionMap::processLeap(const InputEvent* pEvent)
+{
+    static const char *argv[5];
+    char buffer[64];
+
+    const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objType );
+
+    if (pNode == NULL)
+    {
+        // Check to see if we clear the modifiers, do we find an action?
+        if (pEvent->modifier != 0)
+            pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objInst);
+
+        if (pNode == NULL)
+            return false;
+    }
+
+    // "Do nothing" bind:
+    if ( !pNode->consoleFunction[0] )
+        return( true );
+
+    argv[0] = pNode->consoleFunction;
+
+    float values[3];
+    values[0] = pEvent->fValues[0];
+    values[1] = pEvent->fValues[1];
+    values[2] = pEvent->fValues[2];
+
+    if ( pNode->flags & Node::HasDeadZone )
+    {
+        if ( pEvent->fValues[0] >= pNode->deadZoneBegin && pEvent->fValues[0] <= pNode->deadZoneEnd )
+            values[0] = 0.0f;
+        if ( pEvent->fValues[1] >= pNode->deadZoneBegin && pEvent->fValues[1] <= pNode->deadZoneEnd )
+            values[1] = 0.0f;
+        if ( pEvent->fValues[2] >= pNode->deadZoneBegin && pEvent->fValues[2] <= pNode->deadZoneEnd )
+            values[2] = 0.0f;
+
+        // All values are all null, so don't bother executing the function
+        if (!values[0] && !values[1] && !values[2])
+            return true;
+    }
+
+    switch(pEvent->objType)
+    {
+        case LM_HANDPOS:
+
+            // ID
+            argv[1] = Con::getIntArg(pEvent->iValue);
+
+            // Position
+            dSprintf(buffer, sizeof(buffer), "%f %f %f", values[0], values[1], values[2]);
+
+            argv[2] = buffer;
+
+            if (pNode->object)
+                Con::executef(pNode->object, 3, argv[0], argv[1], argv[2]);
+            else
+                Con::execute(3, argv);
+            break;
+
+        case LM_HANDROT:
+            
+            // ID
+            argv[1] = Con::getIntArg(pEvent->iValue);
+
+            // Rotation
+            dSprintf(buffer, sizeof(buffer), "%f %f %f", values[0], values[1], values[2]);
+
+            argv[2] = buffer;
+
+            if (pNode->object)
+                Con::executef(pNode->object, 3, argv[0], argv[1], argv[2]);
+            else
+                Con::execute(3, argv);
+            break;
+
+        case LM_FINGERPOS:
+            
+            // IDs
+            argv[1] = pEvent->fingerIDs;
+
+            // X-coordinates
+            argv[2] = pEvent->fingersX;
+
+            // Y-coordinates
+            argv[3] = pEvent->fingersY;
+
+            // Z-coordinates
+            argv[4] = pEvent->fingersZ;
+
+            if (pNode->object)
+                Con::executef(pNode->object, 5, argv[0], argv[1], argv[2], argv[3], argv[4]);
+            else
+                Con::execute(5, argv);
+            break;
+
+        case LM_HANDAXIS:
+        default:
+            return false;
+    }
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ActionMap::processGesture(const InputEvent* pEvent)
+{
+    static const char *argv[6];
+    char buffer[64];
+
+    const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objType );
+
+    if (pNode == NULL) 
+    {
+        // Check to see if we clear the modifiers, do we find an action?
+        if (pEvent->modifier != 0)
+            pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objInst);
+           
+        if (pNode == NULL)
+            return false;
+    }
+
+    // "Do nothing" bind:
+    if ( !pNode->consoleFunction[0] )
+        return( true );
+
+    // Function
+    argv[0] = pNode->consoleFunction;
+    
+    switch(pEvent->objType)
+    {
+        case SI_CIRCLE_GESTURE:
+
+            // ID
+            argv[1] = Con::getIntArg(pEvent->iValue);
+
+            // Progress
+            argv[2] = Con::getFloatArg(pEvent->fValues[0]);
+
+            // Radius
+            argv[3] = Con::getFloatArg(pEvent->fValues[1]);
+
+            // Direction (1 clockwise, 0 counter-clockwise)
+            argv[4] = Con::getFloatArg(pEvent->fValues[2]);
+
+            // State
+            argv[5] = Con::getFloatArg(pEvent->fValues[3]);
+
+            if (pNode->object)
+                Con::executef(pNode->object, 6, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+            else
+                Con::execute(6, argv);
+            break;
+
+        case SI_SWIPE_GESTURE:
+
+            // ID
+            argv[1] = Con::getIntArg(pEvent->iValue);
+
+            // State
+            argv[2] = Con::getFloatArg(pEvent->fValues[0]);
+
+            // Direction
+            dSprintf(buffer, sizeof(buffer), "%f %f %f", pEvent->fValues[1], pEvent->fValues[2], pEvent->fValues[3]);
+
+            argv[3] = buffer;
+            // Speed
+            argv[4] = Con::getFloatArg(pEvent->fValues[4]);
+
+            if (pNode->object)
+                Con::executef(pNode->object, 5, argv[0], argv[1], argv[2], argv[3], argv[4]);
+            else
+                Con::execute(5, argv);
+            break;
+
+        case SI_KEYTAP_GESTURE:
+        case SI_SCREENTAP_GESTURE:
+
+            // ID
+            argv[1] = Con::getIntArg(pEvent->iValue);
+        
+            // Position
+            dSprintf(buffer, sizeof(buffer), "%f %f %f", pEvent->fValues[0], pEvent->fValues[1], pEvent->fValues[2]);
+
+            argv[2] = buffer;
+
+            // Direction
+            dSprintf(buffer, sizeof(buffer), "%f %f %f", pEvent->fValues[3], pEvent->fValues[4], pEvent->fValues[5]);
+
+            argv[3] = buffer;
+
+            if (pNode->object)
+                Con::executef(pNode->object, 4, argv[0], argv[1], argv[2], argv[3]);
+            else
+                Con::execute(5, argv);
+
+            break;
+
+        case SI_PINCH_GESTURE:
+        case SI_SCALE_GESTURE:
+        default:
+            return true;
+    }
+       
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ActionMap::processTouch(const InputEvent* pEvent)
+{
+    static const char *argv[4];
+    const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objInst);
+       
+    if (pNode == NULL) 
+    {
+        // Check to see if we clear the modifiers, do we find an action?
+        if (pEvent->modifier != 0)
+            pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objInst);
+           
+        if (pNode == NULL)
+            return false;
+    }
+       
+    // "Do nothing" bind:
+    if ( !pNode->consoleFunction[0] )
+        return( true );
+       
+    // Ok, we're all set up, call the function.
+    argv[0] = pNode->consoleFunction;
+    argv[1] = pEvent->fingerIDs;
+    argv[2] = pEvent->fingersX;
+    argv[3] = pEvent->fingersY;
+       
+    if (pNode->object)
+        Con::executef(pNode->object, 4, argv[0], argv[1], argv[2], argv[3]);
+    else
+        Con::execute(4, argv);
+       
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ActionMap::processButton(const InputEvent* pEvent)
+{
+    static const char *argv[2];
+    const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objInst);
+
+    if (pNode == NULL) 
+    {
+        // Check to see if we clear the modifiers, do we find an action?
+        if (pEvent->modifier != 0)
+            pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objInst);
+
+        if (pNode == NULL)
+            return false;
+    }
+
+    // Whadda ya know, we have this bound.  Set up, and call the console
+    //  function associated with it...
+    //
+    F32 value = pEvent->fValues[0];
+       
+    if (pNode->flags & Node::Ranged)
+    {
+        value = (value * 2.0f) - 1.0f;
+         
+        if (pNode->flags & Node::Inverted)
+            value *= -1.0f;
+    }
+    else
+    {
+        if (pNode->flags & Node::Inverted)
+            value = 1.0f - value;
+    }
+
+    if (pNode->flags & Node::HasScale)
+        value *= pNode->scaleFactor;
+
+    if (pNode->flags & Node::HasDeadZone)
+    {
+        if (value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd)
+            value = 0.0f;
+        else			
+        {
+            if( value > 0 )
+                value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
+            else
+                value = ( value + pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
+        }
+    }
+
+    if( pNode->flags & Node::NonLinear )
+        value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
+
+    // Ok, we're all set up, call the function.
+    if(pNode->flags & Node::BindCmd)
+    {
+        // it's a bind command
+        if(pNode->makeConsoleCommand)
+            Con::evaluate(pNode->makeConsoleCommand);
+    }
+    else if ( pNode->consoleFunction[0] )
+    {
+        argv[0] = pNode->consoleFunction;
+        argv[1] = Con::getFloatArg(value);
+        
+        if (pNode->object)
+            Con::executef(pNode->object, 2, argv[0], argv[1]);
+        else
+            Con::execute(2, argv);
+    }
+
+    // [neo, 5/13/2007 - #3109]
+    // The execs/evaluate above could have called reentrant script code which made calls to
+    // bindCmd() etc, channging the node map underneath us. If enough nodes were added then
+    // the node map vector would realloc, with the result that pNode would then be pointing 
+    // at garbage and cause a crash when passed to enterBreakEvent() below. So we just look
+    // it up again to be safe. This is not needed in the other cases below as we return right
+    // after the execs and don't use pNode again.
+    pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objInst );
+
+    if( pNode == NULL )
+        return true; // We already called any bound methods/functions so our job is done
+
+    //
+    // And enter the break into the table if this is a make event...
+    enterBreakEvent(pEvent, pNode);
+
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ActionMap::processMove(const InputEvent* pEvent)
+{
+    static const char *argv[4];
+
+    if (pEvent->deviceType == MouseDeviceType)
+    {
+        const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objType);
+
+        if (pNode == NULL)
+        {
+            // Check to see if we clear the modifiers, do we find an action?
+            if (pEvent->modifier != 0)
+                pNode = findNode(pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objType);
+
+            if (pNode == NULL)
+                return false;
+        }
+
+        // "Do nothing" bind:
+        if ( !pNode->consoleFunction[0] )
+            return( true );
+
+        // Whadda ya know, we have this bound.  Set up, and call the console
+        //  function associated with it.  Mouse events ignore range and dead
+        //  zone params.
+        //
+        F32 value = pEvent->fValues[0];
+         
+        if (pNode->flags & Node::Inverted)
+            value *= -1.0f;
+        if (pNode->flags & Node::HasScale)
+            value *= pNode->scaleFactor;
+
+        // Ok, we're all set up, call the function.
+        argv[0] = pNode->consoleFunction;
+        argv[1] = Con::getFloatArg(value);
+          
+        if (pNode->object)
+            Con::executef(pNode->object, 2, argv[0], argv[1]);
+        else
+            Con::execute(2, argv);
+
+            return true;
+    } 
+    else if ( (pEvent->objType == XI_POS || pEvent->objType == XI_FLOAT || pEvent->objType == XI_ROT || pEvent->objType == XI_INT) )
+    {
+        const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst, pEvent->modifier,   pEvent->objInst);
+
+        if( pNode == NULL )
+            return false;
+
+        // Ok, we're all set up, call the function.
+        argv[0] = pNode->consoleFunction;
+        S32 argc = 1;
+
+        if (pEvent->objType == XI_INT)
+        {
+            // Handle the integer as some sort of motion such as a
+            // single component to an absolute position
+            argv[1] = Con::getIntArg( pEvent->iValue );
+            argc += 1;
+        }
+        else if (pEvent->objType == XI_FLOAT)
+        {
+            // Handle float as some sort of motion such as a
+            // single component to an absolute position
+            argv[1] = Con::getFloatArg( pEvent->fValues[0] );
+            argc += 1;
+        }
+        else if (pEvent->objType == XI_POS)
+        {
+            // Handle Point3F type position
+            argv[1] = Con::getFloatArg( pEvent->fValues[0] );
+            argv[2] = Con::getFloatArg( pEvent->fValues[1] );
+            argv[3] = Con::getFloatArg( pEvent->fValues[2] );
+
+            argc += 3;
+        }
+
+        if (pNode->object)
+        {
+            Con::execute(pNode->object, argc, argv);
+        }
+        else
+        {
+            Con::execute(argc, argv);
+        }
+
+        return true;
+    }
+    else if ( pEvent->deviceType == JoystickDeviceType || pEvent->deviceType == GamepadDeviceType )
+    {
+        // Joystick events...
+        const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier,   pEvent->objInst );
+
+        if( pNode == NULL )
+            return false;
+
+        // "Do nothing" bind:
+        if ( !pNode->consoleFunction[0] )
+            return( true );
+
+        // Whadda ya know, we have this bound.  Set up, and call the console
+        //  function associated with it.  Joystick move events are the same as mouse
+        //  move events except that they don't ignore dead zone.
+        //
+        F32 value = pEvent->fValues[0];
+        if ( pNode->flags & Node::Inverted )
+            value *= -1.0f;
+
+        if ( pNode->flags & Node::HasScale )
+            value *= pNode->scaleFactor;
+
+        if ( pNode->flags & Node::HasDeadZone )
+        {
+            if ( value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd )
+            {
+                value = 0.0f;
+            }
+            else
+            {
+                if( value > 0 )
+                    value = ( value - pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
+                else
+                    value = ( value + pNode->deadZoneBegin ) * ( 1.f / ( 1.f - pNode->deadZoneBegin ) );
+            }
+        }
+
+        if( pNode->flags & Node::NonLinear )
+            value = ( value < 0.f ? -1.f : 1.f ) * mPow( mFabs( value ), CONST_E );
+
+        // Ok, we're all set up, call the function.
+        argv[0] = pNode->consoleFunction;
+        argv[1] = Con::getFloatArg( value );
+            
+        if (pNode->object)
+            Con::executef(pNode->object, S32(argv[0]), argv[1]);
+        else
+            Con::execute(2, argv);
+
+        return true;
+    }
+
+    return false;
+}
+
+//------------------------------------------------------------------------------
+
+bool ActionMap::processMotion(const InputEvent* pEvent)
+{
+    static const char *argv[2];
+
+    // iOS Accelerometer, Gyroscope and DeviceMotion processing
+    // Currently, this is identical to the joystick handling.
+       
+    // This was copied over into its own section because this will
+    // give us a dedicated section to tweak processing based on iOS specific
+    // devices. No point in trying to mangle joystick code any further
+    const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier,   pEvent->objType );
+       
+    if ( pNode == NULL )
+    {
+        // Check to see if we clear the modifiers, do we find an action?
+        if (pEvent->modifier != 0)
+            pNode = findNode( pEvent->deviceType, pEvent->deviceInst, 0, pEvent->objType );
+           
+        if ( pNode == NULL )
+            return false;
+    }
+       
+    // "Do nothing" bind:
+    if ( !pNode->consoleFunction[0] )
+        return( true );
+       
+    F32 value = pEvent->fValues[0];
+       
+    if ( pNode->flags & Node::Inverted )
+        value *= -1.0f;
+       
+    if ( pNode->flags & Node::HasScale )
+        value *= pNode->scaleFactor;
+       
+    if ( pNode->flags & Node::HasDeadZone )
+    {
+        if ( value >= pNode->deadZoneBegin && value <= pNode->deadZoneEnd )
+            value = 0.0f;
+    }
+       
+    // Ok, we're all set up, call the function.
+    argv[0] = pNode->consoleFunction;
+    argv[1] = Con::getFloatArg( value );
+       
+    if (pNode->object)
+        Con::executef(pNode->object, 2, argv[0], argv[1]);
+    else
+        Con::execute(2, argv);
+       
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ActionMap::processXInput(const InputEvent* pEvent)
+{
+    static const char *argv[2];
+
+    if ((pEvent->objType == XI_FLOAT || pEvent->objType == XI_INT))
+    {
+        const Node* pNode = findNode( pEvent->deviceType, pEvent->deviceInst, pEvent->modifier, pEvent->objType );
+
+        if (pNode == NULL )
+            return false;
+
+        // Ok, we're all set up, call the function.
+        argv[0] = pNode->consoleFunction;
+        S32 argc = 1;
+
+        if (pEvent->objType == XI_INT)
+        {
+            // Handle the integer as some sort of motion such as a
+            // single component to an absolute position
+            argv[1] = Con::getIntArg( pEvent->iValue );
+            argc += 1;
+        }
+        else if (pEvent->objType == XI_FLOAT)
+        {
+            // Handle float as some sort of motion such as a
+            // single component to an absolute position
+            argv[1] = Con::getFloatArg( pEvent->fValues[0] );
+            argc += 1;
+        }
+
+        if (pNode->object)
+        {
+            Con::execute(pNode->object, argc, argv);
+        }
+        else
+        {
+            Con::execute(argc, argv);
+        }
+    }
+    
+    return true;
+}
+
+//------------------------------------------------------------------------------
+
+bool ActionMap::processAction(const InputEvent* pEvent)
+{
+    switch(pEvent->action)
+    {
+    case SI_LEAP:
+        return processLeap(pEvent);
+        break;
+    case SI_GESTURE:
+        return processGesture(pEvent);
+        break;
+    case SI_TOUCH:
+        return processTouch(pEvent);
+        break;
+    case SI_MAKE:
+        return processButton(pEvent);
+        break;
+    case SI_MOVE:
+        return processMove(pEvent);
+        break;
+    case SI_MOTION:
+        return processMotion(pEvent);
+        break;
+    case SI_BREAK:
+        return checkBreakTable(pEvent);
+        break;
+    case SI_VALUE:
+        return processXInput(pEvent);
+    }
+
+    return false;
+}
+
+//------------------------------------------------------------------------------
+void ActionMap::enterBreakEvent(const InputEvent* pEvent, const Node* pNode)
+{
+   // There aren't likely to be many breaks outstanding at any one given time,
+   //  so a simple linear search is probably sufficient.  Note that the break table
+   //  is static to the class, all breaks are directed to the action map that received
+   //  the make.
+   //
+   S32 entry = -1;
+   for (U32 i = 0; i < (U32)smBreakTable.size(); i++) {
+      if (smBreakTable[i].deviceType == U32(pEvent->deviceType) &&
+          smBreakTable[i].deviceInst == U32(pEvent->deviceInst) &&
+          smBreakTable[i].objInst    == U32(pEvent->objInst)) {
+         // Match.
+         entry = i;
+         break;
+      }
+   }
+   if (entry == -1) {
+      smBreakTable.increment();
+      entry = smBreakTable.size() - 1;
+
+      smBreakTable[entry].deviceType = pEvent->deviceType;
+      smBreakTable[entry].deviceInst = pEvent->deviceInst;
+      smBreakTable[entry].objInst    = pEvent->objInst;
+   }
+
+   // Ok, we now have the entry, and know that the device desc. and the objInst match.
+   //  Copy out the node information...
+   //
+   smBreakTable[entry].object = pNode->object;
+   // [neo, 5/7/2007 - #2975]
+   // object above can be deleted in between a make/break and so object will point
+   // to turfed memory and crash. To keep things simple we just store id as well so
+   // we can look it up to validate object ref.
+   smBreakTable[entry].objectId = pNode->object ? pNode->object->getId() : 0;
+
+   smBreakTable[entry].consoleFunction = pNode->consoleFunction;
+
+   if(pNode->breakConsoleCommand)
+      smBreakTable[entry].breakConsoleCommand = dStrdup(pNode->breakConsoleCommand);
+   else
+      smBreakTable[entry].breakConsoleCommand = NULL;
+
+   smBreakTable[entry].flags         = pNode->flags;
+   smBreakTable[entry].deadZoneBegin = pNode->deadZoneBegin;
+   smBreakTable[entry].deadZoneEnd   = pNode->deadZoneEnd;
+   smBreakTable[entry].scaleFactor   = pNode->scaleFactor;
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::checkBreakTable(const InputEvent* pEvent)
+{
+   for (U32 i = 0; i < (U32)smBreakTable.size(); i++) {
+      if (smBreakTable[i].deviceType == U32(pEvent->deviceType) &&
+          smBreakTable[i].deviceInst == U32(pEvent->deviceInst) &&
+          smBreakTable[i].objInst    == U32(pEvent->objInst)) {
+         // Match.  Issue the break event...
+         //
+         F32 value = pEvent->fValues[0];
+         if (smBreakTable[i].flags & Node::Ranged) {
+            value = (value * 2.0f) - 1.0f;
+            if (smBreakTable[i].flags & Node::Inverted)
+               value *= -1.0f;
+         } else {
+            if (smBreakTable[i].flags & Node::Inverted)
+               value = 1.0f - value;
+         }
+
+         if (smBreakTable[i].flags & Node::HasScale)
+            value *= smBreakTable[i].scaleFactor;
+
+         if (smBreakTable[i].flags & Node::HasDeadZone)
+            if (value >= smBreakTable[i].deadZoneBegin &&
+                value <= smBreakTable[i].deadZoneEnd)
+               value = 0.0f;
+
+         // Ok, we're all set up, call the function.
+         if(smBreakTable[i].consoleFunction)
+         {
+            if ( smBreakTable[i].consoleFunction[0] )
+            {
+               static const char *argv[2];
+               argv[0] = smBreakTable[i].consoleFunction;
+               argv[1] = Con::getFloatArg(value);
+                              
+               if( smBreakTable[i].object )
+               {
+                  // [neo, 5/7/2007 - #2975]
+                  // object above can be deleted in between a make/break and so object will point
+                  // to turfed memory and crash. To keep things simple we just store id as well so
+                  // we can look it up to validate object ref.
+                  if( smBreakTable[i].objectId > 0 && Sim::findObject( smBreakTable[i].objectId ) )
+                     Con::executef(smBreakTable[i].object, 2, argv[0], argv[1]);
+               }
+               else
+                  Con::execute(2, argv);
+            }
+         }
+         else if(smBreakTable[i].breakConsoleCommand)
+         {
+            Con::evaluate(smBreakTable[i].breakConsoleCommand);
+            dFree(smBreakTable[i].breakConsoleCommand);
+         }
+         smBreakTable.erase(i);
+         return true;
+      }
+   }
+
+   return false;
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::handleEvent(const InputEvent* pEvent)
+{
+   // Interate through the ActionMapSet until we get a map that
+   //  handles the event or we run out of maps...
+   //
+   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
+   AssertFatal(pActionMapSet && pActionMapSet->size() != 0,
+               "error, no ActiveMapSet or no global action map...");
+
+   for (SimSet::iterator itr = pActionMapSet->end() - 1;
+        itr > pActionMapSet->begin(); itr--) {
+      ActionMap* pMap = static_cast<ActionMap*>(*itr);
+      if (pMap->processAction(pEvent) == true)
+         return true;
+   }
+
+   return false;
+}
+
+//------------------------------------------------------------------------------
+bool ActionMap::handleEventGlobal(const InputEvent* pEvent)
+{
+   // Interate through the ActionMapSet until we get a map that
+   //  handles the event or we run out of maps...
+   //
+   SimSet* pActionMapSet = Sim::getActiveActionMapSet();
+   AssertFatal(pActionMapSet && pActionMapSet->size() != 0,
+               "error, no ActiveMapSet or no global action map...");
+
+   return ((ActionMap*)pActionMapSet->first())->processAction(pEvent);
+}
+
+//------------------------------------------------------------------------------
+//-------------------------------------- Key code to string mapping
+//                                        TODO: Add most obvious aliases...
+//
+CodeMapping gVirtualMap[] =
+{
+   //-------------------------------------- KEYBOARD EVENTS
+   //
+   { "backspace",     SI_KEY,    KEY_BACKSPACE   },
+   { "tab",           SI_KEY,    KEY_TAB         },
+
+   { "return",        SI_KEY,    KEY_RETURN      },
+   { "enter",         SI_KEY,    KEY_RETURN      },
+
+   { "shift",         SI_KEY,    KEY_SHIFT       },
+   { "ctrl",          SI_KEY,    KEY_CONTROL     },
+   { "alt",           SI_KEY,    KEY_ALT         },
+   { "pause",         SI_KEY,    KEY_PAUSE       },
+   { "capslock",      SI_KEY,    KEY_CAPSLOCK    },
+
+   { "escape",        SI_KEY,    KEY_ESCAPE      },
+
+   { "space",         SI_KEY,    KEY_SPACE       },
+   { "pagedown",      SI_KEY,    KEY_PAGE_DOWN   },
+   { "pageup",        SI_KEY,    KEY_PAGE_UP     },
+   { "end",           SI_KEY,    KEY_END         },
+   { "home",          SI_KEY,    KEY_HOME        },
+   { "left",          SI_KEY,    KEY_LEFT        },
+   { "up",            SI_KEY,    KEY_UP          },
+   { "right",         SI_KEY,    KEY_RIGHT       },
+   { "down",          SI_KEY,    KEY_DOWN        },
+   { "print",         SI_KEY,    KEY_PRINT       },
+   { "insert",        SI_KEY,    KEY_INSERT      },
+   { "delete",        SI_KEY,    KEY_DELETE      },
+   { "help",          SI_KEY,    KEY_HELP        },
+
+   { "win_lwindow",   SI_KEY,    KEY_WIN_LWINDOW },
+   { "win_rwindow",   SI_KEY,    KEY_WIN_RWINDOW },
+   { "win_apps",      SI_KEY,    KEY_WIN_APPS    },
+
+   { "cmd",           SI_KEY,    KEY_ALT         },
+   { "opt",           SI_KEY,    KEY_MAC_OPT     },
+   { "lopt",          SI_KEY,    KEY_MAC_LOPT    },
+   { "ropt",          SI_KEY,    KEY_MAC_ROPT    },
+
+   { "numpad0",       SI_KEY,    KEY_NUMPAD0     },
+   { "numpad1",       SI_KEY,    KEY_NUMPAD1     },
+   { "numpad2",       SI_KEY,    KEY_NUMPAD2     },
+   { "numpad3",       SI_KEY,    KEY_NUMPAD3     },
+   { "numpad4",       SI_KEY,    KEY_NUMPAD4     },
+   { "numpad5",       SI_KEY,    KEY_NUMPAD5     },
+   { "numpad6",       SI_KEY,    KEY_NUMPAD6     },
+   { "numpad7",       SI_KEY,    KEY_NUMPAD7     },
+   { "numpad8",       SI_KEY,    KEY_NUMPAD8     },
+   { "numpad9",       SI_KEY,    KEY_NUMPAD9     },
+   { "numpadmult",    SI_KEY,    KEY_MULTIPLY    },
+   { "numpadadd",     SI_KEY,    KEY_ADD         },
+   { "numpadsep",     SI_KEY,    KEY_SEPARATOR   },
+   { "numpadminus",   SI_KEY,    KEY_SUBTRACT    },
+   { "numpaddecimal", SI_KEY,    KEY_DECIMAL     },
+   { "numpaddivide",  SI_KEY,    KEY_DIVIDE      },
+   { "numpadenter",   SI_KEY,    KEY_NUMPADENTER },
+
+   { "f1",            SI_KEY,    KEY_F1          },
+   { "f2",            SI_KEY,    KEY_F2          },
+   { "f3",            SI_KEY,    KEY_F3          },
+   { "f4",            SI_KEY,    KEY_F4          },
+   { "f5",            SI_KEY,    KEY_F5          },
+   { "f6",            SI_KEY,    KEY_F6          },
+   { "f7",            SI_KEY,    KEY_F7          },
+   { "f8",            SI_KEY,    KEY_F8          },
+   { "f9",            SI_KEY,    KEY_F9          },
+   { "f10",           SI_KEY,    KEY_F10         },
+   { "f11",           SI_KEY,    KEY_F11         },
+   { "f12",           SI_KEY,    KEY_F12         },
+   { "f13",           SI_KEY,    KEY_F13         },
+   { "f14",           SI_KEY,    KEY_F14         },
+   { "f15",           SI_KEY,    KEY_F15         },
+   { "f16",           SI_KEY,    KEY_F16         },
+   { "f17",           SI_KEY,    KEY_F17         },
+   { "f18",           SI_KEY,    KEY_F18         },
+   { "f19",           SI_KEY,    KEY_F19         },
+   { "f20",           SI_KEY,    KEY_F20         },
+   { "f21",           SI_KEY,    KEY_F21         },
+   { "f22",           SI_KEY,    KEY_F22         },
+   { "f23",           SI_KEY,    KEY_F23         },
+   { "f24",           SI_KEY,    KEY_F24         },
+
+   { "numlock",       SI_KEY,    KEY_NUMLOCK     },
+   { "scrolllock",    SI_KEY,    KEY_SCROLLLOCK  },
+
+   { "lshift",        SI_KEY,    KEY_LSHIFT      },
+   { "rshift",        SI_KEY,    KEY_RSHIFT      },
+   { "lcontrol",      SI_KEY,    KEY_LCONTROL    },
+   { "rcontrol",      SI_KEY,    KEY_RCONTROL    },
+   { "lalt",          SI_KEY,    KEY_LALT        },
+   { "ralt",          SI_KEY,    KEY_RALT        },
+   { "tilde",         SI_KEY,    KEY_TILDE       },
+
+   { "minus",         SI_KEY,    KEY_MINUS       },
+   { "equals",        SI_KEY,    KEY_EQUALS      },
+   { "lbracket",      SI_KEY,    KEY_LBRACKET    },
+   { "rbracket",      SI_KEY,    KEY_RBRACKET    },
+   { "backslash",     SI_KEY,    KEY_BACKSLASH   },
+   { "semicolon",     SI_KEY,    KEY_SEMICOLON   },
+   { "apostrophe",    SI_KEY,    KEY_APOSTROPHE  },
+   { "comma",         SI_KEY,    KEY_COMMA       },
+   { "period",        SI_KEY,    KEY_PERIOD      },
+   { "slash",         SI_KEY,    KEY_SLASH       },
+   { "lessthan",      SI_KEY,    KEY_OEM_102     },
+
+   //-------------------------------------- BUTTON EVENTS
+   // Joystick/Mouse buttons
+   { "button0",       SI_BUTTON, KEY_BUTTON0    },
+   { "button1",       SI_BUTTON, KEY_BUTTON1    },
+   { "button2",       SI_BUTTON, KEY_BUTTON2    },
+   { "button3",       SI_BUTTON, KEY_BUTTON3    },
+   { "button4",       SI_BUTTON, KEY_BUTTON4    },
+   { "button5",       SI_BUTTON, KEY_BUTTON5    },
+   { "button6",       SI_BUTTON, KEY_BUTTON6    },
+   { "button7",       SI_BUTTON, KEY_BUTTON7    },
+   { "button8",       SI_BUTTON, KEY_BUTTON8    },
+   { "button9",       SI_BUTTON, KEY_BUTTON9    },
+   { "button10",      SI_BUTTON, KEY_BUTTON10   },
+   { "button11",      SI_BUTTON, KEY_BUTTON11   },
+   { "button12",      SI_BUTTON, KEY_BUTTON12   },
+   { "button13",      SI_BUTTON, KEY_BUTTON13   },
+   { "button14",      SI_BUTTON, KEY_BUTTON14   },
+   { "button15",      SI_BUTTON, KEY_BUTTON15   },
+   { "button16",      SI_BUTTON, KEY_BUTTON16   },
+   { "button17",      SI_BUTTON, KEY_BUTTON17   },
+   { "button18",      SI_BUTTON, KEY_BUTTON18   },
+   { "button19",      SI_BUTTON, KEY_BUTTON19   },
+   { "button20",      SI_BUTTON, KEY_BUTTON20   },
+   { "button21",      SI_BUTTON, KEY_BUTTON21   },
+   { "button22",      SI_BUTTON, KEY_BUTTON22   },
+   { "button23",      SI_BUTTON, KEY_BUTTON23   },
+   { "button24",      SI_BUTTON, KEY_BUTTON24   },
+   { "button25",      SI_BUTTON, KEY_BUTTON25   },
+   { "button26",      SI_BUTTON, KEY_BUTTON26   },
+   { "button27",      SI_BUTTON, KEY_BUTTON27   },
+   { "button28",      SI_BUTTON, KEY_BUTTON28   },
+   { "button29",      SI_BUTTON, KEY_BUTTON29   },
+   { "button30",      SI_BUTTON, KEY_BUTTON30   },
+   { "button31",      SI_BUTTON, KEY_BUTTON31   },
+
+   //-------------------------------------- MOVE EVENTS
+   // Mouse/Joystick axes:
+   { "xaxis",         SI_MOVE,   SI_XAXIS       },
+   { "yaxis",         SI_MOVE,   SI_YAXIS       },
+   { "zaxis",         SI_MOVE,   SI_ZAXIS       },
+   { "rxaxis",        SI_MOVE,   SI_RXAXIS      },
+   { "ryaxis",        SI_MOVE,   SI_RYAXIS      },
+   { "rzaxis",        SI_MOVE,   SI_RZAXIS      },
+   { "slider",        SI_MOVE,   SI_SLIDER      },
+
+   //-------------------------------------- POV EVENTS
+   // Joystick POV:
+   { "xpov",          SI_POV,    SI_XPOV         },
+   { "ypov",          SI_POV,    SI_YPOV         },
+   { "upov",          SI_POV,    SI_UPOV         },
+   { "dpov",          SI_POV,    SI_DPOV         },
+   { "lpov",          SI_POV,    SI_LPOV         },
+   { "rpov",          SI_POV,    SI_RPOV         },
+   { "xpov2",         SI_POV,    SI_XPOV2        },
+   { "ypov2",         SI_POV,    SI_YPOV2        },
+   { "upov2",         SI_POV,    SI_UPOV2        },
+   { "dpov2",         SI_POV,    SI_DPOV2        },
+   { "lpov2",         SI_POV,    SI_LPOV2        },
+   { "rpov2",         SI_POV,    SI_RPOV2        },
+
+   #if defined( TORQUE_OS_WIN32 ) || defined( TORQUE_OS_XENON )
+   //-------------------------------------- XINPUT EVENTS
+   // Controller connect / disconnect:
+   { "connect",       XI_BUTTON, XI_CONNECT     },
+   
+   // L & R Thumbsticks:
+   { "thumblx",       XI_AXIS,   XI_THUMBLX     },
+   { "thumbly",       XI_AXIS,   XI_THUMBLY     },
+   { "thumbrx",       XI_AXIS,   XI_THUMBRX     },
+   { "thumbry",       XI_AXIS,   XI_THUMBRY     },
+
+   // L & R Triggers:
+   { "triggerl",      XI_AXIS,   XI_LEFT_TRIGGER  },
+   { "triggerr",      XI_AXIS,   XI_RIGHT_TRIGGER },
+
+   // DPAD Buttons:
+   { "dpadu",         XI_BUTTON, SI_UPOV     },
+   { "dpadd",         XI_BUTTON, SI_DPOV   },
+   { "dpadl",         XI_BUTTON, SI_LPOV   },
+   { "dpadr",         XI_BUTTON, SI_RPOV  },
+
+   // START & BACK Buttons:
+   { "btn_start",     XI_BUTTON, XI_START       },
+   { "btn_back",      XI_BUTTON, XI_BACK        },
+
+   // L & R Thumbstick Buttons:
+   { "btn_lt",        XI_BUTTON, XI_LEFT_THUMB  },
+   { "btn_rt",        XI_BUTTON, XI_RIGHT_THUMB },
+
+   // L & R Shoulder Buttons:
+   { "btn_l",         XI_BUTTON, XI_LEFT_SHOULDER  },
+   { "btn_r",         XI_BUTTON, XI_RIGHT_SHOULDER },
+
+   // Primary buttons:
+   { "btn_a",         XI_BUTTON, XI_A           },
+   { "btn_b",         XI_BUTTON, XI_B           },
+   { "btn_x",         XI_BUTTON, XI_X           },
+   { "btn_y",         XI_BUTTON, XI_Y           },
+#endif
+
+
+   //-------------------------------------- MOTION EVENTS
+   // Accelerometer/Gyroscope axes:
+   { "accelx",        SI_MOTION,    SI_ACCELX    },
+   { "accely",        SI_MOTION,    SI_ACCELY    },
+   { "accelz",        SI_MOTION,    SI_ACCELZ    },
+   { "gravityx",      SI_MOTION,    SI_GRAVX     },
+   { "gravityy",      SI_MOTION,    SI_GRAVY     },
+   { "gravityz",      SI_MOTION,    SI_GRAVZ     },
+   { "gyrox",         SI_MOTION,    SI_GYROX     },
+   { "gyroy",         SI_MOTION,    SI_GYROY     },
+   { "gyroz",         SI_MOTION,    SI_GYROZ     },
+   { "yaw",           SI_MOTION,    SI_YAW       },
+   { "pitch",         SI_MOTION,    SI_PITCH     },
+   { "roll",          SI_MOTION,    SI_ROLL      },
+
+   //-------------------------------------- TOUCH EVENTS
+   // Touch events:
+   { "touchdown",     SI_TOUCH,    SI_TOUCHDOWN  },
+   { "touchup",       SI_TOUCH,    SI_TOUCHUP    },
+   { "touchmove",     SI_TOUCH,    SI_TOUCHMOVE  },
+
+   //-------------------------------------- GESTURE EVENTS
+   // Preset gesture events:
+   { "circleGesture",      SI_GESTURE,  SI_CIRCLE_GESTURE    },
+   { "swipeGesture",       SI_GESTURE,  SI_SWIPE_GESTURE     },
+   { "screenTapGesture",   SI_GESTURE,  SI_SCREENTAP_GESTURE },
+   { "keyTapGesture",      SI_GESTURE,  SI_KEYTAP_GESTURE    },
+   { "pinchGesture",       SI_GESTURE,  SI_PINCH_GESTURE     },
+   { "scaleGesture",       SI_GESTURE,  SI_SCALE_GESTURE     },
+
+   //-------------------------------------- GESTURE EVENTS
+   // Preset gesture events:
+   { "leapHandAxis",    SI_LEAP,     LM_HANDAXIS    },
+   { "leapHandPos",     SI_LEAP,     LM_HANDPOS     },
+   { "leapHandRot",     SI_LEAP,     LM_HANDROT     },
+   { "leapFingerPos",   SI_LEAP,     LM_FINGERPOS   },
+   
+   //-------------------------------------- MISCELLANEOUS EVENTS
+   //
+   { "anykey",        SI_KEY,      KEY_ANYKEY },
+   { "nomatch",       SI_UNKNOWN,  0xFFFFFFFF }
+};
+
+AsciiMapping gAsciiMap[] =
+{
+   //--- KEYBOARD EVENTS
+   //
+   { "space",           0x0020 },
+   //{ "exclamation",     0x0021 },
+   { "doublequote",     0x0022 },
+   //{ "pound",           0x0023 },
+   //{ "ampersand",       0x0026 },
+   { "apostrophe",      0x0027 },
+   //{ "lparen",          0x0028 },
+   //{ "rparen",          0x0029 },
+   { "comma",           0x002c },
+   { "minus",           0x002d },
+   { "period",          0x002e },
+   //{ "slash",           0x002f },
+   //{ "colon",           0x003a },
+   //{ "semicolon",       0x003b },
+   //{ "lessthan",        0x003c },
+   //{ "equals",          0x003d },
+   //{ "morethan",        0x003e },
+   //{ "lbracket",        0x005b },
+   { "backslash",       0x005c },
+   //{ "rbracket",        0x005d },
+   //{ "circumflex",      0x005e },
+   //{ "underscore",      0x005f },
+   { "grave",           0x0060 },
+   //{ "tilde",           0x007e },
+   //{ "vertbar",         0x007c },
+   //{ "exclamdown",      0x00a1 },
+   //{ "cent",            0x00a2 },
+   //{ "sterling",        0x00a3 },
+   //{ "currency",        0x00a4 },
+   //{ "brokenbar",       0x00a6 },
+   //{ "ring",            0x00b0 },
+   //{ "plusminus",       0x00b1 },
+   { "super2",          0x00b2 },
+   { "super3",          0x00b3 },
+   { "acute",           0x00b4 },
+   //{ "mu",              0x00b5 },
+   //{ "ordmasculine",    0x00ba },
+   //{ "questiondown",    0x00bf },
+   //{ "gemandbls",       0x00df },
+   //{ "agrave",          0x00e0 },
+   //{ "aacute",          0x00e1 },
+   //{ "acircumflex",     0x00e2 },
+   //{ "atilde",          0x00e3 },
+   //{ "adieresis",       0x00e4 },
+   //{ "aring",           0x00e5 },
+   //{ "ae",              0x00e6 },
+   //{ "ccedille",        0x00e7 },
+   //{ "egrave",          0x00e8 },
+   //{ "eacute",          0x00e9 },
+   //{ "ecircumflex",     0x00ea },
+   //{ "edieresis",       0x00eb },
+   //{ "igrave",          0x00ec },
+   //{ "iacute",          0x00ed },
+   //{ "icircumflex",     0x00ee },
+   //{ "idieresis",       0x00ef },
+   //{ "ntilde",          0x00f1 },
+   //{ "ograve",          0x00f2 },
+   //{ "oacute",          0x00f3 },
+   //{ "ocircumflex",     0x00f4 },
+   //{ "otilde",          0x00f5 },
+   //{ "odieresis",       0x00f6 },
+   //{ "divide",          0x00f7 },
+   //{ "oslash",          0x00f8 },
+   //{ "ugrave",          0x00f9 },
+   //{ "uacute",          0x00fa },
+   //{ "ucircumflex",     0x00fb },
+   //{ "udieresis",       0x00fc },
+   //{ "ygrave",          0x00fd },
+   //{ "thorn",           0x00fe },
+   //{ "ydieresis",       0x00ff },
+   { "nomatch",         0xFFFF }
+};
+
+
+////Device Event Types
+//#define SI_UNKNOWN   0x01
+//#define SI_BUTTON    0x02
+//#define SI_POV       0x03
+//#define SI_XPOV      0x04
+//#define SI_YPOV      0x05
+//#define SI_UPOV      0x06
+//#define SI_DPOV      0x07
+//#define SI_LPOV      0x08
+//#define SI_RPOV      0x09
+//#define SI_KEY       0x0A
+//#define SI_XAXIS     0x0B
+//#define SI_YAXIS     0x0C
+//#define SI_ZAXIS     0x0D
+//#define SI_RXAXIS    0x0E
+//#define SI_RYAXIS    0x0F
+//#define SI_RZAXIS    0x10
+//#define SI_SLIDER    0x11

+ 4 - 4
engine/source/platformOSX/osxTorqueView.mm

@@ -237,9 +237,9 @@
     torqueEvent.ascii = 0;
     torqueEvent.ascii = 0;
     torqueEvent.action = action;
     torqueEvent.action = action;
     if (action == SI_BREAK)
     if (action == SI_BREAK)
-        torqueEvent.fValue = 0.0;
+        torqueEvent.fValues[0] = 0.0;
     else
     else
-        torqueEvent.fValue = 1.0;
+        torqueEvent.fValues[0] = 1.0;
     
     
     // Post the input event
     // Post the input event
     Game->postEvent(torqueEvent);
     Game->postEvent(torqueEvent);
@@ -287,7 +287,7 @@
     torqueEvent.modifier = modifiers;
     torqueEvent.modifier = modifiers;
     torqueEvent.ascii = 0;
     torqueEvent.ascii = 0;
     torqueEvent.action = action;
     torqueEvent.action = action;
-    torqueEvent.fValue = fValue;
+    torqueEvent.fValues[0] = fValue;
     torqueEvent.ascii = chars;
     torqueEvent.ascii = chars;
     
     
     // Post the input event
     // Post the input event
@@ -441,7 +441,7 @@
     torqueEvent.modifier = modifiers;
     torqueEvent.modifier = modifiers;
     torqueEvent.ascii = 0;
     torqueEvent.ascii = 0;
     torqueEvent.action = SI_MOVE;
     torqueEvent.action = SI_MOVE;
-    torqueEvent.fValue = deltaY;
+    torqueEvent.fValues[0] = deltaY;
     Game->postEvent(torqueEvent);
     Game->postEvent(torqueEvent);
 }
 }
 
 

+ 1263 - 1263
engine/source/platformiOS/iOSInput.mm

@@ -1,1263 +1,1263 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-
-#include "platformiOS/platformiOS.h"
-#include "platformiOS/iOSUtil.h"
-#include "platform/platformInput.h"
-#include "platform/event.h"
-#include "console/console.h"
-#include "game/gameInterface.h"
-#include "string/Unicode.h"
-#include "gui/guiCanvas.h"
-
-
-// <Mat> just some random number 50, we'll get a proper value later
-#define IOS_DOUBLE_CLICK_TIME	( 50 * 60.0f * 1000.0f)
-
-// Static class variables:
-InputManager* Input::smManager;
-bool           Input::smActive;
-CursorManager* Input::smCursorManager = 0;
-
-
-bool gInputEnabled = false;
-bool gMouseEnabled = false;
-bool gKBEnabled = false;
-bool gMouseActive = false;
-bool gKBActive = false;
-
-//------------------------------------------------------------------------------
-// Helper functions.  Should migrate to an InputManager object at some point.
-bool enableKeyboard(void);
-void disableKeyboard(void);
-bool activateKeyboard(void);
-void deactivateKeyboard(void);
-bool enableMouse(void);
-void disableMouse(void);
-bool activateMouse(void);
-void deactivateMouse(void);
-
-
-
-static void fillAsciiTable();
-
-
-struct touchEvent {
-	S32 number;
-	S32 x;
-	S32 y;
-	touchEvent( S32 a, S32 b, S32 c ) {
-		number = a;
-		x = b;
-		y = c;
-	}
-};
-
-
-Vector<touchEvent> TouchMoveEvents;//<Mat> to make sure we don't have multiple events per frame
-Vector<touchEvent> TouchDownEvents;
-Vector<touchEvent> TouchUpEvents;
-
-// EFM - BEGIN TOUCH CHANGES
-#define MAX_TOUCH_EVENTS 5
-
-struct touchTracker {
-	S32 lastX;
-	S32 lastY;
-	Vector<touchEvent> downEvents;
-	Vector<touchEvent> moveEvents;
-	Vector<touchEvent> upEvents;
-};
-
-touchTracker CombinedTouchEvents[MAX_TOUCH_EVENTS];
-
-struct touchCorrelation {
-	S32 lastX;
-	S32 lastY;
-};
-
-touchCorrelation lastTouches[MAX_TOUCH_EVENTS];
-
-// EFM - END TOUCH CHANGES
-
-//Luma: Tap support
-Vector<touchEvent> TouchTapEvents;
-int processMultipleTouches();
-
-
-//------------------------------------------------------------------------------
-//
-// This function gets the standard ASCII code corresponding to our key code
-// and the existing modifier key state.
-//
-//------------------------------------------------------------------------------
-struct AsciiData
-{
-   struct KeyData
-   {
-      U16   ascii;
-      bool  isDeadChar;
-   };
-
-   KeyData upper;
-   KeyData lower;
-   KeyData goofy;
-};
-
-
-#define NUM_KEYS ( KEY_OEM_102 + 1 )
-#define KEY_FIRST KEY_ESCAPE
-static AsciiData AsciiTable[NUM_KEYS];
-
-void Input::enableMouse()
-{
-    // Do nothing on iOS
-}
-
-void Input::disableMouse()
-{
-    // Do nothing on iOS
-}
-
-void Input::enableKeyboard()
-{
-    // Do nothing on iOS
-}
-
-void Input::disableKeyboard()
-{
-    // Do nothing on iOS
-}
-
-bool Input::isMouseEnabled()
-{
-    return true;
-}
-
-bool Input::isKeyboardEnabled()
-{
-    return false;
-}
- 
-//--------------------------------------------------------------------------
-void Input::init()
-{
-    Con::printf( "Input Init:" );
-   destroy();
-
-   smManager = NULL;
-	//smManager = new iOSInputManager();
-   smActive = false;
-
-   // stop the double-cursor thing
-   Con::setBoolVariable("$pref::Gui::noClampTorqueCursorToWindow", true);
-   
-   // enable main input
-   Input::enable();
-
-   // Startup the Cursor Manager
-   if(!smCursorManager)
-   {
-      smCursorManager = new CursorManager();
-      if(smCursorManager)
-      {
-         // Add the arrow cursor to the stack
-         smCursorManager->pushCursor(CursorManager::curArrow);
-      }
-      else
-      {
-         Con::printf("   Cursor Manager not enabled.");
-      }
-   }
-	
-	
-	for(int i = 0 ; i < MAX_TOUCH_EVENTS; i++ )
-	{
-		lastTouches[i].lastX = -1;
-		lastTouches[i].lastY = -1;
-	}
-	
-	
-   
-   
-   Con::printf( "" );
-}
-
-//------------------------------------------------------------------------------
-ConsoleFunction( isJoystickDetected, bool, 1, 1, "Always false on the iOS." )
-{
-/*
-   argc; argv;
-   return( DInputDevice::joystickDetected() );
-*/
-   return(false);
-}
-
-//------------------------------------------------------------------------------
-ConsoleFunction( getJoystickAxes, const char*, 2, 2, "(handle instance)" )
-{
-
-   return( "" );
-}
-
-//------------------------------------------------------------------------------
-static void fillAsciiTable()
-{
-
-}
-
-//------------------------------------------------------------------------------
-U16 Input::getKeyCode( U16 asciiCode )
-{
-   U16 keyCode = 0;
-   U16 i;
-   
-   // This is done three times so the lowerkey will always
-   // be found first. Some foreign keyboards have duplicate
-   // chars on some keys.
-   for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
-   {
-      if ( AsciiTable[i].lower.ascii == asciiCode )
-      {
-         keyCode = i;
-         break;
-      };
-   }
-
-   for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
-   {
-      if ( AsciiTable[i].upper.ascii == asciiCode )
-      {
-         keyCode = i;
-         break;
-      };
-   }
-
-   for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
-   {
-      if ( AsciiTable[i].goofy.ascii == asciiCode )
-      {
-         keyCode = i;
-         break;
-      };
-   }
-
-   return( keyCode );
-}
-
-//------------------------------------------------------------------------------
-U16 Input::getAscii( U16 keyCode, KEY_STATE keyState )
-{
-   if ( keyCode >= NUM_KEYS )
-      return 0;
-
-   switch ( keyState )
-   {
-      case STATE_LOWER:
-         return AsciiTable[keyCode].lower.ascii;
-      case STATE_UPPER:
-         return AsciiTable[keyCode].upper.ascii;
-      case STATE_GOOFY:
-         return AsciiTable[keyCode].goofy.ascii;
-      default:
-         return(0);
-            
-   }
-}
-
-//------------------------------------------------------------------------------
-void Input::destroy()
-{
-   // turn us off.
-   if (gInputEnabled)
-      disable();
-   
-   if ( smManager && smManager->isEnabled() )
-   {
-      smManager->disable();
-      delete smManager;
-      smManager = NULL;
-   }
-}
-
-//------------------------------------------------------------------------------
-bool Input::enable()
-{
-	Con::printf( "[]Input::enable." );
-
-   gInputEnabled = true;
-
-   if ( smManager && !smManager->isEnabled() )
-      return( smManager->enable() );
-
-   enableMouse();
-   //enableKeyboard();
-
-   return( gInputEnabled );
-}
-
-//------------------------------------------------------------------------------
-void Input::disable()
-{
-	Con::printf( "[]Input::disable." );
-
-   gInputEnabled = false;
-
-  if ( smManager && smManager->isEnabled() )
-      smManager->disable();
-
-   disableMouse();
-   //disableKeyboard();
-}
-
-//------------------------------------------------------------------------------
-void Input::activate()
-{
-   smActive = true;
-
-   enableMouse();
-// enableKeyboard();
-}
-
-//------------------------------------------------------------------------------
-void Input::deactivate()
-{
-//Con::printf( "[]Input::deactivate." );
-
-   deactivateMouse();
-   //deactivateKeyboard();
-
-   smActive = false;
-
-}
-
-//------------------------------------------------------------------------------
-void Input::reactivate()
-{
-   // don't think mac needs to do anything right now!!!!!! TBD
-   
-   // This is soo hacky...
-//   SetForegroundWindow( winState.appWindow );
-//   PostMessage( winState.appWindow, WM_ACTIVATE, WA_ACTIVE, NULL );
-}
-
-//------------------------------------------------------------------------------
-bool Input::isEnabled()
-{
-   if ( smManager )
-      return smManager->isEnabled();
-
-   return(gInputEnabled);
-}
-
-//------------------------------------------------------------------------------
-bool Input::isActive()
-{
-   return smActive;
-}
-
-//------------------------------------------------------------------------------
-void Input::process()
-{
-	//only gets called once per frame, create touches and accelerometer events here
-	//post, then pop each event
-
-	if(platState.multipleTouchesEnabled) processMultipleTouches();
-	
-   if (!smActive || !gInputEnabled)
-      return;
-
-   if (!gMouseEnabled || !gMouseActive)
-      return;
-      
- 
-   if ( smManager && smManager->isEnabled() && smActive )
-      smManager->process();
-}
-
-//------------------------------------------------------------------------------
-InputManager* Input::getManager()
-{
-   return( smManager );
-}
-
-
-//--------------------------------------------------------------------------
-//#pragma message("input remap table might need tweaking - rumors of ibooks having diff virt keycodes, might need intermediate remap...")
-static U8 VcodeRemap[256] =
-{
-KEY_A,                     // 0x00 
-KEY_S,                     // 0x01 
-KEY_D,                     // 0x02 
-KEY_F,                     // 0x03 
-KEY_H,                     // 0x04 
-KEY_G,                     // 0x05 
-KEY_Z,                     // 0x06 
-KEY_X,                     // 0x07 
-KEY_C,                     // 0x08 
-KEY_V,                     // 0x09 
-KEY_Y,                     // 0x0A       // this is questionable - not normal Y code
-KEY_B,                     // 0x0B 
-KEY_Q,                     // 0x0C 
-KEY_W,                     // 0x0D 
-KEY_E,                     // 0x0E 
-KEY_R,                     // 0x0F 
-KEY_Y,                     // 0x10 
-KEY_T,                     // 0x11 
-KEY_1,                     // 0x12 
-KEY_2,                     // 0x13 
-KEY_3,                     // 0x14 
-KEY_4,                     // 0x15 
-KEY_6,                     // 0x16 
-KEY_5,                     // 0x17 
-KEY_EQUALS,                // 0x18 
-KEY_9,                     // 0x19 
-KEY_7,                     // 0x1A 
-KEY_MINUS,                 // 0x1B 
-KEY_8,                     // 0x1C 
-KEY_0,                     // 0x1D 
-KEY_RBRACKET,              // 0x1E 
-KEY_O,                     // 0x1F 
-KEY_U,                     // 0x20 
-KEY_LBRACKET,              // 0x21 
-KEY_I,                     // 0x22 
-KEY_P,                     // 0x23 
-KEY_RETURN,                // 0x24 
-KEY_L,                     // 0x25 
-KEY_J,                     // 0x26 
-KEY_APOSTROPHE,            // 0x27 
-KEY_K,                     // 0x28 
-KEY_SEMICOLON,             // 0x29 
-KEY_BACKSLASH,             // 0x2A 
-KEY_COMMA,                 // 0x2B 
-KEY_SLASH,                 // 0x2C 
-KEY_N,                     // 0x2D 
-KEY_M,                     // 0x2E 
-KEY_PERIOD,                // 0x2F 
-KEY_TAB,                   // 0x30 
-KEY_SPACE,                 // 0x31 
-KEY_TILDE,                 // 0x32 
-KEY_BACKSPACE,             // 0x33 
-0,                         // 0x34 //?
-KEY_ESCAPE,                // 0x35 
-0,                         // 0x36 //?
-KEY_ALT,                   // 0x37 // best mapping for mac Cmd key
-KEY_LSHIFT,                // 0x38 
-KEY_CAPSLOCK,              // 0x39 
-KEY_MAC_OPT,               // 0x3A // direct map mac Option key -- better than KEY_WIN_WINDOWS
-KEY_CONTROL,               // 0x3B 
-KEY_RSHIFT,                // 0x3C 
-0,                         // 0x3D 
-0,                         // 0x3E 
-0,                         // 0x3F 
-0,                         // 0x40 
-KEY_DECIMAL,               // 0x41 
-0,                         // 0x42 
-KEY_MULTIPLY,              // 0x43 
-0,                         // 0x44 
-KEY_ADD,                   // 0x45 
-KEY_SUBTRACT,              // 0x46 // secondary code?
-KEY_NUMLOCK,               // 0x47 // also known as Clear on mac...
-KEY_SEPARATOR,             // 0x48 // secondary code? for KPEqual
-0,                         // 0x49 
-0,                         // 0x4A 
-KEY_DIVIDE,                // 0x4B 
-KEY_NUMPADENTER,           // 0x4C 
-KEY_DIVIDE,                // 0x4D // secondary code?
-KEY_SUBTRACT,              // 0x4E 
-0,                         // 0x4F 
-0,                         // 0x50 
-KEY_SEPARATOR,             // 0x51 // WHAT IS SEP?  This is KPEqual on mac.
-KEY_NUMPAD0,               // 0x52 
-KEY_NUMPAD1,               // 0x53 
-KEY_NUMPAD2,               // 0x54 
-KEY_NUMPAD3,               // 0x55 
-KEY_NUMPAD4,               // 0x56 
-KEY_NUMPAD5,               // 0x57 
-KEY_NUMPAD6,               // 0x58 
-KEY_NUMPAD7,               // 0x59 
-0,                         // 0x5A 
-KEY_NUMPAD8,               // 0x5B 
-KEY_NUMPAD9,               // 0x5C 
-0,                         // 0x5D 
-0,                         // 0x5E 
-0,                         // 0x5F 
-KEY_F5,                    // 0x60 
-KEY_F6,                    // 0x61 
-KEY_F7,                    // 0x62 
-KEY_F3,                    // 0x63 
-KEY_F8,                    // 0x64 
-KEY_F9,                    // 0x65 
-0,                         // 0x66 
-KEY_F11,                   // 0x67 
-0,                         // 0x68 
-KEY_PRINT,                 // 0x69 
-0,                         // 0x6A 
-KEY_SCROLLLOCK,            // 0x6B 
-0,                         // 0x6C 
-KEY_F10,                   // 0x6D 
-0,                         // 0x6E 
-KEY_F12,                   // 0x6F 
-0,                         // 0x70 
-KEY_PAUSE,                 // 0x71 
-KEY_INSERT,                // 0x72 // also known as mac Help
-KEY_HOME,                  // 0x73 
-KEY_PAGE_UP,               // 0x74 
-KEY_DELETE,                // 0x75 // FwdDel
-KEY_F4,                    // 0x76 
-KEY_END,                   // 0x77 
-KEY_F2,                    // 0x78 
-KEY_PAGE_DOWN,             // 0x79 
-KEY_F1,                    // 0x7A 
-KEY_LEFT,                  // 0x7B 
-KEY_RIGHT,                 // 0x7C 
-KEY_DOWN,                  // 0x7D 
-KEY_UP,                    // 0x7E 
-0,                         // 0x7F 
-0,                         // 0x80 
-0,                         // 0x81 
-0,                         // 0x82 
-0,                         // 0x83 
-0,                         // 0x84 
-0,                         // 0x85 
-0,                         // 0x86 
-0,                         // 0x87 
-0,                         // 0x88 
-0,                         // 0x89 
-0,                         // 0x8A 
-0,                         // 0x8B 
-0,                         // 0x8C 
-0,                         // 0x8D 
-0,                         // 0x8E 
-0,                         // 0x8F 
-
-0,                         // 0x90 
-0,                         // 0x91 
-0,                         // 0x92 
-0,                         // 0x93 
-0,                         // 0x94 
-0,                         // 0x95 
-0,                         // 0x96 
-0,                         // 0x97 
-0,                         // 0x98 
-0,                         // 0x99 
-0,                         // 0x9A 
-0,                         // 0x9B 
-0,                         // 0x9C 
-0,                         // 0x9D 
-0,                         // 0x9E 
-0,                         // 0x9F 
-
-0,                         // 0xA0 
-0,                         // 0xA1 
-0,                         // 0xA2 
-0,                         // 0xA3 
-0,                         // 0xA4 
-0,                         // 0xA5 
-0,                         // 0xA6 
-0,                         // 0xA7 
-0,                         // 0xA8 
-0,                         // 0xA9 
-0,                         // 0xAA 
-0,                         // 0xAB 
-0,                         // 0xAC 
-0,                         // 0xAD 
-0,                         // 0xAE 
-0,                         // 0xAF 
-0,                         // 0xB0 
-0,                         // 0xB1 
-0,                         // 0xB2 
-0,                         // 0xB3 
-0,                         // 0xB4 
-0,                         // 0xB5 
-0,                         // 0xB6 
-0,                         // 0xB7 
-0,                         // 0xB8 
-0,                         // 0xB9 
-0,                         // 0xBA 
-0,                         // 0xBB 
-0,                         // 0xBC 
-0,                         // 0xBD 
-0,                         // 0xBE 
-0,                         // 0xBF 
-0,                         // 0xC0 
-0,                         // 0xC1 
-0,                         // 0xC2 
-0,                         // 0xC3 
-0,                         // 0xC4 
-0,                         // 0xC5 
-0,                         // 0xC6 
-0,                         // 0xC7 
-0,                         // 0xC8 
-0,                         // 0xC9 
-0,                         // 0xCA 
-0,                         // 0xCB 
-0,                         // 0xCC 
-0,                         // 0xCD 
-0,                         // 0xCE 
-0,                         // 0xCF 
-0,                         // 0xD0 
-0,                         // 0xD1 
-0,                         // 0xD2 
-0,                         // 0xD3 
-0,                         // 0xD4 
-0,                         // 0xD5 
-0,                         // 0xD6 
-0,                         // 0xD7 
-0,                         // 0xD8 
-0,                         // 0xD9 
-0,                         // 0xDA 
-0,                         // 0xDB 
-0,                         // 0xDC 
-0,                         // 0xDD 
-0,                         // 0xDE 
-0,                         // 0xDF 
-0,                         // 0xE0 
-0,                         // 0xE1 
-0,                         // 0xE2 
-0,                         // 0xE3 
-0,                         // 0xE4 
-
-0,                         // 0xE5 
-
-0,                         // 0xE6 
-0,                         // 0xE7 
-0,                         // 0xE8 
-0,                         // 0xE9 
-0,                         // 0xEA 
-0,                         // 0xEB 
-0,                         // 0xEC 
-0,                         // 0xED 
-0,                         // 0xEE 
-0,                         // 0xEF 
-   
-0,                         // 0xF0 
-0,                         // 0xF1 
-0,                         // 0xF2 
-0,                         // 0xF3 
-0,                         // 0xF4 
-0,                         // 0xF5 
-   
-0,                         // 0xF6 
-0,                         // 0xF7 
-0,                         // 0xF8 
-0,                         // 0xF9 
-0,                         // 0xFA 
-0,                         // 0xFB 
-0,                         // 0xFC 
-0,                         // 0xFD 
-0,                         // 0xFE 
-0                          // 0xFF 
-};   
-
-
-U8 TranslateOSKeyCode(U8 vcode)
-{
-   return VcodeRemap[vcode];   
-}   
-
-#pragma mark ---- Clipboard functions ----
-//-----------------------------------------------------------------------------
-const char* Platform::getClipboard()
-{
-	return NULL;//no clipboard on iOS
-}
-
-//-----------------------------------------------------------------------------
-bool Platform::setClipboard(const char *text)
-{
-	return NULL;//no clipboard on iOS
-}
-
-#pragma mark ---- Cursor Functions ----
-//------------------------------------------------------------------------------
-void Input::pushCursor(S32 cursorID)
-{
-   CursorManager* cm = getCursorManager();
-   if(cm)
-      cm->pushCursor(cursorID);
-}
-
-//------------------------------------------------------------------------------
-void Input::popCursor()
-{
-   CursorManager* cm = getCursorManager();
-   if(cm)
-      cm->popCursor();
-}
-
-//------------------------------------------------------------------------------
-void Input::refreshCursor()
-{
-   CursorManager* cm = getCursorManager();
-   if(cm)
-      cm->refreshCursor();
-}
-
-#pragma mark ---- DoubleClick Functions ----
-//------------------------------------------------------------------------------
-U32 Input::getDoubleClickTime()
-{
-	return IOS_DOUBLE_CLICK_TIME;
-}
-
-//------------------------------------------------------------------------------
-S32 Input::getDoubleClickWidth()
-{
-   // this is an arbitrary value.
-   return 10;
-}
-
-//------------------------------------------------------------------------------
-S32 Input::getDoubleClickHeight()
-{
-   return getDoubleClickWidth();
-}
-
-#pragma mark -
-
-//------------------------------------------------------------------------------
-bool enableKeyboard()
-{
-   if ( !gInputEnabled )
-      return( false );
-
-   if ( gKBEnabled && gKBActive )
-      return( true );
-
-   gKBEnabled = true;
-   if ( Input::isActive() )
-      gKBEnabled = activateKeyboard();
-
-   if ( gKBEnabled )
-   {
-      Con::printf( "Hardware-direct keyboard enabled." );
-   }
-   else
-   {
-      Con::warnf( "Hardware-direct keyboard failed to enable!" );
-   }
-
-   return( gKBEnabled );
-}
-
-//------------------------------------------------------------------------------
-void disableKeyboard()
-{
-   if ( !gInputEnabled || !gKBEnabled )
-      return;
-
-   deactivateKeyboard();
-   gKBEnabled = false;
-
-   Con::printf( "Hardware-direct keyboard disabled." );
-}
-
-//------------------------------------------------------------------------------
-bool activateKeyboard()
-{
-   if ( !gInputEnabled || !Input::isActive() || !gKBEnabled )
-      return( false );
-
-   OSStatus status = noErr;
-   if (status==noErr)
-      gKBActive = true;
-
-   return( gKBActive );
-}
-
-//------------------------------------------------------------------------------
-void deactivateKeyboard()
-{
-   if ( gInputEnabled && gKBActive )
-   {
-      gKBActive = false;
-   }
-}
-
-//------------------------------------------------------------------------------
-bool enableMouse()
-{
-   if ( !gInputEnabled )
-      return( false );
-
-   if ( gMouseEnabled && gMouseActive )
-      return( true );
-
-   gMouseEnabled = activateMouse();
-
-   return( gMouseEnabled );
-}
-
-//------------------------------------------------------------------------------
-void disableMouse()
-{
-   if ( !gInputEnabled || !gMouseEnabled )
-      return;
-
-   deactivateMouse();
-   gMouseEnabled = false;
-
-   bool hwMouse = false;
-   Con::printf( "%s disabled", hwMouse?"Hardware-direct mouse":"Basic mouse capture");
-}
-
-//------------------------------------------------------------------------------
-bool activateMouse()
-{
-   if ( !gInputEnabled || !Input::isActive() || !gMouseEnabled )
-      return( false );
-   
-   if (gMouseActive)
-      return(true);
-
-   gMouseActive = true;
-
-   return( gMouseActive );
-}
-
-//------------------------------------------------------------------------------
-void deactivateMouse()
-{
-   if ( !gInputEnabled || !gMouseActive )
-       return;
-   
-   gMouseActive = false;
-}
-
-
-//------------------------------------------------------------------------------
-ConsoleFunction( enableMouse, bool, 1, 1, "enableMouse()" )
-{
-   return( enableMouse() );
-}
-
-//------------------------------------------------------------------------------
-ConsoleFunction( disableMouse, void, 1, 1, "disableMouse()" )
-{
-   disableMouse();
-}
-
-//------------------------------------------------------------------------------
-void printInputState(void)
-{
-   if ( gInputEnabled )
-   {
-         Con::printf( "Low-level input system is enabled." );
-      
-      Con::printf( "- Keyboard is %sabled and %sactive.", 
-            gKBEnabled ? "en" : "dis",
-            gKBActive ? "" : "in" );
-      Con::printf( "- Mouse is %sabled and %sactive.", 
-            gMouseEnabled ? "en" : "dis",
-            gMouseActive ? "" : "in" );
-/*
-      Con::printf( "- Joystick is %sabled and %sactive.", 
-            gJoystickEnabled() ? "en" : "dis",
-            gJoystickActive() ? "" : "in" );
-*/
-   }
-   else
-   {
-      Con::printf( "Low-level input system is disabled." );
-   }
-}
-
-//------------------------------------------------------------------------------
-ConsoleFunction( echoInputState, void, 1, 1, "echoInputState()" )
-{
-   printInputState();
-}
-
-//------------------------------------------------------------------------------
-ConsoleFunction( toggleInputState, void, 1, 1, "toggleInputState()" )
-{
-   if (gInputEnabled)
-      Input::disable();
-   else
-      Input::enable();
-
-   printInputState();
-}
-
-//------------------------------------------------------------------------------
-ConsoleFunction( deactivateKeyboard, void, 1, 1, "deactivateKeyboard();")
-{
-   // these are only useful on the windows side. They deal with some vagaries of win32 DirectInput.
-}
-
-ConsoleFunction( activateKeyboard, void, 1, 1, "activateKeyboard();")
-{
-   // these are only useful on the windows side. They deal with some vagaries of win32 DirectInput.
-}
-
-
-//------------------------------------------------------------------------------
-void Input::setCursorPos(S32 x, S32 y)
-{
-	//this gets called from GuiCanvas to set the game mouse cursor
-}
-
-int processMultipleTouches()
-{	
-	char posX[256], posY[256], temp[10], touchNums[256];
-    
-	dMemset(posX, 0, sizeof(posX));
-    dMemset(posY, 0, sizeof(posY));
-    dMemset(touchNums, 0, sizeof(touchNums));
-
-	touchEvent *currentEvent;
-	
-	//Down Events
-	int numTouchDownEvents = TouchDownEvents.size();
-	while( TouchDownEvents.size() > 0 )
-    {
-		currentEvent = &TouchDownEvents.last();
-		dItoa( currentEvent->x, temp );
-		dStrcat( posX, temp );
-		dStrcat( posX, " " );
-		
-		dItoa( currentEvent->y, temp );
-		dStrcat( posY, temp );
-		dStrcat( posY, " " );
-		
-		dItoa( currentEvent->number, temp );
-		dStrcat( touchNums, temp );
-		dStrcat( touchNums, " " );
-		
-		TouchDownEvents.pop_back();
-	}
-	dItoa( numTouchDownEvents, temp );
-    
-    if( numTouchDownEvents > 0 )
-    {
-        InputEvent touchEvent;
-        
-        touchEvent.deviceInst = 0;
-        touchEvent.objInst = SI_TOUCHDOWN;
-        
-        touchEvent.deviceType = ScreenTouchDeviceType;
-        touchEvent.action = SI_TOUCH;
-        touchEvent.objType = SI_TOUCHDOWN;
-        
-        dStrcpy(touchEvent.touchesX, posX);
-        dStrcpy(touchEvent.touchesY, posY);
-        dStrcpy(touchEvent.touchIDs, touchNums);
-        
-        touchEvent.modifier = 0;
-        
-        Game->postEvent(touchEvent);        
-    }
-    
-    // Deprecated in 1.5
-	//if( numTouchDownEvents > 0 )
-    //    Con::executef( 4, "oniOSTouchDown", touchNums , posX, posY );
-
-	//Move events
-	int numTouchMoveEvents = TouchMoveEvents.size();
-	while( TouchMoveEvents.size() > 0 ) 
-    {
-		currentEvent = &TouchMoveEvents.last();
-		dItoa( currentEvent->x, temp );
-		dStrcat( posX, temp );
-		dStrcat( posX, " " );
-		
-		dItoa( currentEvent->y, temp );
-		dStrcat( posY, temp );
-		dStrcat( posY, " " );
-		
-		dItoa( currentEvent->number, temp );
-		dStrcat( touchNums, temp );
-		dStrcat( touchNums, " " );		
-		
-		TouchMoveEvents.pop_back();
-	}
-	dItoa( numTouchMoveEvents, temp );
-    
-    if( numTouchMoveEvents > 0 )
-    {
-        InputEvent touchEvent;
-        
-        touchEvent.deviceInst = 0;
-        touchEvent.objInst = SI_TOUCHMOVE;
-        
-        touchEvent.deviceType = ScreenTouchDeviceType;
-        touchEvent.action = SI_TOUCH;
-        touchEvent.objType = SI_TOUCHMOVE;
-        
-        dStrcpy(touchEvent.touchesX, posX);
-        dStrcpy(touchEvent.touchesY, posY);
-        dStrcpy(touchEvent.touchIDs, touchNums);
-        
-        touchEvent.modifier = 0;
-        
-        Game->postEvent(touchEvent);        
-    }
-    
-    // Deprecated in 1.5 -MP
-	//if( numTouchMoveEvents > 0 )
-    //    Con::executef( 4, "oniOSTouchMove", touchNums , posX, posY );
-	
-	//Up events
-	int numTouchUpEvents = TouchUpEvents.size();
-    
-    dMemset(posX, 0, sizeof(posX));
-    dMemset(posY, 0, sizeof(posY));
-    dMemset(touchNums, 0, sizeof(touchNums));
-    
-	while( TouchUpEvents.size() > 0 ) 
-    {
-		currentEvent = &TouchUpEvents.last();
-		dItoa( currentEvent->x, temp );
-		dStrcat( posX, temp );
-		dStrcat( posX, " " );
-		
-		dItoa( currentEvent->y, temp );
-		dStrcat( posY, temp );
-		dStrcat( posY, " " );
-		
-		dItoa( currentEvent->number, temp );
-		dStrcat( touchNums, temp );
-		dStrcat( touchNums, " " );		
-		
-		lastTouches[currentEvent->number].lastX = -1;
-		lastTouches[currentEvent->number].lastY	 = -1;
-		
-        int x;
-        x = -1;
-        
-        lastTouches[currentEvent->number].lastX = -1;
-		lastTouches[currentEvent->number].lastY	 = -1;
-        
-		TouchUpEvents.pop_back();
-	}
-    
-	dItoa( numTouchUpEvents, temp );
-	
-    if( numTouchUpEvents > 0 )
-    {
-        InputEvent touchEvent;
-        
-        touchEvent.deviceInst = 0;
-        touchEvent.objInst = SI_TOUCHUP;
-        
-        touchEvent.deviceType = ScreenTouchDeviceType;
-        touchEvent.action = SI_TOUCH;
-        touchEvent.objType = SI_TOUCHUP;
-        
-        dStrcpy(touchEvent.touchesX, posX);
-        dStrcpy(touchEvent.touchesY, posY);
-        dStrcpy(touchEvent.touchIDs, touchNums);
-        
-        touchEvent.modifier = 0;
-        
-        Game->postEvent(touchEvent);        
-    }
-    
-    // Deprecated in 1.5 -MP
-    //if( numTouchUpEvents > 0 )
-    //    Con::executef( 4, "oniOSTouchUp", touchNums , posX, posY );
-	
-	//Luma: Tap support
-	posX[0] = '\0';
-	posY[0] = '\0';
-    
-	int numTapEvents = TouchTapEvents.size();
-	
-    while( TouchTapEvents.size() > 0 ) 
-    {
-		currentEvent = &TouchTapEvents.last();
-		sprintf( temp, "%d ", currentEvent->x );
-		dStrcat( posX, temp );
-		
-		sprintf( temp, "%d ", currentEvent->y );
-		dStrcat( posY, temp );
-		
-		TouchTapEvents.pop_back();
-	}
-    
-	sprintf( temp, "%d", numTapEvents );
-    
-	//if( numTapEvents > 0 )
-    //    Con::executef( 4, "oniOSTouchTap", temp , posX, posY );
-	
-	return numTouchDownEvents + numTouchMoveEvents + numTouchUpEvents;
-}
-
-
-
-//we want these to only be called once per frame!!
-bool createMouseMoveEvent( S32 touchNumber, S32 x, S32 y, S32 lastX, S32 lastY ) //EFM
-{	
-	S32 currentSlot = -1;
-	
-	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )
-	{
-		if( (lastX == lastTouches[i].lastX ) &&
-		   (lastY == lastTouches[i].lastY ) )
-		{
-			currentSlot = i;
-		}
-	}
-
-	if( currentSlot == -1 ) return false;
-	
-	ScreenTouchEvent event;
-	event.xPos = x;
-	event.yPos = y;
-	event.action = SI_MOVE;
-	event.touchID = currentSlot;
-    event.numTouches = 0;
-    
-	//Luma: Mouse not moving (no hover for mouse fingers!)
-	Canvas->setCursorPos( Point2I( x, y ) );  
-
-	if( currentSlot != -1 )
-	{
-		lastTouches[currentSlot].lastX = x;
-		lastTouches[currentSlot].lastY = y;
-	}		
-	
-	TouchMoveEvents.push_back( touchEvent( currentSlot, x, y ) );	
-	Game->postEvent(event);
-	
-	return true;//return false if we get bad values or something
-}
-
-
-bool createMouseDownEvent( S32 touchNumber, S32 x, S32 y, U32 numTouches ) 
-{
-	S32 vacantSlot = -1;
-	
-	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (vacantSlot == -1) ; i++ )
-	{
-		if( lastTouches[i].lastX == -1 )
-		{
-			vacantSlot = i;
-		}
-	}
-	
-	if( vacantSlot == -1 ) 
-        return false;
-		
-	ScreenTouchEvent event;
-	event.xPos = x;
-	event.yPos = y;
-    event.touchID = vacantSlot;
-	event.action = SI_MAKE;
-	event.numTouches = numTouches;
-    
-	//Luma: Update position
-	Canvas->setCursorPos( Point2I( x, y ) );  		
-	
-	if( vacantSlot != -1 )
-	{
-		lastTouches[vacantSlot].lastX = x;
-		lastTouches[vacantSlot].lastY = y;
-	}	
-
-	TouchDownEvents.push_back( touchEvent( vacantSlot, x, y ) );
-	Game->postEvent(event);
-	
-	return true;//return false if we get bad values or something
-}
-
-bool createMouseUpEvent( S32 touchNumber, S32 x, S32 y, S32 lastX, S32 lastY, U32 numTouches ) //EFM
-{	
-	S32 currentSlot = -1;
-	
-	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )
-	{
-		if(( (x == lastTouches[i].lastX) && (y == lastTouches[i].lastY )) ||
-		   ( (lastX == lastTouches[i].lastX ) && (lastY == lastTouches[i].lastY )))
-		{
-			currentSlot = i;
-		}	
-	}
-	
-	if( currentSlot == -1 ) 
-        return false;
-
-	ScreenTouchEvent event;
-	event.xPos = x;
-	event.yPos = y;
-	event.action = SI_BREAK;
-	event.touchID = currentSlot;
-	event.numTouches = numTouches;
-    
-	TouchUpEvents.push_back( touchEvent( currentSlot, x, y ) );	
-	
-	Game->postEvent(event);
-	
-	return true;//return false if we get bad values or something
-}
-
-void clearPendingMultitouchEvents( void ) //EFM
-{	
-    for( int i = 0 ; i < MAX_TOUCH_EVENTS ; i++ )
-	{
-		lastTouches[i].lastX = -1;
-		lastTouches[i].lastY = -1;
-	}
-
-	TouchMoveEvents.clear();
-	TouchDownEvents.clear();
-	TouchUpEvents.clear();
-}
-
-
-//Luma: Tap support
-void createMouseTapEvent( S32 nbrTaps, S32 x, S32 y ) {
-
-	TouchTapEvents.push_back( touchEvent( nbrTaps, x, y ) );
-}
-
-
-// 0 = x, 1 = y, 2 = z
-UIAccelerationValue g_lastAccel[3];
-
-// PUAP -Mat this is polled at AccelerometerUpdateMS, which should be set at around 33 
-/*
-bool createAccelMoveEvent( UIAccelerationValue *accel ) {
-	bool returnVal = false;
-	
-	U32 axis[3] = { SI_XAXIS, SI_YAXIS, SI_ZAXIS }; 
-	
-	for( int i = 0; i < 3; i++ ) {
-		if(accel[i]  != g_lastAccel[i] ) {
-			InputEvent event;
-			event.deviceInst = 0;//joystick number
-			event.fValue = accel[i];
-			event.deviceType = JoystickDeviceType;
-			event.objType = axis[i];
-			event.objInst = i;//axis number
-			event.action = SI_MOVE;
-			event.modifier = 0;
-			Game->postEvent(event);
-			g_lastAccel[i]  = accel[i];
-			returnVal = true;
-		}
-	}
-	return false;
-}
-*/
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+
+#include "platformiOS/platformiOS.h"
+#include "platformiOS/iOSUtil.h"
+#include "platform/platformInput.h"
+#include "platform/event.h"
+#include "console/console.h"
+#include "game/gameInterface.h"
+#include "string/Unicode.h"
+#include "gui/guiCanvas.h"
+
+
+// <Mat> just some random number 50, we'll get a proper value later
+#define IOS_DOUBLE_CLICK_TIME	( 50 * 60.0f * 1000.0f)
+
+// Static class variables:
+InputManager* Input::smManager;
+bool           Input::smActive;
+CursorManager* Input::smCursorManager = 0;
+
+
+bool gInputEnabled = false;
+bool gMouseEnabled = false;
+bool gKBEnabled = false;
+bool gMouseActive = false;
+bool gKBActive = false;
+
+//------------------------------------------------------------------------------
+// Helper functions.  Should migrate to an InputManager object at some point.
+bool enableKeyboard(void);
+void disableKeyboard(void);
+bool activateKeyboard(void);
+void deactivateKeyboard(void);
+bool enableMouse(void);
+void disableMouse(void);
+bool activateMouse(void);
+void deactivateMouse(void);
+
+
+
+static void fillAsciiTable();
+
+
+struct touchEvent {
+	S32 number;
+	S32 x;
+	S32 y;
+	touchEvent( S32 a, S32 b, S32 c ) {
+		number = a;
+		x = b;
+		y = c;
+	}
+};
+
+
+Vector<touchEvent> TouchMoveEvents;//<Mat> to make sure we don't have multiple events per frame
+Vector<touchEvent> TouchDownEvents;
+Vector<touchEvent> TouchUpEvents;
+
+// EFM - BEGIN TOUCH CHANGES
+#define MAX_TOUCH_EVENTS 5
+
+struct touchTracker {
+	S32 lastX;
+	S32 lastY;
+	Vector<touchEvent> downEvents;
+	Vector<touchEvent> moveEvents;
+	Vector<touchEvent> upEvents;
+};
+
+touchTracker CombinedTouchEvents[MAX_TOUCH_EVENTS];
+
+struct touchCorrelation {
+	S32 lastX;
+	S32 lastY;
+};
+
+touchCorrelation lastTouches[MAX_TOUCH_EVENTS];
+
+// EFM - END TOUCH CHANGES
+
+//Luma: Tap support
+Vector<touchEvent> TouchTapEvents;
+int processMultipleTouches();
+
+
+//------------------------------------------------------------------------------
+//
+// This function gets the standard ASCII code corresponding to our key code
+// and the existing modifier key state.
+//
+//------------------------------------------------------------------------------
+struct AsciiData
+{
+   struct KeyData
+   {
+      U16   ascii;
+      bool  isDeadChar;
+   };
+
+   KeyData upper;
+   KeyData lower;
+   KeyData goofy;
+};
+
+
+#define NUM_KEYS ( KEY_OEM_102 + 1 )
+#define KEY_FIRST KEY_ESCAPE
+static AsciiData AsciiTable[NUM_KEYS];
+
+void Input::enableMouse()
+{
+    // Do nothing on iOS
+}
+
+void Input::disableMouse()
+{
+    // Do nothing on iOS
+}
+
+void Input::enableKeyboard()
+{
+    // Do nothing on iOS
+}
+
+void Input::disableKeyboard()
+{
+    // Do nothing on iOS
+}
+
+bool Input::isMouseEnabled()
+{
+    return true;
+}
+
+bool Input::isKeyboardEnabled()
+{
+    return false;
+}
+ 
+//--------------------------------------------------------------------------
+void Input::init()
+{
+    Con::printf( "Input Init:" );
+   destroy();
+
+   smManager = NULL;
+	//smManager = new iOSInputManager();
+   smActive = false;
+
+   // stop the double-cursor thing
+   Con::setBoolVariable("$pref::Gui::noClampTorqueCursorToWindow", true);
+   
+   // enable main input
+   Input::enable();
+
+   // Startup the Cursor Manager
+   if(!smCursorManager)
+   {
+      smCursorManager = new CursorManager();
+      if(smCursorManager)
+      {
+         // Add the arrow cursor to the stack
+         smCursorManager->pushCursor(CursorManager::curArrow);
+      }
+      else
+      {
+         Con::printf("   Cursor Manager not enabled.");
+      }
+   }
+	
+	
+	for(int i = 0 ; i < MAX_TOUCH_EVENTS; i++ )
+	{
+		lastTouches[i].lastX = -1;
+		lastTouches[i].lastY = -1;
+	}
+	
+	
+   
+   
+   Con::printf( "" );
+}
+
+//------------------------------------------------------------------------------
+ConsoleFunction( isJoystickDetected, bool, 1, 1, "Always false on the iOS." )
+{
+/*
+   argc; argv;
+   return( DInputDevice::joystickDetected() );
+*/
+   return(false);
+}
+
+//------------------------------------------------------------------------------
+ConsoleFunction( getJoystickAxes, const char*, 2, 2, "(handle instance)" )
+{
+
+   return( "" );
+}
+
+//------------------------------------------------------------------------------
+static void fillAsciiTable()
+{
+
+}
+
+//------------------------------------------------------------------------------
+U16 Input::getKeyCode( U16 asciiCode )
+{
+   U16 keyCode = 0;
+   U16 i;
+   
+   // This is done three times so the lowerkey will always
+   // be found first. Some foreign keyboards have duplicate
+   // chars on some keys.
+   for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
+   {
+      if ( AsciiTable[i].lower.ascii == asciiCode )
+      {
+         keyCode = i;
+         break;
+      };
+   }
+
+   for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
+   {
+      if ( AsciiTable[i].upper.ascii == asciiCode )
+      {
+         keyCode = i;
+         break;
+      };
+   }
+
+   for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
+   {
+      if ( AsciiTable[i].goofy.ascii == asciiCode )
+      {
+         keyCode = i;
+         break;
+      };
+   }
+
+   return( keyCode );
+}
+
+//------------------------------------------------------------------------------
+U16 Input::getAscii( U16 keyCode, KEY_STATE keyState )
+{
+   if ( keyCode >= NUM_KEYS )
+      return 0;
+
+   switch ( keyState )
+   {
+      case STATE_LOWER:
+         return AsciiTable[keyCode].lower.ascii;
+      case STATE_UPPER:
+         return AsciiTable[keyCode].upper.ascii;
+      case STATE_GOOFY:
+         return AsciiTable[keyCode].goofy.ascii;
+      default:
+         return(0);
+            
+   }
+}
+
+//------------------------------------------------------------------------------
+void Input::destroy()
+{
+   // turn us off.
+   if (gInputEnabled)
+      disable();
+   
+   if ( smManager && smManager->isEnabled() )
+   {
+      smManager->disable();
+      delete smManager;
+      smManager = NULL;
+   }
+}
+
+//------------------------------------------------------------------------------
+bool Input::enable()
+{
+	Con::printf( "[]Input::enable." );
+
+   gInputEnabled = true;
+
+   if ( smManager && !smManager->isEnabled() )
+      return( smManager->enable() );
+
+   enableMouse();
+   //enableKeyboard();
+
+   return( gInputEnabled );
+}
+
+//------------------------------------------------------------------------------
+void Input::disable()
+{
+	Con::printf( "[]Input::disable." );
+
+   gInputEnabled = false;
+
+  if ( smManager && smManager->isEnabled() )
+      smManager->disable();
+
+   disableMouse();
+   //disableKeyboard();
+}
+
+//------------------------------------------------------------------------------
+void Input::activate()
+{
+   smActive = true;
+
+   enableMouse();
+// enableKeyboard();
+}
+
+//------------------------------------------------------------------------------
+void Input::deactivate()
+{
+//Con::printf( "[]Input::deactivate." );
+
+   deactivateMouse();
+   //deactivateKeyboard();
+
+   smActive = false;
+
+}
+
+//------------------------------------------------------------------------------
+void Input::reactivate()
+{
+   // don't think mac needs to do anything right now!!!!!! TBD
+   
+   // This is soo hacky...
+//   SetForegroundWindow( winState.appWindow );
+//   PostMessage( winState.appWindow, WM_ACTIVATE, WA_ACTIVE, NULL );
+}
+
+//------------------------------------------------------------------------------
+bool Input::isEnabled()
+{
+   if ( smManager )
+      return smManager->isEnabled();
+
+   return(gInputEnabled);
+}
+
+//------------------------------------------------------------------------------
+bool Input::isActive()
+{
+   return smActive;
+}
+
+//------------------------------------------------------------------------------
+void Input::process()
+{
+	//only gets called once per frame, create touches and accelerometer events here
+	//post, then pop each event
+
+	if(platState.multipleTouchesEnabled) processMultipleTouches();
+	
+   if (!smActive || !gInputEnabled)
+      return;
+
+   if (!gMouseEnabled || !gMouseActive)
+      return;
+      
+ 
+   if ( smManager && smManager->isEnabled() && smActive )
+      smManager->process();
+}
+
+//------------------------------------------------------------------------------
+InputManager* Input::getManager()
+{
+   return( smManager );
+}
+
+
+//--------------------------------------------------------------------------
+//#pragma message("input remap table might need tweaking - rumors of ibooks having diff virt keycodes, might need intermediate remap...")
+static U8 VcodeRemap[256] =
+{
+KEY_A,                     // 0x00 
+KEY_S,                     // 0x01 
+KEY_D,                     // 0x02 
+KEY_F,                     // 0x03 
+KEY_H,                     // 0x04 
+KEY_G,                     // 0x05 
+KEY_Z,                     // 0x06 
+KEY_X,                     // 0x07 
+KEY_C,                     // 0x08 
+KEY_V,                     // 0x09 
+KEY_Y,                     // 0x0A       // this is questionable - not normal Y code
+KEY_B,                     // 0x0B 
+KEY_Q,                     // 0x0C 
+KEY_W,                     // 0x0D 
+KEY_E,                     // 0x0E 
+KEY_R,                     // 0x0F 
+KEY_Y,                     // 0x10 
+KEY_T,                     // 0x11 
+KEY_1,                     // 0x12 
+KEY_2,                     // 0x13 
+KEY_3,                     // 0x14 
+KEY_4,                     // 0x15 
+KEY_6,                     // 0x16 
+KEY_5,                     // 0x17 
+KEY_EQUALS,                // 0x18 
+KEY_9,                     // 0x19 
+KEY_7,                     // 0x1A 
+KEY_MINUS,                 // 0x1B 
+KEY_8,                     // 0x1C 
+KEY_0,                     // 0x1D 
+KEY_RBRACKET,              // 0x1E 
+KEY_O,                     // 0x1F 
+KEY_U,                     // 0x20 
+KEY_LBRACKET,              // 0x21 
+KEY_I,                     // 0x22 
+KEY_P,                     // 0x23 
+KEY_RETURN,                // 0x24 
+KEY_L,                     // 0x25 
+KEY_J,                     // 0x26 
+KEY_APOSTROPHE,            // 0x27 
+KEY_K,                     // 0x28 
+KEY_SEMICOLON,             // 0x29 
+KEY_BACKSLASH,             // 0x2A 
+KEY_COMMA,                 // 0x2B 
+KEY_SLASH,                 // 0x2C 
+KEY_N,                     // 0x2D 
+KEY_M,                     // 0x2E 
+KEY_PERIOD,                // 0x2F 
+KEY_TAB,                   // 0x30 
+KEY_SPACE,                 // 0x31 
+KEY_TILDE,                 // 0x32 
+KEY_BACKSPACE,             // 0x33 
+0,                         // 0x34 //?
+KEY_ESCAPE,                // 0x35 
+0,                         // 0x36 //?
+KEY_ALT,                   // 0x37 // best mapping for mac Cmd key
+KEY_LSHIFT,                // 0x38 
+KEY_CAPSLOCK,              // 0x39 
+KEY_MAC_OPT,               // 0x3A // direct map mac Option key -- better than KEY_WIN_WINDOWS
+KEY_CONTROL,               // 0x3B 
+KEY_RSHIFT,                // 0x3C 
+0,                         // 0x3D 
+0,                         // 0x3E 
+0,                         // 0x3F 
+0,                         // 0x40 
+KEY_DECIMAL,               // 0x41 
+0,                         // 0x42 
+KEY_MULTIPLY,              // 0x43 
+0,                         // 0x44 
+KEY_ADD,                   // 0x45 
+KEY_SUBTRACT,              // 0x46 // secondary code?
+KEY_NUMLOCK,               // 0x47 // also known as Clear on mac...
+KEY_SEPARATOR,             // 0x48 // secondary code? for KPEqual
+0,                         // 0x49 
+0,                         // 0x4A 
+KEY_DIVIDE,                // 0x4B 
+KEY_NUMPADENTER,           // 0x4C 
+KEY_DIVIDE,                // 0x4D // secondary code?
+KEY_SUBTRACT,              // 0x4E 
+0,                         // 0x4F 
+0,                         // 0x50 
+KEY_SEPARATOR,             // 0x51 // WHAT IS SEP?  This is KPEqual on mac.
+KEY_NUMPAD0,               // 0x52 
+KEY_NUMPAD1,               // 0x53 
+KEY_NUMPAD2,               // 0x54 
+KEY_NUMPAD3,               // 0x55 
+KEY_NUMPAD4,               // 0x56 
+KEY_NUMPAD5,               // 0x57 
+KEY_NUMPAD6,               // 0x58 
+KEY_NUMPAD7,               // 0x59 
+0,                         // 0x5A 
+KEY_NUMPAD8,               // 0x5B 
+KEY_NUMPAD9,               // 0x5C 
+0,                         // 0x5D 
+0,                         // 0x5E 
+0,                         // 0x5F 
+KEY_F5,                    // 0x60 
+KEY_F6,                    // 0x61 
+KEY_F7,                    // 0x62 
+KEY_F3,                    // 0x63 
+KEY_F8,                    // 0x64 
+KEY_F9,                    // 0x65 
+0,                         // 0x66 
+KEY_F11,                   // 0x67 
+0,                         // 0x68 
+KEY_PRINT,                 // 0x69 
+0,                         // 0x6A 
+KEY_SCROLLLOCK,            // 0x6B 
+0,                         // 0x6C 
+KEY_F10,                   // 0x6D 
+0,                         // 0x6E 
+KEY_F12,                   // 0x6F 
+0,                         // 0x70 
+KEY_PAUSE,                 // 0x71 
+KEY_INSERT,                // 0x72 // also known as mac Help
+KEY_HOME,                  // 0x73 
+KEY_PAGE_UP,               // 0x74 
+KEY_DELETE,                // 0x75 // FwdDel
+KEY_F4,                    // 0x76 
+KEY_END,                   // 0x77 
+KEY_F2,                    // 0x78 
+KEY_PAGE_DOWN,             // 0x79 
+KEY_F1,                    // 0x7A 
+KEY_LEFT,                  // 0x7B 
+KEY_RIGHT,                 // 0x7C 
+KEY_DOWN,                  // 0x7D 
+KEY_UP,                    // 0x7E 
+0,                         // 0x7F 
+0,                         // 0x80 
+0,                         // 0x81 
+0,                         // 0x82 
+0,                         // 0x83 
+0,                         // 0x84 
+0,                         // 0x85 
+0,                         // 0x86 
+0,                         // 0x87 
+0,                         // 0x88 
+0,                         // 0x89 
+0,                         // 0x8A 
+0,                         // 0x8B 
+0,                         // 0x8C 
+0,                         // 0x8D 
+0,                         // 0x8E 
+0,                         // 0x8F 
+
+0,                         // 0x90 
+0,                         // 0x91 
+0,                         // 0x92 
+0,                         // 0x93 
+0,                         // 0x94 
+0,                         // 0x95 
+0,                         // 0x96 
+0,                         // 0x97 
+0,                         // 0x98 
+0,                         // 0x99 
+0,                         // 0x9A 
+0,                         // 0x9B 
+0,                         // 0x9C 
+0,                         // 0x9D 
+0,                         // 0x9E 
+0,                         // 0x9F 
+
+0,                         // 0xA0 
+0,                         // 0xA1 
+0,                         // 0xA2 
+0,                         // 0xA3 
+0,                         // 0xA4 
+0,                         // 0xA5 
+0,                         // 0xA6 
+0,                         // 0xA7 
+0,                         // 0xA8 
+0,                         // 0xA9 
+0,                         // 0xAA 
+0,                         // 0xAB 
+0,                         // 0xAC 
+0,                         // 0xAD 
+0,                         // 0xAE 
+0,                         // 0xAF 
+0,                         // 0xB0 
+0,                         // 0xB1 
+0,                         // 0xB2 
+0,                         // 0xB3 
+0,                         // 0xB4 
+0,                         // 0xB5 
+0,                         // 0xB6 
+0,                         // 0xB7 
+0,                         // 0xB8 
+0,                         // 0xB9 
+0,                         // 0xBA 
+0,                         // 0xBB 
+0,                         // 0xBC 
+0,                         // 0xBD 
+0,                         // 0xBE 
+0,                         // 0xBF 
+0,                         // 0xC0 
+0,                         // 0xC1 
+0,                         // 0xC2 
+0,                         // 0xC3 
+0,                         // 0xC4 
+0,                         // 0xC5 
+0,                         // 0xC6 
+0,                         // 0xC7 
+0,                         // 0xC8 
+0,                         // 0xC9 
+0,                         // 0xCA 
+0,                         // 0xCB 
+0,                         // 0xCC 
+0,                         // 0xCD 
+0,                         // 0xCE 
+0,                         // 0xCF 
+0,                         // 0xD0 
+0,                         // 0xD1 
+0,                         // 0xD2 
+0,                         // 0xD3 
+0,                         // 0xD4 
+0,                         // 0xD5 
+0,                         // 0xD6 
+0,                         // 0xD7 
+0,                         // 0xD8 
+0,                         // 0xD9 
+0,                         // 0xDA 
+0,                         // 0xDB 
+0,                         // 0xDC 
+0,                         // 0xDD 
+0,                         // 0xDE 
+0,                         // 0xDF 
+0,                         // 0xE0 
+0,                         // 0xE1 
+0,                         // 0xE2 
+0,                         // 0xE3 
+0,                         // 0xE4 
+
+0,                         // 0xE5 
+
+0,                         // 0xE6 
+0,                         // 0xE7 
+0,                         // 0xE8 
+0,                         // 0xE9 
+0,                         // 0xEA 
+0,                         // 0xEB 
+0,                         // 0xEC 
+0,                         // 0xED 
+0,                         // 0xEE 
+0,                         // 0xEF 
+   
+0,                         // 0xF0 
+0,                         // 0xF1 
+0,                         // 0xF2 
+0,                         // 0xF3 
+0,                         // 0xF4 
+0,                         // 0xF5 
+   
+0,                         // 0xF6 
+0,                         // 0xF7 
+0,                         // 0xF8 
+0,                         // 0xF9 
+0,                         // 0xFA 
+0,                         // 0xFB 
+0,                         // 0xFC 
+0,                         // 0xFD 
+0,                         // 0xFE 
+0                          // 0xFF 
+};   
+
+
+U8 TranslateOSKeyCode(U8 vcode)
+{
+   return VcodeRemap[vcode];   
+}   
+
+#pragma mark ---- Clipboard functions ----
+//-----------------------------------------------------------------------------
+const char* Platform::getClipboard()
+{
+	return NULL;//no clipboard on iOS
+}
+
+//-----------------------------------------------------------------------------
+bool Platform::setClipboard(const char *text)
+{
+	return NULL;//no clipboard on iOS
+}
+
+#pragma mark ---- Cursor Functions ----
+//------------------------------------------------------------------------------
+void Input::pushCursor(S32 cursorID)
+{
+   CursorManager* cm = getCursorManager();
+   if(cm)
+      cm->pushCursor(cursorID);
+}
+
+//------------------------------------------------------------------------------
+void Input::popCursor()
+{
+   CursorManager* cm = getCursorManager();
+   if(cm)
+      cm->popCursor();
+}
+
+//------------------------------------------------------------------------------
+void Input::refreshCursor()
+{
+   CursorManager* cm = getCursorManager();
+   if(cm)
+      cm->refreshCursor();
+}
+
+#pragma mark ---- DoubleClick Functions ----
+//------------------------------------------------------------------------------
+U32 Input::getDoubleClickTime()
+{
+	return IOS_DOUBLE_CLICK_TIME;
+}
+
+//------------------------------------------------------------------------------
+S32 Input::getDoubleClickWidth()
+{
+   // this is an arbitrary value.
+   return 10;
+}
+
+//------------------------------------------------------------------------------
+S32 Input::getDoubleClickHeight()
+{
+   return getDoubleClickWidth();
+}
+
+#pragma mark -
+
+//------------------------------------------------------------------------------
+bool enableKeyboard()
+{
+   if ( !gInputEnabled )
+      return( false );
+
+   if ( gKBEnabled && gKBActive )
+      return( true );
+
+   gKBEnabled = true;
+   if ( Input::isActive() )
+      gKBEnabled = activateKeyboard();
+
+   if ( gKBEnabled )
+   {
+      Con::printf( "Hardware-direct keyboard enabled." );
+   }
+   else
+   {
+      Con::warnf( "Hardware-direct keyboard failed to enable!" );
+   }
+
+   return( gKBEnabled );
+}
+
+//------------------------------------------------------------------------------
+void disableKeyboard()
+{
+   if ( !gInputEnabled || !gKBEnabled )
+      return;
+
+   deactivateKeyboard();
+   gKBEnabled = false;
+
+   Con::printf( "Hardware-direct keyboard disabled." );
+}
+
+//------------------------------------------------------------------------------
+bool activateKeyboard()
+{
+   if ( !gInputEnabled || !Input::isActive() || !gKBEnabled )
+      return( false );
+
+   OSStatus status = noErr;
+   if (status==noErr)
+      gKBActive = true;
+
+   return( gKBActive );
+}
+
+//------------------------------------------------------------------------------
+void deactivateKeyboard()
+{
+   if ( gInputEnabled && gKBActive )
+   {
+      gKBActive = false;
+   }
+}
+
+//------------------------------------------------------------------------------
+bool enableMouse()
+{
+   if ( !gInputEnabled )
+      return( false );
+
+   if ( gMouseEnabled && gMouseActive )
+      return( true );
+
+   gMouseEnabled = activateMouse();
+
+   return( gMouseEnabled );
+}
+
+//------------------------------------------------------------------------------
+void disableMouse()
+{
+   if ( !gInputEnabled || !gMouseEnabled )
+      return;
+
+   deactivateMouse();
+   gMouseEnabled = false;
+
+   bool hwMouse = false;
+   Con::printf( "%s disabled", hwMouse?"Hardware-direct mouse":"Basic mouse capture");
+}
+
+//------------------------------------------------------------------------------
+bool activateMouse()
+{
+   if ( !gInputEnabled || !Input::isActive() || !gMouseEnabled )
+      return( false );
+   
+   if (gMouseActive)
+      return(true);
+
+   gMouseActive = true;
+
+   return( gMouseActive );
+}
+
+//------------------------------------------------------------------------------
+void deactivateMouse()
+{
+   if ( !gInputEnabled || !gMouseActive )
+       return;
+   
+   gMouseActive = false;
+}
+
+
+//------------------------------------------------------------------------------
+ConsoleFunction( enableMouse, bool, 1, 1, "enableMouse()" )
+{
+   return( enableMouse() );
+}
+
+//------------------------------------------------------------------------------
+ConsoleFunction( disableMouse, void, 1, 1, "disableMouse()" )
+{
+   disableMouse();
+}
+
+//------------------------------------------------------------------------------
+void printInputState(void)
+{
+   if ( gInputEnabled )
+   {
+         Con::printf( "Low-level input system is enabled." );
+      
+      Con::printf( "- Keyboard is %sabled and %sactive.", 
+            gKBEnabled ? "en" : "dis",
+            gKBActive ? "" : "in" );
+      Con::printf( "- Mouse is %sabled and %sactive.", 
+            gMouseEnabled ? "en" : "dis",
+            gMouseActive ? "" : "in" );
+/*
+      Con::printf( "- Joystick is %sabled and %sactive.", 
+            gJoystickEnabled() ? "en" : "dis",
+            gJoystickActive() ? "" : "in" );
+*/
+   }
+   else
+   {
+      Con::printf( "Low-level input system is disabled." );
+   }
+}
+
+//------------------------------------------------------------------------------
+ConsoleFunction( echoInputState, void, 1, 1, "echoInputState()" )
+{
+   printInputState();
+}
+
+//------------------------------------------------------------------------------
+ConsoleFunction( toggleInputState, void, 1, 1, "toggleInputState()" )
+{
+   if (gInputEnabled)
+      Input::disable();
+   else
+      Input::enable();
+
+   printInputState();
+}
+
+//------------------------------------------------------------------------------
+ConsoleFunction( deactivateKeyboard, void, 1, 1, "deactivateKeyboard();")
+{
+   // these are only useful on the windows side. They deal with some vagaries of win32 DirectInput.
+}
+
+ConsoleFunction( activateKeyboard, void, 1, 1, "activateKeyboard();")
+{
+   // these are only useful on the windows side. They deal with some vagaries of win32 DirectInput.
+}
+
+
+//------------------------------------------------------------------------------
+void Input::setCursorPos(S32 x, S32 y)
+{
+	//this gets called from GuiCanvas to set the game mouse cursor
+}
+
+int processMultipleTouches()
+{	
+	char posX[256], posY[256], temp[10], touchNums[256];
+    
+	dMemset(posX, 0, sizeof(posX));
+    dMemset(posY, 0, sizeof(posY));
+    dMemset(touchNums, 0, sizeof(touchNums));
+
+	touchEvent *currentEvent;
+	
+	//Down Events
+	int numTouchDownEvents = TouchDownEvents.size();
+	while( TouchDownEvents.size() > 0 )
+    {
+		currentEvent = &TouchDownEvents.last();
+		dItoa( currentEvent->x, temp );
+		dStrcat( posX, temp );
+		dStrcat( posX, " " );
+		
+		dItoa( currentEvent->y, temp );
+		dStrcat( posY, temp );
+		dStrcat( posY, " " );
+		
+		dItoa( currentEvent->number, temp );
+		dStrcat( touchNums, temp );
+		dStrcat( touchNums, " " );
+		
+		TouchDownEvents.pop_back();
+	}
+	dItoa( numTouchDownEvents, temp );
+    
+    if( numTouchDownEvents > 0 )
+    {
+        InputEvent touchEvent;
+        
+        touchEvent.deviceInst = 0;
+        touchEvent.objInst = SI_TOUCHDOWN;
+        
+        touchEvent.deviceType = ScreenTouchDeviceType;
+        touchEvent.action = SI_TOUCH;
+        touchEvent.objType = SI_TOUCHDOWN;
+        
+        dStrcpy(touchEvent.fingersX, posX);
+        dStrcpy(touchEvent.fingersY, posY);
+        dStrcpy(touchEvent.fingerIDs, touchNums);
+        
+        touchEvent.modifier = 0;
+        
+        Game->postEvent(touchEvent);        
+    }
+    
+    // Deprecated in 1.5
+	//if( numTouchDownEvents > 0 )
+    //    Con::executef( 4, "oniOSTouchDown", touchNums , posX, posY );
+
+	//Move events
+	int numTouchMoveEvents = TouchMoveEvents.size();
+	while( TouchMoveEvents.size() > 0 ) 
+    {
+		currentEvent = &TouchMoveEvents.last();
+		dItoa( currentEvent->x, temp );
+		dStrcat( posX, temp );
+		dStrcat( posX, " " );
+		
+		dItoa( currentEvent->y, temp );
+		dStrcat( posY, temp );
+		dStrcat( posY, " " );
+		
+		dItoa( currentEvent->number, temp );
+		dStrcat( touchNums, temp );
+		dStrcat( touchNums, " " );		
+		
+		TouchMoveEvents.pop_back();
+	}
+	dItoa( numTouchMoveEvents, temp );
+    
+    if( numTouchMoveEvents > 0 )
+    {
+        InputEvent touchEvent;
+        
+        touchEvent.deviceInst = 0;
+        touchEvent.objInst = SI_TOUCHMOVE;
+        
+        touchEvent.deviceType = ScreenTouchDeviceType;
+        touchEvent.action = SI_TOUCH;
+        touchEvent.objType = SI_TOUCHMOVE;
+        
+        dStrcpy(touchEvent.fingersX, posX);
+        dStrcpy(touchEvent.fingersY, posY);
+        dStrcpy(touchEvent.fingerIDs, touchNums);
+        
+        touchEvent.modifier = 0;
+        
+        Game->postEvent(touchEvent);        
+    }
+    
+    // Deprecated in 1.5 -MP
+	//if( numTouchMoveEvents > 0 )
+    //    Con::executef( 4, "oniOSTouchMove", touchNums , posX, posY );
+	
+	//Up events
+	int numTouchUpEvents = TouchUpEvents.size();
+    
+    dMemset(posX, 0, sizeof(posX));
+    dMemset(posY, 0, sizeof(posY));
+    dMemset(touchNums, 0, sizeof(touchNums));
+    
+	while( TouchUpEvents.size() > 0 ) 
+    {
+		currentEvent = &TouchUpEvents.last();
+		dItoa( currentEvent->x, temp );
+		dStrcat( posX, temp );
+		dStrcat( posX, " " );
+		
+		dItoa( currentEvent->y, temp );
+		dStrcat( posY, temp );
+		dStrcat( posY, " " );
+		
+		dItoa( currentEvent->number, temp );
+		dStrcat( touchNums, temp );
+		dStrcat( touchNums, " " );		
+		
+		lastTouches[currentEvent->number].lastX = -1;
+		lastTouches[currentEvent->number].lastY	 = -1;
+		
+        int x;
+        x = -1;
+        
+        lastTouches[currentEvent->number].lastX = -1;
+		lastTouches[currentEvent->number].lastY	 = -1;
+        
+		TouchUpEvents.pop_back();
+	}
+    
+	dItoa( numTouchUpEvents, temp );
+	
+    if( numTouchUpEvents > 0 )
+    {
+        InputEvent touchEvent;
+        
+        touchEvent.deviceInst = 0;
+        touchEvent.objInst = SI_TOUCHUP;
+        
+        touchEvent.deviceType = ScreenTouchDeviceType;
+        touchEvent.action = SI_TOUCH;
+        touchEvent.objType = SI_TOUCHUP;
+        
+        dStrcpy(touchEvent.fingersX, posX);
+        dStrcpy(touchEvent.fingersY, posY);
+        dStrcpy(touchEvent.fingerIDs, touchNums);
+        
+        touchEvent.modifier = 0;
+        
+        Game->postEvent(touchEvent);        
+    }
+    
+    // Deprecated in 1.5 -MP
+    //if( numTouchUpEvents > 0 )
+    //    Con::executef( 4, "oniOSTouchUp", touchNums , posX, posY );
+	
+	//Luma: Tap support
+	posX[0] = '\0';
+	posY[0] = '\0';
+    
+	int numTapEvents = TouchTapEvents.size();
+	
+    while( TouchTapEvents.size() > 0 ) 
+    {
+		currentEvent = &TouchTapEvents.last();
+		sprintf( temp, "%d ", currentEvent->x );
+		dStrcat( posX, temp );
+		
+		sprintf( temp, "%d ", currentEvent->y );
+		dStrcat( posY, temp );
+		
+		TouchTapEvents.pop_back();
+	}
+    
+	sprintf( temp, "%d", numTapEvents );
+    
+	//if( numTapEvents > 0 )
+    //    Con::executef( 4, "oniOSTouchTap", temp , posX, posY );
+	
+	return numTouchDownEvents + numTouchMoveEvents + numTouchUpEvents;
+}
+
+
+
+//we want these to only be called once per frame!!
+bool createMouseMoveEvent( S32 touchNumber, S32 x, S32 y, S32 lastX, S32 lastY ) //EFM
+{	
+	S32 currentSlot = -1;
+	
+	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )
+	{
+		if( (lastX == lastTouches[i].lastX ) &&
+		   (lastY == lastTouches[i].lastY ) )
+		{
+			currentSlot = i;
+		}
+	}
+
+	if( currentSlot == -1 ) return false;
+	
+	ScreenTouchEvent event;
+	event.xPos = x;
+	event.yPos = y;
+	event.action = SI_MOVE;
+	event.touchID = currentSlot;
+    event.numTouches = 0;
+    
+	//Luma: Mouse not moving (no hover for mouse fingers!)
+	Canvas->setCursorPos( Point2I( x, y ) );  
+
+	if( currentSlot != -1 )
+	{
+		lastTouches[currentSlot].lastX = x;
+		lastTouches[currentSlot].lastY = y;
+	}		
+	
+	TouchMoveEvents.push_back( touchEvent( currentSlot, x, y ) );	
+	Game->postEvent(event);
+	
+	return true;//return false if we get bad values or something
+}
+
+
+bool createMouseDownEvent( S32 touchNumber, S32 x, S32 y, U32 numTouches ) 
+{
+	S32 vacantSlot = -1;
+	
+	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (vacantSlot == -1) ; i++ )
+	{
+		if( lastTouches[i].lastX == -1 )
+		{
+			vacantSlot = i;
+		}
+	}
+	
+	if( vacantSlot == -1 ) 
+        return false;
+		
+	ScreenTouchEvent event;
+	event.xPos = x;
+	event.yPos = y;
+    event.touchID = vacantSlot;
+	event.action = SI_MAKE;
+	event.numTouches = numTouches;
+    
+	//Luma: Update position
+	Canvas->setCursorPos( Point2I( x, y ) );  		
+	
+	if( vacantSlot != -1 )
+	{
+		lastTouches[vacantSlot].lastX = x;
+		lastTouches[vacantSlot].lastY = y;
+	}	
+
+	TouchDownEvents.push_back( touchEvent( vacantSlot, x, y ) );
+	Game->postEvent(event);
+	
+	return true;//return false if we get bad values or something
+}
+
+bool createMouseUpEvent( S32 touchNumber, S32 x, S32 y, S32 lastX, S32 lastY, U32 numTouches ) //EFM
+{	
+	S32 currentSlot = -1;
+	
+	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )
+	{
+		if(( (x == lastTouches[i].lastX) && (y == lastTouches[i].lastY )) ||
+		   ( (lastX == lastTouches[i].lastX ) && (lastY == lastTouches[i].lastY )))
+		{
+			currentSlot = i;
+		}	
+	}
+	
+	if( currentSlot == -1 ) 
+        return false;
+
+	ScreenTouchEvent event;
+	event.xPos = x;
+	event.yPos = y;
+	event.action = SI_BREAK;
+	event.touchID = currentSlot;
+	event.numTouches = numTouches;
+    
+	TouchUpEvents.push_back( touchEvent( currentSlot, x, y ) );	
+	
+	Game->postEvent(event);
+	
+	return true;//return false if we get bad values or something
+}
+
+void clearPendingMultitouchEvents( void ) //EFM
+{	
+    for( int i = 0 ; i < MAX_TOUCH_EVENTS ; i++ )
+	{
+		lastTouches[i].lastX = -1;
+		lastTouches[i].lastY = -1;
+	}
+
+	TouchMoveEvents.clear();
+	TouchDownEvents.clear();
+	TouchUpEvents.clear();
+}
+
+
+//Luma: Tap support
+void createMouseTapEvent( S32 nbrTaps, S32 x, S32 y ) {
+
+	TouchTapEvents.push_back( touchEvent( nbrTaps, x, y ) );
+}
+
+
+// 0 = x, 1 = y, 2 = z
+UIAccelerationValue g_lastAccel[3];
+
+// PUAP -Mat this is polled at AccelerometerUpdateMS, which should be set at around 33 
+/*
+bool createAccelMoveEvent( UIAccelerationValue *accel ) {
+	bool returnVal = false;
+	
+	U32 axis[3] = { SI_XAXIS, SI_YAXIS, SI_ZAXIS }; 
+	
+	for( int i = 0; i < 3; i++ ) {
+		if(accel[i]  != g_lastAccel[i] ) {
+			InputEvent event;
+			event.deviceInst = 0;//joystick number
+			event.fValue = accel[i];
+			event.deviceType = JoystickDeviceType;
+			event.objType = axis[i];
+			event.objInst = i;//axis number
+			event.action = SI_MOVE;
+			event.modifier = 0;
+			Game->postEvent(event);
+			g_lastAccel[i]  = accel[i];
+			returnVal = true;
+		}
+	}
+	return false;
+}
+*/

+ 460 - 460
engine/source/platformiOS/iOSMotionManager.mm

@@ -1,460 +1,460 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#import "iOSMotionManager.h"
-
-#include "platformiOS.h"
-#include "string/stringBuffer.h"
-#include "sim/simBase.h"
-#include "game/gameInterface.h"
-
-extern iOSPlatState platState;
-
-static const double kFilterConst = 0.1;
-
-static const double kUpdateInterval = 0.2;
-
-@implementation iOSMotionManager
-
-
-@synthesize referenceAttitude;
-@synthesize accelerometerEnabled;
-@synthesize gyroscopeEnabled;
-
-- (id)init
-{
-    if (!(self = [super init])) return nil;
-    
-    if(self != NULL)
-    {
-        accelerometerEnabled = NO;
-        gyroscopeEnabled = NO;
-        
-        motionManager = [[CMMotionManager alloc] init];
-        
-        if(motionManager.deviceMotionAvailable)
-        {
-            [motionManager setDeviceMotionUpdateInterval:kUpdateInterval];
-        }
-        else
-        {
-            [motionManager setAccelerometerUpdateInterval:kUpdateInterval];
-        }
-    }
-    else
-    {
-        Con::printf("Could not initialized iOSMotionManager!");
-        return 0;
-    }
-        
-    return self;
-}
-
-
-
-double accelAxes[6];
-
-
-- (void)enableAccelerometer
-{
-    accelerometerEnabled = YES;
-}
-
-- (void)disableAccelerometer
-{
-    accelerometerEnabled = NO;
-}
-
-- (bool)isAccelerometerActive
-{
-    return motionManager.accelerometerActive;
-}
-
-- (bool)enableGyroscope
-{
-    if(motionManager.gyroAvailable)
-        gyroscopeEnabled = YES;
-    else
-    {
-        Con::errorf("Gyroscope not supported on this device");
-        return false;
-    }
-    
-    return true;    
-}
-
-- (bool)disableGyroscope
-{
-    if(motionManager.gyroAvailable)
-        gyroscopeEnabled = NO;
-    else
-    {
-        Con::errorf("Gyroscope not supported on this device");
-        return false;
-    }
-    
-    return true;
-}
-
-- (bool)isGyroAvailable
-{
-    return motionManager.gyroAvailable;
-}
-
-- (bool)isGyroActive
-{
-    return motionManager.gyroActive;
-}
-
-static double filteredAccel[3] = {0, 0, 0};
-
-void (^accelerometerHandler)(CMAccelerometerData*, NSError*) = ^(CMAccelerometerData *accelData, NSError *)
-{
-    if(gMotionManager.accelerometerEnabled)
-    {
-        U32 accelAxes[6] = { SI_ACCELX, SI_ACCELY, SI_ACCELZ, SI_GRAVX, SI_GRAVY, SI_GRAVZ };
-        
-        double userAcc[6];
-        
-        if(platState.portrait)
-        {
-        
-            filteredAccel[0] = (accelData.acceleration.x * kFilterConst) + (filteredAccel[0] * (1.0 - kFilterConst));
-            filteredAccel[1] = (accelData.acceleration.y * kFilterConst) + (filteredAccel[1] * (1.0 - kFilterConst));
-            filteredAccel[2] = (accelData.acceleration.z * kFilterConst) + (filteredAccel[2] * (1.0 - kFilterConst));
-            
-            userAcc[0] = accelData.acceleration.x - filteredAccel[0];
-            userAcc[1] = accelData.acceleration.y - filteredAccel[1];
-            userAcc[2] = accelData.acceleration.z - filteredAccel[2];
-            
-            // Assign the non-filtered data to gravity
-            userAcc[3] = accelData.acceleration.x;
-            userAcc[4] = accelData.acceleration.y;
-            userAcc[5] = accelData.acceleration.z;
-        }
-        else 
-        {
-            filteredAccel[0] = (accelData.acceleration.y * kFilterConst) + (filteredAccel[0] * (1.0 - kFilterConst));
-            filteredAccel[1] = (accelData.acceleration.x * kFilterConst) + (filteredAccel[1] * (1.0 - kFilterConst));
-            filteredAccel[2] = (accelData.acceleration.z * kFilterConst) + (filteredAccel[2] * (1.0 - kFilterConst));
-
-            userAcc[0] = accelData.acceleration.y - filteredAccel[0];
-            userAcc[1] = accelData.acceleration.x - filteredAccel[1];
-            userAcc[2] = accelData.acceleration.z - filteredAccel[2];
-            
-            // Assign the non-filtered data to gravity
-            userAcc[3] = accelData.acceleration.y;
-            userAcc[4] = accelData.acceleration.x;
-            userAcc[5] = accelData.acceleration.z;
-        }
-        
-        for( int i = 0; i < 6; i++)
-        {
-            InputEvent event;
-            
-            event.deviceInst = 0;
-            event.fValue = userAcc[i];
-            event.deviceType = AccelerometerDeviceType;
-            event.objType = accelAxes[i];
-            event.objInst = i;
-            event.action = SI_MOTION;
-            event.modifier = 0;
-            
-            Game->postEvent(event);
-        }
-    }
-};
-
-void (^motionHandler)(CMDeviceMotion*, NSError*) = ^(CMDeviceMotion *motionData, NSError *error)
-{
-    if(gMotionManager.referenceAttitude == NULL)
-        [gMotionManager resetDeviceMotionReference];
-    
-    CMAttitude* currentAttitude = motionData.attitude;
-  
-    [currentAttitude multiplyByInverseOfAttitude:gMotionManager.referenceAttitude];
-  
-    if(gMotionManager.accelerometerEnabled)
-    {
-        U32 accelAxes[6] = { SI_ACCELX, SI_ACCELY, SI_ACCELZ, SI_GRAVX, SI_GRAVY, SI_GRAVZ };
-        
-        double userAcc[6];
-        if(platState.portrait)
-        {
-            userAcc[0] = motionData.userAcceleration.x; 
-            userAcc[1] = motionData.userAcceleration.y;
-            userAcc[2] = motionData.userAcceleration.z;
-            userAcc[3] = motionData.gravity.x; 
-            userAcc[4] = motionData.gravity.y;
-            userAcc[5] = motionData.gravity.z;
-        }
-        else 
-        {
-            userAcc[0] = motionData.userAcceleration.y; 
-            userAcc[1] = motionData.userAcceleration.x;
-            userAcc[2] = motionData.userAcceleration.z;
-            userAcc[3] = motionData.gravity.y; 
-            userAcc[4] = motionData.gravity.x;
-            userAcc[5] = motionData.gravity.z;            
-        }
-
-        for( int i = 0; i < 6; i++)
-        {
-            InputEvent event;
-        
-            event.deviceInst = 0;
-            event.fValue = userAcc[i];
-            event.deviceType = AccelerometerDeviceType;
-            event.objType = accelAxes[i];
-            event.objInst = i;
-            event.action = SI_MOTION;
-            event.modifier = 0;
-        
-            Game->postEvent(event);
-        }
-    }
-    
-    if(gMotionManager.gyroscopeEnabled)
-    {
-        double gyroData[6] = { currentAttitude.pitch, 
-                               currentAttitude.yaw, 
-                               currentAttitude.roll, 
-                               motionData.rotationRate.x, 
-                               motionData.rotationRate.y, 
-                               motionData.rotationRate.z };
-        
-        U32 gyroAxes[6] = { SI_PITCH, SI_YAW, SI_ROLL, SI_GYROX, SI_GYROY, SI_GYROZ };
-        
-        for( int i = 0; i < 6; i++)
-        {
-            InputEvent event;
-            
-            event.deviceInst = 0;
-            event.fValue = gyroData[i];
-            event.deviceType = GyroscopeDeviceType;
-            event.objType = gyroAxes[i];
-            event.objInst = i;
-            event.action = SI_MOTION;
-            event.modifier = 0;
-            
-            Game->postEvent(event);
-        }
-    }
-    
-};
-
-- (bool)startDeviceMotion
-{
-    if(motionManager.deviceMotionAvailable)
-    {
-        if(referenceAttitude == NULL)
-            referenceAttitude = motionManager.deviceMotion.attitude;
-        
-        [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:motionHandler];
-    }
-    else
-    {
-        [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:accelerometerHandler];
-    }
-    
-    return true;
-}
-
-- (bool)stopDeviceMotion
-{
-    if(motionManager.deviceMotionAvailable)
-        [motionManager stopDeviceMotionUpdates];
-    else
-    {
-        [motionManager stopAccelerometerUpdates];
-    }
-    return true;
-}
-
-- (bool)resetDeviceMotionReference
-{
-    if(motionManager.deviceMotionAvailable)
-    {
-        referenceAttitude = motionManager.deviceMotion.attitude;
-        return true;
-    }
-    
-    Con::errorf("Device Motion not supported on this device (check OS)");
-    return false;
-}
-
-- (bool)isDeviceMotionAvailable
-{
-    return motionManager.deviceMotionAvailable;
-}
-
-- (bool)isDeviceMotionActive
-{
-    return motionManager.deviceMotionActive;
-}
-
-@end
-
-ConsoleFunction(initMotionManager, void, 1, 1, "() Initialize the iOSMotionManager")
-{
-    if(gMotionManager != NULL)
-    {
-        Con::printf("Motion Manager already initialized");
-    }
-    else
-        gMotionManager = [[iOSMotionManager alloc] init];
-}
-
-ConsoleFunction(enableAccelerometer, void, 1, 1, "() Allow accelerometer tracking during device motion updates")
-{
-    if(gMotionManager == NULL)
-        gMotionManager = [[iOSMotionManager alloc] init];
-    
-    gMotionManager.accelerometerEnabled = YES;
-    [gMotionManager startDeviceMotion];
-}
-
-ConsoleFunction(disableAccelerometer, void, 1, 1, "() Stop accelerometer tracking")
-{
-    if(gMotionManager != NULL)
-        gMotionManager.accelerometerEnabled = NO;
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        gMotionManager = [[iOSMotionManager alloc] init];
-    }
-}
-
-ConsoleFunction(isAccelerometerActive, bool, 1, 1, "() Check to see if Accelerometer is being polled\n"
-                "@return True if accelerometer is on, false otherwise")
-{
-    if(gMotionManager != NULL)
-        return [gMotionManager isAccelerometerActive];
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        gMotionManager = [[iOSMotionManager alloc] init];
-        return [gMotionManager isAccelerometerActive];
-    }
-}
-
-ConsoleFunction(isGyroAvailable, bool, 1, 1, "() Check to see if this iOS device has a gyroscope\n"
-                                             "@return True if gyro is on the device, false otherwise")
-{
-    if(gMotionManager != NULL)
-        return [gMotionManager isGyroAvailable];
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        gMotionManager = [[iOSMotionManager alloc] init];
-        return [gMotionManager isGyroAvailable];
-    }
-}
-
-ConsoleFunction(isGyroActive, bool, 1, 1, "() Check to see if this iOS device has a gyroscope\n"
-                "@return True if gyro is on the device, false otherwise")
-{
-    if(gMotionManager != NULL)
-        return [gMotionManager isGyroActive];
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        gMotionManager = [[iOSMotionManager alloc] init];
-        return [gMotionManager isGyroActive];
-    }
-}
-ConsoleFunction(enableGyroscope, void, 1, 1, "() Start the gyroscope tracking\n"
-                "@return True if gyroscope is supported, false otherwise")
-{
-    if(gMotionManager != NULL)
-        gMotionManager.gyroscopeEnabled = YES;
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        
-        gMotionManager = [[iOSMotionManager alloc] init];
-        gMotionManager.gyroscopeEnabled = YES;
-        [gMotionManager startDeviceMotion];
-    }
-}
-
-ConsoleFunction(stopGyroscope, void, 1, 1, "() Stop gyroscope tracking\n"
-                "@return True if gyroscope is supported, false otherwise")
-{
-    if(gMotionManager != NULL)
-        gMotionManager.gyroscopeEnabled = NO;
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        
-        gMotionManager = [[iOSMotionManager alloc] init];
-    }
-}
-
-ConsoleFunction(isDeviceMotionAvailable, bool, 1, 1, "() Check to see if this iOS device supports advanced device motion (requires gyroscope\n"
-                "@return True if Device Motion is supported, false otherwise")
-{
-    if(gMotionManager != NULL)
-        return [gMotionManager isDeviceMotionAvailable];
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        gMotionManager = [[iOSMotionManager alloc] init];
-        return [gMotionManager isDeviceMotionAvailable];
-    }
-}
-
-ConsoleFunction(isDeviceMotionActive, bool, 1, 1, "() Check to see if the device motion is running\n"
-                                                  "@return True if device motion is being tracked, false otherwise")
-{
-    if(gMotionManager != NULL)
-        return [gMotionManager isDeviceMotionActive];
-    
-    Con::warnf("Motion Manager was not initialized. Initializing now");
-    gMotionManager = [[iOSMotionManager alloc] init];
-    return [gMotionManager isDeviceMotionActive];
-}
-ConsoleFunction(startDeviceMotion, bool, 1, 1, "() Start Device motion tracking\n"
-                                               "@return True if device motion is supported, false otherwise")
-{
-    if(gMotionManager != NULL)
-        return [gMotionManager startDeviceMotion];
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        gMotionManager = [[iOSMotionManager alloc] init];
-        return [gMotionManager startDeviceMotion];
-    }
-}
-
-ConsoleFunction(stopDeviceMotion, bool, 1, 1, "() Stop Device Motion tracking\n"
-                                              "@return True if device motion is supported, false otherwise")
-{
-    if(gMotionManager != NULL)
-        return [gMotionManager stopDeviceMotion];
-    else
-    {
-        Con::warnf("Motion Manager was not initialized. Initializing now");
-        gMotionManager = [[iOSMotionManager alloc] init];
-        return [gMotionManager stopDeviceMotion];
-    }
-}
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#import "iOSMotionManager.h"
+
+#include "platformiOS.h"
+#include "string/stringBuffer.h"
+#include "sim/simBase.h"
+#include "game/gameInterface.h"
+
+extern iOSPlatState platState;
+
+static const double kFilterConst = 0.1;
+
+static const double kUpdateInterval = 0.2;
+
+@implementation iOSMotionManager
+
+
+@synthesize referenceAttitude;
+@synthesize accelerometerEnabled;
+@synthesize gyroscopeEnabled;
+
+- (id)init
+{
+    if (!(self = [super init])) return nil;
+    
+    if(self != NULL)
+    {
+        accelerometerEnabled = NO;
+        gyroscopeEnabled = NO;
+        
+        motionManager = [[CMMotionManager alloc] init];
+        
+        if(motionManager.deviceMotionAvailable)
+        {
+            [motionManager setDeviceMotionUpdateInterval:kUpdateInterval];
+        }
+        else
+        {
+            [motionManager setAccelerometerUpdateInterval:kUpdateInterval];
+        }
+    }
+    else
+    {
+        Con::printf("Could not initialized iOSMotionManager!");
+        return 0;
+    }
+        
+    return self;
+}
+
+
+
+double accelAxes[6];
+
+
+- (void)enableAccelerometer
+{
+    accelerometerEnabled = YES;
+}
+
+- (void)disableAccelerometer
+{
+    accelerometerEnabled = NO;
+}
+
+- (bool)isAccelerometerActive
+{
+    return motionManager.accelerometerActive;
+}
+
+- (bool)enableGyroscope
+{
+    if(motionManager.gyroAvailable)
+        gyroscopeEnabled = YES;
+    else
+    {
+        Con::errorf("Gyroscope not supported on this device");
+        return false;
+    }
+    
+    return true;    
+}
+
+- (bool)disableGyroscope
+{
+    if(motionManager.gyroAvailable)
+        gyroscopeEnabled = NO;
+    else
+    {
+        Con::errorf("Gyroscope not supported on this device");
+        return false;
+    }
+    
+    return true;
+}
+
+- (bool)isGyroAvailable
+{
+    return motionManager.gyroAvailable;
+}
+
+- (bool)isGyroActive
+{
+    return motionManager.gyroActive;
+}
+
+static double filteredAccel[3] = {0, 0, 0};
+
+void (^accelerometerHandler)(CMAccelerometerData*, NSError*) = ^(CMAccelerometerData *accelData, NSError *)
+{
+    if(gMotionManager.accelerometerEnabled)
+    {
+        U32 accelAxes[6] = { SI_ACCELX, SI_ACCELY, SI_ACCELZ, SI_GRAVX, SI_GRAVY, SI_GRAVZ };
+        
+        double userAcc[6];
+        
+        if(platState.portrait)
+        {
+        
+            filteredAccel[0] = (accelData.acceleration.x * kFilterConst) + (filteredAccel[0] * (1.0 - kFilterConst));
+            filteredAccel[1] = (accelData.acceleration.y * kFilterConst) + (filteredAccel[1] * (1.0 - kFilterConst));
+            filteredAccel[2] = (accelData.acceleration.z * kFilterConst) + (filteredAccel[2] * (1.0 - kFilterConst));
+            
+            userAcc[0] = accelData.acceleration.x - filteredAccel[0];
+            userAcc[1] = accelData.acceleration.y - filteredAccel[1];
+            userAcc[2] = accelData.acceleration.z - filteredAccel[2];
+            
+            // Assign the non-filtered data to gravity
+            userAcc[3] = accelData.acceleration.x;
+            userAcc[4] = accelData.acceleration.y;
+            userAcc[5] = accelData.acceleration.z;
+        }
+        else 
+        {
+            filteredAccel[0] = (accelData.acceleration.y * kFilterConst) + (filteredAccel[0] * (1.0 - kFilterConst));
+            filteredAccel[1] = (accelData.acceleration.x * kFilterConst) + (filteredAccel[1] * (1.0 - kFilterConst));
+            filteredAccel[2] = (accelData.acceleration.z * kFilterConst) + (filteredAccel[2] * (1.0 - kFilterConst));
+
+            userAcc[0] = accelData.acceleration.y - filteredAccel[0];
+            userAcc[1] = accelData.acceleration.x - filteredAccel[1];
+            userAcc[2] = accelData.acceleration.z - filteredAccel[2];
+            
+            // Assign the non-filtered data to gravity
+            userAcc[3] = accelData.acceleration.y;
+            userAcc[4] = accelData.acceleration.x;
+            userAcc[5] = accelData.acceleration.z;
+        }
+        
+        for( int i = 0; i < 6; i++)
+        {
+            InputEvent event;
+            
+            event.deviceInst = 0;
+            event.fValues[0] = userAcc[i];
+            event.deviceType = AccelerometerDeviceType;
+            event.objType = accelAxes[i];
+            event.objInst = i;
+            event.action = SI_MOTION;
+            event.modifier = 0;
+            
+            Game->postEvent(event);
+        }
+    }
+};
+
+void (^motionHandler)(CMDeviceMotion*, NSError*) = ^(CMDeviceMotion *motionData, NSError *error)
+{
+    if(gMotionManager.referenceAttitude == NULL)
+        [gMotionManager resetDeviceMotionReference];
+    
+    CMAttitude* currentAttitude = motionData.attitude;
+  
+    [currentAttitude multiplyByInverseOfAttitude:gMotionManager.referenceAttitude];
+  
+    if(gMotionManager.accelerometerEnabled)
+    {
+        U32 accelAxes[6] = { SI_ACCELX, SI_ACCELY, SI_ACCELZ, SI_GRAVX, SI_GRAVY, SI_GRAVZ };
+        
+        double userAcc[6];
+        if(platState.portrait)
+        {
+            userAcc[0] = motionData.userAcceleration.x; 
+            userAcc[1] = motionData.userAcceleration.y;
+            userAcc[2] = motionData.userAcceleration.z;
+            userAcc[3] = motionData.gravity.x; 
+            userAcc[4] = motionData.gravity.y;
+            userAcc[5] = motionData.gravity.z;
+        }
+        else 
+        {
+            userAcc[0] = motionData.userAcceleration.y; 
+            userAcc[1] = motionData.userAcceleration.x;
+            userAcc[2] = motionData.userAcceleration.z;
+            userAcc[3] = motionData.gravity.y; 
+            userAcc[4] = motionData.gravity.x;
+            userAcc[5] = motionData.gravity.z;            
+        }
+
+        for( int i = 0; i < 6; i++)
+        {
+            InputEvent event;
+        
+            event.deviceInst = 0;
+            event.fValues[0] = userAcc[i];
+            event.deviceType = AccelerometerDeviceType;
+            event.objType = accelAxes[i];
+            event.objInst = i;
+            event.action = SI_MOTION;
+            event.modifier = 0;
+        
+            Game->postEvent(event);
+        }
+    }
+    
+    if(gMotionManager.gyroscopeEnabled)
+    {
+        double gyroData[6] = { currentAttitude.pitch, 
+                               currentAttitude.yaw, 
+                               currentAttitude.roll, 
+                               motionData.rotationRate.x, 
+                               motionData.rotationRate.y, 
+                               motionData.rotationRate.z };
+        
+        U32 gyroAxes[6] = { SI_PITCH, SI_YAW, SI_ROLL, SI_GYROX, SI_GYROY, SI_GYROZ };
+        
+        for( int i = 0; i < 6; i++)
+        {
+            InputEvent event;
+            
+            event.deviceInst = 0;
+            event.fValues[0] = gyroData[i];
+            event.deviceType = GyroscopeDeviceType;
+            event.objType = gyroAxes[i];
+            event.objInst = i;
+            event.action = SI_MOTION;
+            event.modifier = 0;
+            
+            Game->postEvent(event);
+        }
+    }
+    
+};
+
+- (bool)startDeviceMotion
+{
+    if(motionManager.deviceMotionAvailable)
+    {
+        if(referenceAttitude == NULL)
+            referenceAttitude = motionManager.deviceMotion.attitude;
+        
+        [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:motionHandler];
+    }
+    else
+    {
+        [motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:accelerometerHandler];
+    }
+    
+    return true;
+}
+
+- (bool)stopDeviceMotion
+{
+    if(motionManager.deviceMotionAvailable)
+        [motionManager stopDeviceMotionUpdates];
+    else
+    {
+        [motionManager stopAccelerometerUpdates];
+    }
+    return true;
+}
+
+- (bool)resetDeviceMotionReference
+{
+    if(motionManager.deviceMotionAvailable)
+    {
+        referenceAttitude = motionManager.deviceMotion.attitude;
+        return true;
+    }
+    
+    Con::errorf("Device Motion not supported on this device (check OS)");
+    return false;
+}
+
+- (bool)isDeviceMotionAvailable
+{
+    return motionManager.deviceMotionAvailable;
+}
+
+- (bool)isDeviceMotionActive
+{
+    return motionManager.deviceMotionActive;
+}
+
+@end
+
+ConsoleFunction(initMotionManager, void, 1, 1, "() Initialize the iOSMotionManager")
+{
+    if(gMotionManager != NULL)
+    {
+        Con::printf("Motion Manager already initialized");
+    }
+    else
+        gMotionManager = [[iOSMotionManager alloc] init];
+}
+
+ConsoleFunction(enableAccelerometer, void, 1, 1, "() Allow accelerometer tracking during device motion updates")
+{
+    if(gMotionManager == NULL)
+        gMotionManager = [[iOSMotionManager alloc] init];
+    
+    gMotionManager.accelerometerEnabled = YES;
+    [gMotionManager startDeviceMotion];
+}
+
+ConsoleFunction(disableAccelerometer, void, 1, 1, "() Stop accelerometer tracking")
+{
+    if(gMotionManager != NULL)
+        gMotionManager.accelerometerEnabled = NO;
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        gMotionManager = [[iOSMotionManager alloc] init];
+    }
+}
+
+ConsoleFunction(isAccelerometerActive, bool, 1, 1, "() Check to see if Accelerometer is being polled\n"
+                "@return True if accelerometer is on, false otherwise")
+{
+    if(gMotionManager != NULL)
+        return [gMotionManager isAccelerometerActive];
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        gMotionManager = [[iOSMotionManager alloc] init];
+        return [gMotionManager isAccelerometerActive];
+    }
+}
+
+ConsoleFunction(isGyroAvailable, bool, 1, 1, "() Check to see if this iOS device has a gyroscope\n"
+                                             "@return True if gyro is on the device, false otherwise")
+{
+    if(gMotionManager != NULL)
+        return [gMotionManager isGyroAvailable];
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        gMotionManager = [[iOSMotionManager alloc] init];
+        return [gMotionManager isGyroAvailable];
+    }
+}
+
+ConsoleFunction(isGyroActive, bool, 1, 1, "() Check to see if this iOS device has a gyroscope\n"
+                "@return True if gyro is on the device, false otherwise")
+{
+    if(gMotionManager != NULL)
+        return [gMotionManager isGyroActive];
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        gMotionManager = [[iOSMotionManager alloc] init];
+        return [gMotionManager isGyroActive];
+    }
+}
+ConsoleFunction(enableGyroscope, void, 1, 1, "() Start the gyroscope tracking\n"
+                "@return True if gyroscope is supported, false otherwise")
+{
+    if(gMotionManager != NULL)
+        gMotionManager.gyroscopeEnabled = YES;
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        
+        gMotionManager = [[iOSMotionManager alloc] init];
+        gMotionManager.gyroscopeEnabled = YES;
+        [gMotionManager startDeviceMotion];
+    }
+}
+
+ConsoleFunction(stopGyroscope, void, 1, 1, "() Stop gyroscope tracking\n"
+                "@return True if gyroscope is supported, false otherwise")
+{
+    if(gMotionManager != NULL)
+        gMotionManager.gyroscopeEnabled = NO;
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        
+        gMotionManager = [[iOSMotionManager alloc] init];
+    }
+}
+
+ConsoleFunction(isDeviceMotionAvailable, bool, 1, 1, "() Check to see if this iOS device supports advanced device motion (requires gyroscope\n"
+                "@return True if Device Motion is supported, false otherwise")
+{
+    if(gMotionManager != NULL)
+        return [gMotionManager isDeviceMotionAvailable];
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        gMotionManager = [[iOSMotionManager alloc] init];
+        return [gMotionManager isDeviceMotionAvailable];
+    }
+}
+
+ConsoleFunction(isDeviceMotionActive, bool, 1, 1, "() Check to see if the device motion is running\n"
+                                                  "@return True if device motion is being tracked, false otherwise")
+{
+    if(gMotionManager != NULL)
+        return [gMotionManager isDeviceMotionActive];
+    
+    Con::warnf("Motion Manager was not initialized. Initializing now");
+    gMotionManager = [[iOSMotionManager alloc] init];
+    return [gMotionManager isDeviceMotionActive];
+}
+ConsoleFunction(startDeviceMotion, bool, 1, 1, "() Start Device motion tracking\n"
+                                               "@return True if device motion is supported, false otherwise")
+{
+    if(gMotionManager != NULL)
+        return [gMotionManager startDeviceMotion];
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        gMotionManager = [[iOSMotionManager alloc] init];
+        return [gMotionManager startDeviceMotion];
+    }
+}
+
+ConsoleFunction(stopDeviceMotion, bool, 1, 1, "() Stop Device Motion tracking\n"
+                                              "@return True if device motion is supported, false otherwise")
+{
+    if(gMotionManager != NULL)
+        return [gMotionManager stopDeviceMotion];
+    else
+    {
+        Con::warnf("Motion Manager was not initialized. Initializing now");
+        gMotionManager = [[iOSMotionManager alloc] init];
+        return [gMotionManager stopDeviceMotion];
+    }
+}